报错现象
你希望用 /teamwork 把一项科研或工程任务,拆成几个可以同时跑的子实验,派给多个智能体并行执行,最后汇总结果并交叉复核。任务拆解、并行执行和合并复核这三步,通常会在下面几种情况下出错(报错文案因界面和版本而异,具体内容以官方文档当前版本为准):
1. 合并阶段抛出与上下文超限同类的错误,例如 context length exceeded、combined context is too long 一类提示。它出现在执行 /teamwork 汇总的时候,而不是在单个子智能体执行的时候。影响是:前面并行跑的实验结果无法自动汇总,只能人工从各个会话里抄结论。
2. 子智能体返回空结果或答非所问,表现为 agent returned no result,或者结果里只有一句“已按要求完成”。影响是:复核环节拿不到可核对的内容。
3. 合并没有报错,但结论互相矛盾:两组子实验对同一个指标给出不同数值,汇总时被自然语言“揉”成一句话,看上去正常,实际上不可用。这类问题不会留下报错信息,最难发现。
4. 工具调用超时或中途中断:tool call timed out、command timed out after Ns、rate limit 一类。影响是:部分子实验失败,剩下的结果不完整。
5. 重派之后出现重复劳动或结果互相覆盖:同一个输出文件被两个子任务先后写入,最后留下的是哪一份说不清。
适用范围:单机单人使用,任务包含 3~10 个可并行子实验,数据规模中等(几万条以内或几个 GB 以内)。任务规模再大一些时,需要改用真正的作业调度,而不是单纯的并发对话。
可能原因
按实际出现的概率从高到低排列:
1. 任务拆分得过粗,边界模糊。子任务描述里带着“等相关方法”“适当调参”“酌情处理”这类词,每个智能体对任务的理解都不一样,结果自然对不上。
2. 多个子任务共享同一个写入路径。所有子实验都往 results/ 或同一个 notebook 里写,并发时就互相覆盖。
3. 上下文预算没有事先估算。把每个子实验的完整运行日志原样交给汇总环节,三五个子任务就把上下文撑满了。
4. 输出格式不统一。有的子任务交回 Markdown 表格,有的交回一段散文,汇总只能靠模型“读一遍再总结”,误差由此产生。
5. 复核并没有真正做到交叉复核。让同一个智能体、用同一套 prompt 检查自己刚出的结论,等于自己评自己,发现不了系统性偏差。
6. 并发数量、超时或额度设置超过了实际环境的能力上限。
7. 各子实验的环境不一致:依赖版本、随机种子、数据快照不同,数值不可比。
8. 重派策略粗暴:失败一个就整批重跑,导致已经成功的结果被新结果覆盖。
逐条排查与解决
第 1 条:任务拆分粒度
判断方法:查看子任务清单里有没有模糊词。
```bash
mkdir -p tasks runs results
grep -nE '等|相关|酌情|适当|视情况' tasks/*.md
```
只要有命中,就说明这条子任务无法独立验收。改成固定五要素模板,每个子任务写满五项,缺一项就不派发:
```markdown
子任务 <ID>:<一句话目标>
输入
- 数据:<绝对路径或快照 ID>
- 基线代码:<git commit>
- 固定参数:<随机种子、超参数、切分方式>
方法
- 只做一件事:<具体操作>
- 允许修改的文件:<路径白名单>
- 禁止:改动共享数据、改动其他子任务目录
输出(写入 runs/<ID>/summary.json)
{
"task_id": "<ID>",
"metric_name": "<指标名>",
"metric_value": 0.0,
"seed": 0,
"n_samples": 0,
"status": "success|failed",
"notes": "<不超过 100 字>"
}
验收标准
- summary.json 能被 jq 解析且字段齐全
- 指标可复现:同种子重跑一次,数值一致
预算
- 超时:<分钟>
- 最多重试:1 次
```
第 2 条:共享写入冲突
判断方法:
```bash
git status --porcelain
find runs -maxdepth 2 -newer tasks -type f | sort
```
如果两个不同子任务的产物落在同一路径,就是这个问题。
解决:每个子任务一个独立工作区。
```bash
git worktree add runs/exp-01 -b exp-01
git worktree add runs/exp-02 -b exp-02
```
并在模板里明确写死:产物只允许写入 runs/<ID>/。
第 3 条:上下文超限
判断方法:先量体积。
```bash
du -sh logs/* runs/*/summary.json 2>/dev/null | sort -h
wc -c results/*.json
```
如果 logs/ 有几十 MB 而汇总只需要几个数字,问题就在这里。
解决:分层——原始日志留在磁盘上,子任务只回传 summary.json,汇总环节只读 summary。
```bash
jq -s '[.[] | {task_id, metric_name, metric_value, seed, status}]' \
runs/*/summary.json > results/merged.json
```
把 merged.json(通常几 KB)交给 /teamwork 汇总,而不是日志。
第 4 条:输出格式不统一
判断方法:批量校验。
```bash
for f in runs/*/summary.json; do
jq -e 'has("task_id") and has("metric_value") and has("status")' "$f" \
|| echo "BAD: $f"
done
```
有 BAD 就说明格式没对齐。把校验命令写进子任务模板的验收标准,不合格直接算失败,进入重派流程。
第 5 条:复核没有真正交叉
判断方法:看复核者是谁。如果复核 prompt 和被复核子任务的 prompt 出自同一份文本,就是这个问题。
解决:交叉配对 + 固定清单。A 组的结果交给 B 组复核,反之亦然;复核者只看产物、不看原任务的执行过程。
```markdown
复核任务 <ID>
你拿到的是子任务 <X> 的 summary.json 和对应代码 diff。
只做三件事,不要重跑实验:
1. 复算:用 diff 里的代码和记录的 seed,独立复算一次指标,记录你的数值。
2. 对齐:你的数值与 summary.json 的差异是否在 <容差> 内。
3. 判定:一致 / 不一致 / 无法判定,并给出一句话理由。
输出到 runs/<ID>/review.json,字段:reviewer, target, recomputed_value, verdict。
```
再汇总:
```bash
jq -s 'group_by(.target) | map({target: .[0].target, verdicts: map(.verdict)})' \
runs/*/review.json
```
只要出现“不一致”,先不合并,回到第 1 条查拆分。
第 6 条:并发与超时
判断方法:看失败是否集中在时间点附近。
```bash
grep -h 'timed out\|timeout\|rate limit' runs/*/log.txt | sort | uniq -c
```
解决:先把并发降到 2 路验证一轮,再逐步加;单条命令加硬超时:
```bash
timeout 1800 python run_experiment.py --config runs/exp-01/config.yaml
```
/teamwork 是否支持直接传并发数、超时上限,各版本不同,以官方文档当前版本为准;不支持就在任务模板里用 shell 的 timeout 兜住。
第 7 条:环境不一致
判断方法:比对锁文件与提交号。
```bash
git rev-parse HEAD
pip freeze > env.lock # 或 conda list --export > env.lock
sha256sum data/snapshot.tar
```
把 commit、env.lock、数据哈希写进每个子任务的“输入”段;汇总前先比对,不一致的结果直接作废重跑。
第 8 条:重派覆盖了成功结果
判断方法:看 runs/ 下有没有时间戳接近、内容不同的同名文件。
解决:重派只针对失败子任务,且换新目录。
```markdown
重派任务 <ID>-r1
沿用 <ID> 的输入与方法,只改一处:<具体修正点>。
输出写入 runs/<ID>-r1/summary.json,不要修改 runs/<ID>/ 下的任何文件。
若本次仍失败,在 notes 里写清失败位置,不要重试第二次。
```
```bash
保留历史,不覆盖
mv runs/exp-01 runs/exp-01.failed-$(date +%Y%m%d%H%M)
```
都不管用时的兜底方案
- 降级为串行:一次只派一个子任务,跑完再派下一个。并行带来的加速没了,但能把“并发冲突”这一类问题一次性排除掉。
- 先跑通一个:只保留 1 个子实验,把模板、schema、复核清单全部走通,再扩到多路。多数合并失败是模板没验证就批量派发导致的。
- 合并交给脚本,不交给模型:用
jq -s生成一张表,人工看表下结论。模型只用来解释异常值,不用来做数值合并。 - 复核换人:智能体互相复核仍打架时,把两份
summary.json和复算脚本交给同事手工跑一遍,以复算结果为准。 - 完全退出 /teamwork:手动开几个独立会话,套用同一份任务模板,产物落同一套目录结构。协作流程保留了,编排工具先放一边,等模板稳定再回来。
如何预防再次发生
1. 把模板和 schema 提进仓库:tasks/_template.md、results/schema.json、check.sh 一起版本化管理,新任务只能从模板复制。
2. 目录与分支先隔离再派发:runs/<任务>-<序号>/ + git worktree,模板里写明写入白名单。
3. 只汇总 summary,不汇总过程:原始日志留盘归档,汇总环节永远只读小文件。
4. 复核强制交叉:复核者与被复核者不共享 prompt,复核结果单独落 review.json 并做机器判定。
5. 设预算上限:每个子任务写死超时和重试次数,重派上限 1 次,避免无限重试烧额度。
6. 每次任务后留一份复盘:记录失败子任务、失败原因、是否重派、最终是否合并。跑三五次之后,你会发现自己反复踩的是同一两个坑。
7. 工具能力以官方文档当前版本为准:/teamwork 的并发上限、超时参数、AI 词典:上下文窗口">上下文窗口会随版本变化,把关键数值写进自己的检查脚本,而不是记在脑子里。
