主题
31-环境重建与自动化部署手册
一句话:手册的判据只有一条——任何工程师在干净环境从零把链路重建到跑通:命令可贴、坑已标注、验收可逐条勾;它只写“怎么重建”不复述“为什么”,正因如此,环境版本、镜像源、网关协议这些约束必须钉死成口径,否则复跑结果靠的是运气而不是交接。
定位:本平台(基于开源 agentscope-service 官方 main 构建的企业智能体平台)的可执行交接文档——任何工程师在干净环境上,从零重建到 M4 链路跑通。 口径:命令基于 Windows + pwsh 7(本环境);Linux 仅路径/镜像名差异,命令主体相同。结论可复核、命令可复跑、坑已标注。 配套:《30-搭建过程与问题解决台账》记录"为什么"(根因/选型),本文记录"怎么重建"(步骤/命令/验收)。
1. 环境要求(M1 基线)
| 项 | 要求 | 本环境参考 |
|---|---|---|
| OS | Windows 10/11(Linux 亦可,路径改 /) | Windows |
| 容器 | Docker Desktop(引擎必须运行) | 安装路径 C:\Users\Administrator\AppData\Local\Programs\DockerDesktop\Docker Desktop.exe(不在 Program Files) |
| JDK | 21(官方构建要求) | D:\Java\jdk-21.0.8 |
| Maven | 3.9.x | D:\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.jarpowershell
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_PASSWORD | admin 初始密码(新环境必改) |
| 数据库 | .env → POSTGRES_PASSWORD / POSTGRES_DB=agentscope | PG 凭据 |
| 模型 key | .env → OPENAI_API_KEY | token-plan 网关 key(sk-sp-…,在 .env 中维护,勿提交) |
| 模型网关 | .env → OPENAI_BASE_URL | https://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 utf86.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,每事件带 cursor7. 关键凭据与 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 |
| 3 | PowerShell -Dxxx 报 Unknown lifecycle phase | 参数整体加引号 |
| 4 | docker.io 拉镜像超时(IPv6) | 只用本机缓存 / ACR;Dockerfile FROM 本地 ACR 镜像 |
| 5 | 官方 release 镜像接不了兼容网关 | 必须本地构建 + openai 扩展 + model: openai:qwen3.8-flash |
| 6 | 旧格式创建 agent 报 store: conflict | binding 放顶层 + 租户 header + definition 内 defaultEnvironmentId/model |
| 7 | pwsh 直接打印 API 结果抽风 | 一律 Out-File 到临时文件再 Read |
| 8 | 控制台 UI Chat 发消息无回答 | 官方 main 运行时缺陷(UI 会话未进执行管线/历史读空/events 403);API 链路不受影响,验收走 API;修复跟踪台账 #9/#10 |
| 9 | Turn 报 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 completed8.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 状态)对等继续开发。