子 agent:一个 agent 忙不过来、或需要别人把关时,怎么分工?
本章一问:一个 agent 忙不过来、或需要别人把关时,怎么分工?
主线定位
下面是累计数据流,本章点亮「子 agent」。它在循环之外:子 agent 自己是一整个循环,嵌在父 agent 的一次工具调用里。
本章问题链
每一课只回答一个问题;上一课的失败,逼出下一课的问题。
| 课 | 这一课的问题 | 朴素方案在哪个真数字上失败 | 一句话 |
|---|---|---|---|
| 第 1 课 | 要在整个仓库里找全 parse_date 的调用点,都读进主上下文吗? | 主 agent 自己 grep:24 行结果里真正的调用点 5 行,从此每轮重发;两次运行主窗口峰值 1,767 / 2,328 | 子 agent 省的是主上下文,不是总 token |
| 岔路 | 多个 agent 同时改代码,怎么不互相踩? | 两个 agent 同时往同一个文件追加一行,不加锁时 3 行只剩 2 行(构造输入 · 真算法) | 并行写之前先切开写的范围:不同任务用 worktree,同一个文件排队写;两者都不是沙箱 |
| 岔路 | Pi 为什么不内置子 agent? | 子 agent 扩展 1,141 行,权限确认扩展 34 行 | 不内置不等于不支持:Pi 把子 agent 留给扩展 |
| 第 2 课 | 子 agent 只拿到一句任务描述,会丢掉什么? | 只给任务文本:交接只有 28 token,丢了 D1、D3、D4;子 agent 看到 5 个真实调用点,报回的全是 import、注释与定义行 | 行动里藏着决定,只传任务文本就会丢掉它们 |
| 第 3 课 | 子 agent 能无限派下去吗?轮数预算算谁的? | 父子共用计数:t4-sub-dec-s1 的父 agent 自己只要 3 轮,上限得给到 7 | 每一层都要有自己的深度闸和预算 |
| 第 4 课 | 干活的 agent 评自己的活,可信吗? | 32 次真实运行里明确声称完成 20 次,验收失败 12 次;一个只读的子 agent 说「已写进 CALLERS.md」 | 干活的和评活的必须分开,评活的不能动手改 |
| 实验课 | 有 / 无子 agent 的真实对照 | — | 用自己的 trace 定 M7 的四个决策 |
演进地图
本章的「现代做法」是被一连串真实数字逼出来的。每一课都会用这张图标出「你在这里」。
- 所有 harness 的默认形态;本课项目 T4 的「不用子 agent」两次运行解决了不需要交接:主 agent 亲眼看到每一行搜索结果,不会有信息在转手时丢失。卡在两次 grep 结果进主上下文 563 / 1,120 token,之后每轮跟着重发(A5);要判对兼容性还得读 7 个文件(内容 1,818 token),两次都没读——找到 5/6 与 5/6,兼容性判对 3/6 与 2/6。
- learn-claude-code s06、CoreCoder AgentTool、OpenCode task、Claude Code 子 agent、本课项目 delegate解决了搜索的中间结果留在子 agent 自己的窗口里;4 组对照里 3 组主上下文峰值更低。卡在sub-text-s2 的子 agent 在自己的 grep 里看到了 5 个真实调用点,报回的 9 个「调用点」里 9 个是 import、注释或定义行;父 agent 照抄,verifier 找到 0/6。
- 本课项目 with_decisions、Hermes 的 context 字段、Codex v2 的 fork_turns(默认 all)、Claude Code 的 fork解决了子 agent 拿到了父 agent 的全部约束;sub-dec-s1 的子 agent 报回的真实调用点行号 5/6。卡在两次仍然 0/6:s1 的子 agent 一个文件都没读就猜兼容性,父 agent 全程 write_file 0 次却说「已写进 CALLERS.md」;s2 的子 agent 正则写错,15 轮预算只用了 3 轮就交差。
- OpenCode subagent_depth、Codex agent_max_depth、Hermes max_spawn_depth(默认都是 1);Claude Code 默认 3 层;Hermes、CoreCoder、lcc、本课项目的子 agent 预算独立解决了递归有上界;子 agent 的轮数不挤占父 agent:sub-dec-s1 的父 agent 只需要 3 轮,父子共用一个计数时得给到 7。卡在预算防的是停不下来,不防过早收工:T4 的 4 个子 agent 各有 15 轮,最多只用了 4 轮。
- learn-claude-code s17 独立评估器、Codex Guardian(A3)、Anthropic cwc-long-running-agents 的 evaluator、Hermes 后台自省 fork解决了完成与否不再由干活的 agent 自己说了算;评审者没有写工具,不能顺手「修好」来掩盖问题。卡在T1 与 T4 里最后一句话明确声称完成 20 次,verifier 判失败 12 次;评审者也是模型,也会被说服 → 确定性的判决在 A9。
数字口径:本课项目 miniagent 用 Qwen/Qwen3-8B-MLX-4bit 本机录制的 T4(2026-09-26,找全 parse_date 调用点,6 次运行 + 4 条子 agent trace;单一模型、每种配置 2 个 seed,只说明现象存在,不说明比例)。token 取自服务端 usage;「内容 token」用录制模型的 tokenizer 现数。耗时不作比较(本机有其他任务同时占用)。
贯穿任务:修好 test_parse_date 之后,谁还在用它?
全课的贯穿任务是让失败的 test_parse_date 通过。它修好之后自然冒出下一个问题(大纲任务约束第 5 条):parse_date 改成「日在前」,仓库里还有谁在调用它、会不会受影响?本课项目把这一步做成任务 tasks/callers,录成 T4。为什么换任务:修 bug 本身只读一两个文件,用不上分工;「找全调用点」要搜整个仓库、读很多文件而只要一张表,是子 agent 被设计来做的那类活。这一章给贯穿 trace 加上子 agent 分支:子 agent 自己的一串轮次、独立的预算,以及两条 token 流——交接下去、报告回来。
- T4 的六次运行(本课项目 miniagent,Qwen/Qwen3-8B-MLX-4bit,本机 2026-09-26):不用子 agent、用子 agent 只给任务文本、用子 agent 带上父决定,各跑 seed 1、2。子 agent 只读、权限默认拒绝、预算 15 轮、深度上限 1。
- 6 次全部没通过验收(不用子 agent 的两次找到 5/6 个调用点,用了子 agent 的四次都是 0/6)。主窗口峰值 4 组对照里 3 组因为子 agent 而更低。本章的结论只到机制一层:隔离让主窗口更小、交接会丢信息、预算要按层算、自述会出错;不下「子 agent 让结果更好」的结论。单一的小模型、每种配置 2 个 seed,只在这个规模上成立。
- 录制时第一次跑的一条运行因为本课项目 grep 工具的缺陷作废重录了(第 4 课与实验课的深挖里讲),它不在本章的任何数字里。
三层交互
| 层 | 本章里的组件 | 在哪一课 |
|---|---|---|
| 概念动画 | 演进地图(每一代卡在哪个真数字上);泳道的聚合 ↔ 展开 | 每一课、岔路 B1 |
| 算法模拟器(真算法、小数据) | Hermes 的 consume / refund 在真实事件序列上逐步计数,切「各一份 / 共用一份」;四个深度闸在同一组输入上的裁决表;Pi 的同文件写队列在浏览器事件循环里真跑一次竞争 | 第 3 课、岔路 B1 |
| 真实数据 | 三次运行并排的主窗口 / 子窗口 token 流与调用树;两种交接的逐层信息丢失(先猜后揭示);32 次运行的「声称 vs 验收」,点一行跳到那一轮 | 第 1、2、4 课、实验课 |
所有算法都在浏览器里现算,不联网。预算与深度闸的移植配了自检:Hermes 的 IterationBudget 用 python 直接加载 pin 原类跑出期望,OpenCode 与 Codex 的深度闸分别用 bun 与 rustc 在 pin 源码的逐字切片上跑,Hermes 的深度闸执行原文函数,本课项目真跑 DelegateTool.execute;组件右上角显示与原实现一致的条数。
项目推进:里程碑 M7 · 同步子 agent 工具
对应 04-实践项目/MILESTONES.md 的「A7 · 子 Agent 与编排」。实现已经在 miniagent/subagent.py:delegate(task[, decisions]) 在工具调用内部同步起一个子 agent,空历史、只读工具、权限默认拒绝、独立预算、深度上限 1,父 agent 只收到子 agent 的最后一段话。代码 AI 来写,决策你来做。
- 子 agent 的权限是否严格小于父 agent?本项目:是,只给只读工具、权限默认拒绝(A3·L4 的原则)。对照 CoreCoder:子 agent 用父 agent 同一套权限。第 4 课的只读强度表给了从「提示词」到「操作系统」的五档。
- 预算独立还是共享?本项目:独立,子 agent 用完时报告末尾写明。第 3 课的真实数字:共用一个计数时,t4-sub-dec-s1 的父 agent 需要的上限从 3 变成 7,t4-sub-dec-s2 从 5 变成 8。
- 深度上限多少?本项目 1,与 OpenCode、Codex v1、Hermes 的缺省一致;Claude Code 缺省 3 层。
- 要不要把父 agent 已定的决定显式传下去?怎么传?两种都录了。第 2 课:带上决定之后六条约束全部到位,但父 agent 已经看到的行号仍然没交出去。
验收标准(MILESTONES.md 的五条,附本章对照真实数据的结果):
- ① 用子 agent 时主上下文增量小于不用:4 组里 3 组成立;t4-sub-dec-s1 不成立(2,281 > 1,767),因为父 agent 先自己 grep 了一遍才派活。建议把这一条改写成量「delegate 报告进入主窗口的 token」与「同样的搜索结果进入主窗口的 token」之比,并加一条「父 agent 交接前不重复子 agent 的搜索」(Codex 的 spawn 指引原话:不要在主线与子任务之间重复同一件事)。
- ② 受限子 agent 调写工具被拒,拒绝以 tool result 回传:
tests/test_subagent.py的test_child_cannot_write。 - ③ 超过深度上限时报错而不是静默:
test_depth_limit_is_an_explicit_error;第 3 课的深度闸表里,本项目与原实现逐格一致。 - ④ 声称完成与 verifier 不一致时,以 verifier 为准:T4 里明确声称完成的 5 次全部没通过,harness 的
verify都记为失败。建议补一条父 agent 侧的规则:子 agent 报告里可核对的声称(「已写入某文件」)在转述前先核对(Hermes 工具说明里的原则,第 4 课)。 - ⑤ 导出 T4:
知识平台/src/data/project/agent-t4-subagents.json已导出。 - 建议补的两条(本章数据暴露的):(a)
with_decisions交接时由 harness 自动附上父 agent 已看到的 file:line,而不是指望父 agent 自己写进 decisions;(b)约定子 agent 报告的格式:每个结论配 file:line 与原行文本,父 agent 可以逐条抽查。
坑与带走
本章拦截的误解| 误解 | 纠正 | 在哪一课 |
|---|---|---|
| 子 agent 省 token | 省的是主窗口;总 token 要加上子 agent 的每一轮。本课项目里带上父决定的两次总数多了四成左右,只给任务文本的两次更少是因为做得少;Anthropic 自报多 agent 约为对话的 15 倍 | 第 1 课 |
| 子 agent 是隔离的,所以安全 | 隔离的只是消息;s06 的原话是「message isolation, not process or filesystem isolation」 | 第 1 课 |
| 把决定都传下去,子 agent 就不会出错 | 传下去的只是写下来的部分;父 agent 做过、看过的事照样会丢;子 agent 自己也会出错 | 第 2 课 |
| 多 agent 总比单 agent 强 | Cognition 的两条原则;Anthropic 自己也说大多数编码任务可并行的部分比研究少。T4 里找到调用点最多的是不用子 agent 的两次 | 第 2 课 |
| 子 agent 受父 agent 的上限约束 | 各家的子 agent 都各带一份预算,父子总数可以超过父 agent 的上限 | 第 3 课 |
| 预算够大,子 agent 就会把活干完 | 预算防停不下来,不防过早收工:T4 的子 agent 各有 15 轮,最多用了 4 轮 | 第 3 课 |
| 让它再检查一遍就能自我纠错 | 没有外部反馈时,推理任务上的自我纠正常常无效(Huang 等);编码任务有外部反馈可用——跑测试 | 第 4 课 |
| 评审者是另一个模型,所以客观 | 同一模型族偏爱自己的产出(Panickssery 等),评审者也会被说服;要只读、要新窗口,最终由可执行的检查判定 | 第 4 课 |
| worktree 就是沙箱 | worktree 只分开工作目录与分支;「It is not a sandbox」 | 岔路 B1 |
| Pi 的作者明确拒绝 multi-agent | 1-2 被否决的说法;只能说核心不内置、可以用扩展或 tmux 实现 | 岔路 B2 |
| 症状 | 后果 | 怎么办 |
|---|---|---|
| 把子 agent 当省钱手段 | 总 token 不降反升,还多了交接出错的机会 | 只在主上下文吃紧、或需要隔离的时候用;先算主窗口,再算总账 |
| 父 agent 先自己搜一遍再派活 | 两份搜索结果都进了主窗口,隔离白做(t4-sub-dec-s1) | 派出去的活,父 agent 不要重复做 |
| 只传任务文本 | 父 agent 的约束丢失,子 agent 把 import 当调用点(t4-sub-text-s2) | 显式传决定并附上原始任务;或 fork 继承历史,代价是上下文 |
| 报告里的行号、结论没有依据 | 父 agent 照抄错误,没法抽查 | 约定报告格式:每条结论配 file:line 与原行 |
| 父子共用预算、不限深度 | 父 agent 被子 agent 挤掉收尾的轮次;递归没有上界 | 每层各带一份预算 + 深度闸,超限显式报错 |
| 把子 agent 的自述当事实 | 「已写入」其实没写,父 agent 转述给用户(t4-sub-dec-s1) | 可核对的声称先核对;最终由 harness 的检查判定 |
| 评审者有写权限 | 顺手改掉问题,掩盖失败 | 评审者只读;强度按「提示词 → 工具表 → 权限规则 → 沙箱」往上选 |
带走这些句子(各课「一句话」):
- 子 agent 省的是主上下文,不是总 token。
- 并行写之前先切开写的范围:不同任务用 worktree,同一个文件排队写;两者都不是沙箱。
- 不内置不等于不支持:Pi 把子 agent 留给扩展,核心只保留能被扩展接上的接口。
- 行动里藏着决定,只传任务文本就会丢掉它们。
- 每一层都要有自己的深度闸和预算。
- 干活的和评活的必须分开,评活的不能动手改。
深入这一章
按你愿意花的时间选。每条都实际打开核对过(2026-09-26);站外链接都需要联网,离线包里只保留链接。
🎮 想更直观 10–30 分钟
🔬 想吃透原理 1–3 小时
📄 想读原文 按需
我替你排除了什么:Alejandro AO「Anthropic: How to Build Multi Agent Systems」等第三方转述视频(对官方博客的二次转述,没有增量)· analysis_claude_code 对 Claude Code 多 agent 的逆向(基于 v1.0.33,太旧)· win4r/cc-notebook 的多 Agent 架构篇(基于逆向或泄露代码,细节未经官方核实)· OpenAI Traces 等需要登录的可观测平台 · Datawhale hello-agents 第十四章「自动化深度研究智能体」(三个角色按代码写好的流程依次调用,是 A0 讲的 workflow,不是模型派出去的子 agent)与第九章 §9.2.3 的子代理一段(Anthropic《Effective context engineering》的中文转述,原文已在 A5 必看)· 把「15 倍」当成编码 agent 通用结论的转述文章(原文是研究任务、自家评测)。