Files
2026-08-14 23:41:57 +08:00

197 lines
8.2 KiB
Markdown
Raw Permalink Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# pigo 协作 —— 调用文档
> 在 Docker 容器内运行一个 pigo agent(单 agent)完成 /blackboard/task.md 中的任务,工作区为 /blackboard/workspace,完成时通过 blackboard 工具创建 DONEsupervisor 把结果以结构化 JSONresult.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
```powershell
$env:GOOS="linux"; $env:CGO_ENABLED="0"
go build -trimpath -ldflags="-s -w" -o coop/tmp/pigo-linux-amd64 ./cmd/pigo
```
Linux/macOS
```bash
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 构建镜像
```bash
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 最小运行(真实模型)
```bash
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 保留黑板产物与连续会话(推荐)
```bash
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 idsupervisor 内部维护,供 --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|O_EXCL`);已存在则报错且不覆盖。仅交付完整时调用 |
环境变量 `BB` / `ROUND` / `NAME` 由 supervisor 注入。
---
## 8. 验证与调试
### 8.1 无模型端到端验证(mock)
`coop/tmp/mock_openai.py` 是一个 OpenAI 兼容 mock server,驱动 agent 依次调用 `blackboard done`,用于验证单 agent 编排与 DONE 原子性:
```bash
# 终端 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 查看日志
```bash
# 黑板挂载后:
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。