pigo 协作 —— 调用文档
在 Docker 容器内运行一个 pigo agent(单 agent)完成 /blackboard/task.md 中的任务,工作区为 /blackboard/workspace,完成时通过 blackboard 工具创建 DONE;supervisor 把结果以结构化 JSON(result.json)落盘,供外部调度方直接解析。
1. 原理与架构
+------------------ docker 容器 pigo-coop ----------------+
| |
TASK/MODEL/ | +---------- supervisor.sh(单 agent 编排)-------+ |
API_KEY ──────┼─▶ | 每轮运行一个 pigo 进程: | |
| | └─ agent ──▶ cwd = /blackboard/workspace | |
| | (--resume 会话 · 角色 prompt agent.md) | |
| +──────┬────────────────────────────────----------+ |
| ▼ |
| /blackboard(任务黑板:task.md + workspace + DONE) |
+-----------------------------------------------------------+
- 单 agent:每轮一个 pigo 进程串行推进,无评审者;工作区
/blackboard/workspace是普通文件工具(read/write/bash)的根目录。 - 原子完成标记:
DONE只能通过blackboard工具done(O_CREATE|O_EXCL)创建,supervisor 检测到DONE即收尾。 - 连续上下文:headless 运行自动持久化会话,supervisor 从 stream-json 首事件提取
sessionId,下一轮用--resume恢复,agent 跨轮记住自己的思考。 - 协议注入:任务协议(AGENTS.md)副本放入工作区,pigo 自动注入系统提示;角色 prompt 通过
--append-system-prompt注入。 - 结构化结果:任务结束(成功/未解出/超时/失败)统一写
$BB/result.json,字段:status、exit_code、summary、flag、artifacts。
2. 前置条件
| 依赖 | 说明 |
|---|---|
| Go 工具链 | 版本与 go.mod 一致(当前 go 1.27rc1),用于交叉编译 pigo 二进制 |
| Docker | 本机已有基础镜像 pigo-worker:latest(Alpine,含 bash/git/wget/flock/timeout/CA 证书) |
| 模型后端 | 任意 OpenAI 兼容 API(如 DeepSeek、Ollama、OpenRouter),需可访问的 base-url 与 API key |
3. 构建
3.1 交叉编译 pigo(含 blackboard 工具)
Windows PowerShell:
$env:GOOS="linux"; $env:CGO_ENABLED="0"
go build -trimpath -ldflags="-s -w" -o coop/tmp/pigo-linux-amd64 ./cmd/pigo
Linux/macOS:
GOOS=linux CGO_ENABLED=0 go build -trimpath -ldflags="-s -w" -o coop/tmp/pigo-linux-amd64 ./cmd/pigo
产物 coop/tmp/pigo-linux-amd64 是纯静态 Linux 二进制(约 30MB)。
3.2 构建镜像
docker build -f coop/Dockerfile -t pigo-coop .
镜像直接
FROM pigo-worker:latest(复用本机已有镜像,不拉取 golang/alpine),只覆盖 pigo 二进制并加入 supervisor 与协作 prompt,构建通常秒级完成。
4. 环境变量(运行参数)
| 变量 | 必填 | 默认值 | 说明 |
|---|---|---|---|
MODEL |
✅ | — | 模型名,如 deepseek-chat |
BASE_URL |
✅ | — | OpenAI 兼容 API base-url |
API_KEY |
✅ | — | API key |
PROTOCOL |
否 | 按 model 推断 | 协议 openai / anthropic |
TASK |
二选一 | — | 任务描述;不填则需挂载 $BB/task.md |
BLACKBOARD |
否 | /blackboard |
黑板根目录(即 BB) |
PROMPTS |
否 | /prompts |
协作 prompt 目录(镜像内固定,一般不用改) |
ROUND_MAX |
否 | 10 |
最大轮次 |
TIMEOUT |
否 | 600 |
单轮超时秒数,0=不超时 |
FAIL_MODE |
否 | stop |
agent 失败时:stop=立即退出(默认)| continue=继续下一轮 |
5. 运行示例
5.1 最小运行(真实模型)
docker run --rm \
-e MODEL=deepseek-chat \
-e BASE_URL=https://api.deepseek.com \
-e API_KEY=<your-key> \
-e TASK="请为 XX 编写设计文档并实现原型" \
-e ROUND_MAX=6 \
pigo-coop
5.2 保留黑板产物与连续会话(推荐)
mkdir -p blackboard
docker run --rm \
-v $PWD/blackboard:/blackboard \ # 黑板产物落盘
-v $HOME/.pigo:/root/.pigo \ # 保留 agent 会话(--resume 依赖)
-e MODEL=deepseek-chat \
-e BASE_URL=https://api.deepseek.com \
-e API_KEY=<your-key> \
-e TASK="..." \
pigo-coop
会话持久化在
~/.pigo/sessions(容器内为/root/.pigo)。不挂载$HOME时,会话只存在于容器生命周期内——跨docker run不保留;每次run内部跨轮仍有效。
5.3 结果与退出码
- 任务完成(检测到
DONE):退出码0,result.json的status=solved。 - 达到
ROUND_MAX仍未完成:退出码1,status=unsolved,检查黑板与日志。 - 单轮超时被强杀:
status=timeout(退出码 124)。 - 参数缺失 / 非法:退出码
2。
6. 黑板目录结构
/blackboard/
├── task.md # 任务描述(勿修改)
├── AGENTS.md # 任务协议(工作区有副本)
├── workspace/ # agent 工作区 = 其 cwd(产物全部在这里)
├── DONE # 完成标记(只用 blackboard done 创建)
├── result.json # 结构化结果(supervisor 结束时生成)
├── sessions/ # agent 的 session id(supervisor 内部维护,供 --resume)
└── logs/ # 每轮运行日志:round-N.log
7. blackboard 工具(agent 侧 API)
pigo 在 BB 环境变量存在时自动注册 blackboard 工具;普通运行不受影响。agent 通过该工具原子读写黑板:
| 操作 | 参数 | 行为 |
|---|---|---|
read |
(可选 path) |
无 path:返回黑板全局快照(task.md、workspace 清单、DONE 状态、环境);有 path:返回黑板内单文件内容(如 workspace/exploit.py) |
post |
file、content |
原子追加消息到 messages/<file>;file 必须是裸 *.md 名(防目录穿越),内容 ≤ 32 KiB |
done |
summary |
原子创建 DONE(`O_CREATE |
环境变量 BB / ROUND / NAME 由 supervisor 注入。
8. 验证与调试
8.1 无模型端到端验证(mock)
coop/tmp/mock_openai.py 是一个 OpenAI 兼容 mock server,驱动 agent 依次调用 blackboard done,用于验证单 agent 编排与 DONE 原子性:
# 终端 1:启动 mock(本机)
python coop/tmp/mock_openai.py 8899
# 终端 2:运行容器,base-url 指向 mock(按环境替换宿主地址)
docker run --rm \
-v $PWD/blackboard:/blackboard \
-e MODEL=mock -e BASE_URL=http://<host-ip>:8899 -e API_KEY=test \
-e TASK="验证任务" -e ROUND_MAX=3 -e TIMEOUT=120 \
pigo-coop
预期:agent 完成并创建 DONE,容器退出 0,blackboard/result.json 中 status=solved。
8.2 查看日志
# 黑板挂载后:
cat blackboard/logs/round-1.log # 第 1 轮的 stream-json 事件
cat blackboard/sessions/agent.session # 下一轮 --resume 用的 session id
8.3 常见问题
| 现象 | 原因 / 处理 |
|---|---|
退出码 2 且提示缺 MODEL/BASE_URL/API_KEY |
未传必填环境变量 |
容器内报 DONE already exists |
正常:DONE 幂等,上一次运行已留标记 |
| 跨 run 后 agent 不记得之前轮次 | 未挂载 $HOME/.pigo;会话在容器内 ~/.pigo/sessions,--rm 后丢失 |
docker build 报找不到 pigo-worker:latest |
先 docker pull 或在目标机导入该基础镜像 |
构建期 chmod 被拒 |
已用 COPY --chmod=755 规避(NTFS 挂载构建上下文会丢可执行位) |
9. 任务协议要点(详见 /blackboard/AGENTS.md)
每轮:读取 task.md → 检查已有产物 → 推进任务 → 完成后用 blackboard done 创建 DONE。红线:不直接写 DONE;不伪造命令/提交结果;不修改 task.md 与 AGENTS.md。