跳到正文

31-环境重建与自动化部署手册 ​

一句话:手册的判据只有一条——任何工程师在干净环境从零把链路重建到跑通:命令可贴、坑已标注、验收可逐条勾;它只写“怎么重建”不复述“为什么”,正因如此,环境版本、镜像源、网关协议这些约束必须钉死成口径,否则复跑结果靠的是运气而不是交接。

定位:本平台(基于开源 agentscope-service 官方 main 构建的企业智能体平台)的可执行交接文档——任何工程师在干净环境上,从零重建到 M4 链路跑通。 口径:命令基于 Windows + pwsh 7(本环境);Linux 仅路径/镜像名差异,命令主体相同。结论可复核、命令可复跑、坑已标注。 配套:《30-搭建过程与问题解决台账》记录"为什么"(根因/选型),本文记录"怎么重建"(步骤/命令/验收)。


1. 环境要求(M1 基线) ​

项要求本环境参考
OSWindows 10/11(Linux 亦可,路径改 /)Windows
容器Docker Desktop(引擎必须运行)安装路径 C:\Users\Administrator\AppData\Local\Programs\DockerDesktop\Docker Desktop.exe(不在 Program Files)
JDK21(官方构建要求)D:\Java\jdk-21.0.8
Maven3.9.xD:\Java\apache-maven-3.9.9
Git任意需能走 SSH 协议 访问 github.com
网络①github.com(SSH 拉源码)②ACR(官方镜像)③qianwen 网关(token-plan compatible-mode)docker.io 直连不可用(IPv6 超时)

先决检查:docker info 成功;ssh -T git@github.com 返回欢迎语;git --version、java -version(21)、mvn -version。


2. 拉取源码(SSH 协议) ​

powershell
# 必须落在纯 ASCII 路径!中文路径会破坏 protoc 原生编译(报 02-???????)
git clone git@github.com:agentscope-ai/agentscope-java.git D:\build\agentscope-java
cd D:\build\agentscope-java
git checkout -b official-main origin/main   # 官方主线,本手册基于 HEAD=d04529e9
  • 官方 ACR 镜像对应 origin/release/2.1.0-BETA1(不可直接用于模型对接,见 §8 坑 5)。
  • 本地仓库(用户工作树)建议再 robocopy D:\build\agentscope-java C:\Users\...\Desktop\02-项目代码\agentscope-java /E /NFL /NDL 做整树副本(保持 ASCII 构建副本 + 中文工作树并存)。

3. 本地构建(唯一代码改动点 = 模型对接) ​

3.1 加 openai 扩展依赖 ​

文件:agentscope-service/service-dataplane/pom.xml,在 dependencies 中加入:

xml
<dependency>
  <groupId>io.agentscope</groupId>
  <artifactId>agentscope-extensions-model-openai</artifactId>
  <version>2.1.0-SNAPSHOT</version>
</dependency>

原因(详见 30-台账 §2.2):官方 release/main 打包 dashscope-only + 原生协议,接不了 OpenAI 兼容网关(token-plan/maas);必须本地加 openai 扩展,agent 配 model: openai:qwen3.8-flash 指向网关。不动任何业务代码。

3.2 构建命令(pwsh 注意) ​

powershell
cd D:\build\agentscope-java
$env:JAVA_HOME = "D:\Java\jdk-21.0.8"
$env:PATH = "D:\Java\apache-maven-3.9.9\bin;$env:PATH"
mvn -pl agentscope-service/service-dataplane -am clean package -DskipTests "-Dmaven.test.skip=true"

坑 4:pwsh 里 -Dxxx=yyy 必须整体加引号("-Dmaven.test.skip=true"),否则报 Unknown lifecycle phase。 坑 1:路径必须 ASCII(protoc)。

3.3 产物验收 ​

powershell
# jar 约 142MB,必须包含 openai 扩展
jar tf agentscope-service/service-dataplane/target/service-dataplane-2.1.0-SNAPSHOT.jar |
  Select-String "agentscope-extensions-model-openai"

4. 镜像构建(本地 dataplane 镜像) ​

dockerfile
# agentscope-service/docker/Dockerfile.local-openai
# FROM 官方 ACR data 镜像(本地已有缓存)+ 覆盖新 jar —— 不能 FROM docker.io(IPv6 超时)
FROM sca-registry.cn-hangzhou.cr.aliyuncs.com/agentscope/as-service-dataplane:2.1.0-BETA1
COPY agentscope-service/service-dataplane/target/service-dataplane-2.1.0-SNAPSHOT.jar /app.jar
powershell
cd D:\build\agentscope-java
docker build -f agentscope-service/docker/Dockerfile.local-openai -t as-dataplane:local-openai .
docker images as-dataplane:local-openai   # ≈1.01GB

坑 6:docker.io 直连 443 超时(IPv6),任何 FROM eclipse-temurin:21-jre 都会失败;用本地已有 ACR 镜像做 base 最稳。


5. compose 部署(M3) ​

5.1 服务拓扑(deploy/compose.yaml) ​

客户端 → gateway(:18080) ─┬─ control(:8080 内部) ─┬─ db(PG17, agentscope, schema dp/rt)
                          │                        ├─ scheduler
                          └─ data(:8082, as-dataplane:local-openai, actuator/health)

5.2 关键配置(deploy/.env 与 compose.yaml) ​

配置位置值说明
登录密码.env → CONTROL_PLANE_BOOTSTRAP_PASSWORDadmin 初始密码(新环境必改)
数据库.env → POSTGRES_PASSWORD / POSTGRES_DB=agentscopePG 凭据
模型 key.env → OPENAI_API_KEYtoken-plan 网关 key(sk-sp-…,在 .env 中维护,勿提交)
模型网关.env → OPENAI_BASE_URLhttps://token-plan.maas.qianwenaiapi.com/compatible-mode/v1
dashscope.env → DASHSCOPE_API_KEY置空(官方默认 bean 不建,避免走原生协议)
data 镜像compose.yaml → data service image: as-dataplane:local-openai本地构建镜像
env 透传compose.yaml → x-runtime-env必须含 OPENAI_API_KEY/OPENAI_BASE_URL(透传给 agent 运行环境)

5.3 启动与健康 ​

powershell
cd agentscope-service/deploy
docker compose up -d
docker compose ps                      # 全部 running
Invoke-RestMethod http://localhost:8082/actuator/health   # data → UP
Invoke-WebRequest http://localhost:18080/healthz -UseBasicParsing   # gateway

若改过 jar/镜像:docker compose up -d --build 或先 docker compose rm -f data 再 up(data 用本地镜像)。


6. 验证脚本(M4 链路复跑,用 D:\build\_*.json 存证) ​

全部走 http://localhost:18080。pwsh 直接 stdout 打印 API 结果会抽风(坑 7)→ 一律 Out-File 后 Read。

6.1 登录 ​

powershell
$login = Invoke-RestMethod -Uri "http://localhost:18080/api/auth/login" -Method Post `
  -ContentType "application/json" -Body '{"username":"admin","password":"<CONTROL_PLANE_BOOTSTRAP_PASSWORD>"}'
$login | ConvertTo-Json | Out-File D:\build\_login.json -Encoding utf8
# 期望:token + user(roles 含 admin);JWT 过期后需重登

6.2 环境 → Agent(官方格式,坑 7) ​

powershell
$h = @{Authorization="Bearer $jwt"; "X-AgentScope-Tenant"="default"}
# 环境
Invoke-RestMethod -Uri "http://localhost:18080/api/environments" -Method Post -Headers $h `
  -ContentType "application/json" -Body '{"name":"Quickstart local","type":"local","config":{}}'
# Agent:binding 在顶层(managed)+ tenant header + definition 内 defaultEnvironmentId/model
$agentBody = '{"binding":{"kind":"managed"},"definition":{"name":"notes-assistant-openai","system":"你是编码助手","model":"openai:qwen3.8-flash","defaultEnvironmentId":"env_<新ID>"}}'
Invoke-RestMethod -Uri "http://localhost:18080/api/v1/agents" -Method Post -Headers $h `
  -ContentType "application/json" -Body $agentBody | ConvertTo-Json -Depth 6 | Out-File D:\build\_agent2.json -Encoding utf8

6.3 Session → Turn → 结果 ​

powershell
# Session(target.type=agent + id)
Invoke-RestMethod -Uri "http://localhost:18080/api/v1/agent-sessions" -Method Post -Headers $h `
  -ContentType "application/json" -Body '{"target":{"type":"agent","id":"<agentId>"}}'
# Turn(Idempotency-Key 必带;中文消息用 UTF-8 字节)
$bytes = [System.Text.Encoding]::UTF8.GetBytes('{"message":"你好,请用一句话介绍你自己。"}')
Invoke-WebRequest -Uri "http://localhost:18080/api/v1/agent-sessions/<sessionId>/turns" -Method Post `
  -Headers @{Authorization="Bearer $jwt"; "X-AgentScope-Tenant"="default"; "Idempotency-Key"="m4-verify-001"} `
  -ContentType "application/json; charset=utf-8" -Body $bytes -UseBasicParsing   # → 202 queued
# 轮询 turn 状态 → completed,result=模型回答
Invoke-RestMethod -Uri "http://localhost:18080/api/v1/agent-sessions/<sessionId>/turns/<turnId>" -Headers $h

验收标准:turn status=completed;result 为正常中文回答;snapshot 含 model=qwen3.8-flash ×2 调用 completed + message_id=chatcmpl-… + 工具调用(memory_search/list_files 可选出现)。

6.4 幂等 + SSE(M5 抽测复跑) ​

powershell
# 幂等:同 key 发两次 → 返回同一 turn id,只执行一次
# SSE:事件链完整 + cursor 续传
curl.exe -s -N --max-time 8 -H "Authorization: Bearer $jwt" -H "X-AgentScope-Tenant: default" `
  "http://localhost:18080/api/v1/agent-sessions/<sessionId>/events/stream"
# 期望:session.status_running → … → item.delta(chatcmpl-…) → turn.completed,每事件带 cursor

7. 关键凭据与 ID(重建后全部为新值) ​

对象位置 / 重建方式
admin 密码deploy.env → CONTROL_PLANE_BOOTSTRAP_PASSWORD
模型 key / 网关deploy.env → OPENAI_API_KEY / OPENAI_BASE_URL(token-plan compatible-mode)
agent / binding / session / env随 §6 重建,新 UUID(参考:agent=86a8ba5b-…、session=23c43553-…)
镜像本地 as-dataplane:local-openai;官方 sca-registry.cn-hangzhou.cr.aliyuncs.com/agentscope/as-*:2.1.0-BETA1
源码agentscope-java official-main(构建副本 D:\build\agentscope-java;工作树 02-项目代码\agentscope-java)

8. 已知坑速查(防止重踩,详见 30-台账) ​

#坑一句话解法
1中文路径破坏 protoc构建/克隆必须纯 ASCII 路径(D:\build)
2幂等键复用冲突每次验证用新 Idempotency-Key
3PowerShell -Dxxx 报 Unknown lifecycle phase参数整体加引号
4docker.io 拉镜像超时(IPv6)只用本机缓存 / ACR;Dockerfile FROM 本地 ACR 镜像
5官方 release 镜像接不了兼容网关必须本地构建 + openai 扩展 + model: openai:qwen3.8-flash
6旧格式创建 agent 报 store: conflictbinding 放顶层 + 租户 header + definition 内 defaultEnvironmentId/model
7pwsh 直接打印 API 结果抽风一律 Out-File 到临时文件再 Read
8控制台 UI Chat 发消息无回答官方 main 运行时缺陷(UI 会话未进执行管线/历史读空/events 403);API 链路不受影响,验收走 API;修复跟踪台账 #9/#10
9Turn 报 JdbcStore putIfVersion (insert) failed长路径做 item_key 超 255(VARCHAR 截断)→ 先执行 item_key 扩容 DDL(见 §8.1),再重建 data

8.1 M5/M6 扩展部署(2026-10-26 补,全部实证) ​

8.1.1 Schema 修复(item_key 扩容,M6 前置) ​

坑 9 的 DDL(PG 容器内执行;db 凭据从 docker inspect agentscope-service-db-1 / compose.yaml 取,-U postgres 不通):

powershell
docker exec -i agentscope-service-db-1 psql -U <db_user> -d agentscope -c "ALTER TABLE dp.agentscope_store ALTER COLUMN item_key TYPE VARCHAR(2048);"
# 验证:SELECT max(octet_length(item_key)) FROM dp.agentscope_store;  (应 ≤2048)

根因:runtime 用长路径做 item_key 超过 255 上限,JdbcStore 把 SQLException 吞成 IllegalStateException(30 台账坑 1)。改后 docker compose up -d --force-recreate data(K12)。

8.1.2 MCP 运行时(M5,真实 MCP server 实证) ​

powershell
# 1) 起真实 MCP server(everything)
npx @modelcontextprotocol/server-everything streamableHttp   # 监听 0.0.0.0:3001
# 2) definition 挂 mcpServers(PATCH 全量替换,必须带 version 乐观锁,缺则 400)
#    body: {version, name, system, model, mcpServers:[{name:"everything", url:"http://host.docker.internal:3001/mcp"}], ...}
# 3) 验证
#    data 日志:MCP client 'everything' registered successfully → Registered MCP server (transport=http)
#    turn 触发模型自主选工具 everything__echo → snapshot required_action(kind=confirmation) 挂起
#    runtimeStatus=requires_action / stopReason=tool_confirmation / approvalId=expiresAt=+1h
# 4) 审批放行:user.tool_confirmation 批准 → 工具执行并回填 → turn completed

8.1.3 Skill 运行时(M5,definition.skills) ​

powershell
# definition 顶层 skills:[{name, type:"workspace"}] 启用工作区技能
# 内容源:SkillRepositoryConfigEntry(type: filesystem|git)经 SkillRepositorySupport.createAll 装配
# 实证:体验层"开放技能包"场景(30 §5.14)四链路原生支持
# 注意:definitionFiles 快照不同步是官方限制(30 §5.6②);Nacos 内容需自定义装配 NacosSkillRepository(32 篇 3.5 定论)

8.1.4 Higress AI 网关(M6,机制已实证) ​

powershell
# 正式部署/重建:走官方脚本(Linux/CI 有 bash 环境)一步到位,会创建默认 Gateway+listener:
curl https://higress.cn/ai-gateway/install.sh | bash
# 本机(无 bash)手动 docker run 的默认 listener 不生效——不再手动深挖(30 §5.11)
# 验证:provider/密钥/路由三要素落盘;gateway 8080 监听
# 切换:agentscope data 面 base-url 指向 Higress AI 端点(模型统一入口+密钥集中+按 model 路由)

8.1.5 QwenPaw 实例(M6,员工数字分身容器形态) ​

powershell
docker pull docker.1panel.live/agentscope/qwenpaw:latest   # docker.io 443 超时 / ACR 无权限,用 1panel 镜像
docker tag docker.1panel.live/agentscope/qwenpaw:latest agentscope/qwenpaw:latest
docker run -d --name qwenpaw -p 8088:80 ...   # dashboard 127.0.0.1:8088;三卷 qwenpaw-data/secrets/backups
docker exec -it qwenpaw qwenpaw models add-provider tokenplan -n 'TokenPlan' -u 'https://token-plan.maas.qianwenaiapi.com/compatible-mode/v1'
docker exec -it qwenpaw qwenpaw models add-model tokenplan -m qwen3.8-flash   # 双行 stdin 喂 config-key
# active slot 用 docker cp 改写 /app/working.secret/providers/active_model.json = {"provider_id":"tokenplan","model":"qwen3.8-flash"}
docker exec qwenpaw qwenpaw task -i '一句话回答' --output-dir /tmp/qwp --timeout 120   # 冒烟
# 会话入口:POST /api/console/chat(注意 /api 前缀,/console/chat 405);opencode 委托走 delegate_external_agent(action=start/close)

9. 交接验收清单(新环境重建判定) ​

  • [ ] docker compose ps 全 running;data /actuator/health = UP
  • [ ] jar 含 agentscope-extensions-model-openai
  • [ ] 登录拿到 JWT(roles 含 admin)
  • [ ] 一轮 turn completed 且中文回答正常(UTF-8 发送)
  • [ ] 幂等:同 key 双发同 id、单次执行
  • [ ] SSE 事件链完整(含 chatcmpl message_id、cursor)
  • [ ] snapshot 显示 model=qwen3.8-flash 调用 completed

以上全部通过 = 环境重建成功,可与本环境(2026-10-25 状态)对等继续开发。

把 AI 工程讲到既懂也会用