Github 原文:shareAI-lab/learn-claude-code
问题
Agent 能计划了。但如果一个任务太大,比如”重构整个认证模块”,光靠 TODO 列表不够。这个任务本身就是几十个小任务的集合,放在同一个对话里会被上下文淹没。试想一下,Agent 在修一个 bug。它读了 30 个文件来追踪调用链,中间聊了 60 轮。messages 列表涨到 120 条,其中大部分是”追踪调用链”的中间过程,和”修 bug”这个最终目标无关。
这些中间过程占着上下文位置,让 Agent 越来越”健忘”,它记不住最初的问题是什么了。
或者说,你修 bug 的时候,会”开一个新终端”来追踪调用链。追踪完了,终端关掉,结果写进笔记,回到原来的终端继续修 bug——Agent 也需要这个能力:开一个独立的子进程,给它一个独立的消息列表,让它专心做一件事。
解决方案
📍 这里难度一下就上来了,要仔细看哦~
保留上一章的最小 hook 结构和 todo_write 工具,本章重点转向新增的 task 工具。调用它时,spawn 一个子 Agent,拥有全新的 messages[],跑自己的循环,结束后只把摘要文本回传给主 Agent。对话上下文被丢弃,但文件系统的副作用(写文件、改文件、跑命令)保留在工作目录中。
这就是之前我在介绍设计师新玩具 Claude Code的时候说的 Subagent 的概念,由主 agent 也就是 Parent agent作为实际用户在使用的 Agent,然后他会根据任务拆分若干个独立的 Subagent 来干活,最后他来验收结果串起来,把结果交给用户。
但这里要说明的,这个子 agent 并不完全和我们之前介绍的 Agent 的 loop 一样,他没有 task 工具,所以没法自己再派生新的子子 agent,而且它的安全策略不是独立的,受到主 agent 的 hook 的权限管理。
工作原理
spawn_subagent,给子 Agent 一个全新的 messages 列表,跑自己的循环,只回传结论,这就是这个 Subagent 的高明之处,这可以让主 Agent 的上下文非常干净,不会那么快就发生压缩。
整理来说,Subagent 这个东西有 4 个最关键的设计:
| 决策 | 选择 | 原因 |
|---|---|---|
| 上下文隔离 | 全新 messages[] | 子 Agent 的中间过程不污染主 Agent 的上下文 |
| 只回传结论 | extract_text(last_message) | 不是回传整个 messages 列表 |
| 禁止递归 | 子 Agent 无 task 工具 | 防止子 Agent 再 spawn 新的子 Agent |
| 安全策略不跳过 | 子 Agent 工具调用也走 PreToolUse hook | 上下文隔离不代表权限隔离 |

CC中的Subagent
更多种类的 Subagent
CC 的 Subagent 会更加复杂,不是我们常规的 loop 循环的 message 开头,他有 3 种:
| 模式 | 触发条件 | 上下文 |
|---|---|---|
| Normal Subagent | 指定了 subagent_type(normal path) | 全新 messages[],只有 prompt |
| Fork Subagent | 没指定 subagent_type,fork gate 开启 | 通过 buildForkedMessages() 构造 cache-friendly 前缀,共享 prompt cache |
| General-Purpose | 没指定 subagent_type,fork gate 关闭 | 同 Normal |
吓哭了,这上面的东西如数家珍,完全看不懂?别急,我们一个一个拆开来解释。
-
Normal:这个就是我们最常看到的 Subagent,我们指定或者 claude code 来指定的一个叫做 xxx 的 agent,例如要审查合同,老板说:“让法务来审查一下”,主 agent 就是老板,法务就是 Subagent。
-
General:这个就是个什么都干的外包小工,甚至不配拥有姓名,啥都干。还是刚才的问题,老板不会说交给法务,只会说“交给那个新来的外包来干”,没人关心这个外包干嘛的,反正给他就完了。
-
Fork:这个最复杂,也是 CC 最牛的一个,我们待会还会再细化去讲。简单来说就是老板复制了一个自己,继承了老板所有的上下文,然后单独干活,如果你了解 git 就会发现其实就是 git 的 branch 分支,Codex 的工作树

复杂的上下文控制
子 Agent 不是完全隔离的:文件读取状态是共享的。UI 和通知的隔离程度取决于执行路径。CC 在这里做的很复杂,实现更是复杂度爆炸。
简单来说,就是这些 agent 之间不是真正的完全隔离,只通讯结果和输入的内容,而是有这一套很复杂的隔离机制,有的东西隔离,有的不隔离,而且不同的情况隔离的策略也不一样。
这么做的原因是解决这个问题:假如你是一个老板,这时候你要让你的下属做一个任务,需要 ABC 三个员工,然后你把文件发给他们并且交给他们任务,如果是之前教学版本那种完全隔离的情况,就会出现,同一份文档你和你的三个员工每个人都要读一遍,这太浪费 Token 了,效率也很低,于是 CC 就做了一件事情就是你们四个人在这方面的上下文内容共享,这样就只需要读一遍了,只要需要了就直接拿来用。
递归层级和保护
CC 引入了一个叫做abortController的东西,这个东西可以让 Agent 完全听从主 Agent 的指挥。主 Agent 说停,所以的 Subagent 立马就全部停止,乖乖听话。
此外,他们还做了一个叫做queryTracking的东西,这个东西是方便后续 AI 或者人来追踪问题的,就比如主 agent 的东西是 0 层,员工 A 是 1 层,以此类推,这样就好归因到谁的问题,谁的锅:)
还有一个东西就是 Fork 防护,这玩意儿就是刚才说的,Subagent 不允许自己再创建 subagent,也就是企业里不允许大老板交给小老板,小老板交给小组长,小组长交给小职员,层层嵌套,这在企业里叫做层层剥削,架构冗余,这在 Agent 里面也是一样,而且还会导致 CPU 爆炸。
权限向上冒泡
CC 有一个PermissionBubbling机制,子 Agent 没有资格直接询问用户,必须要线上冒泡到主 Agent 再询问用户。
假如 Subagent 在执行的时候想要删除文件,他没有权限直接问用户,让用户选择允许、拒绝,他必须要告诉主 Agent,然后主 Agent 询问用户。
异步任务
CC 的主 Agent 和 Subagent 之间,可以同步也可以异步。
同步模式
同步模式下,主 Agent 就是真的一直在等着他交付的所有 Subagent 干完给他结果,就是
老板
↓
派活
↓
等着
↓
等着
↓
等着
↓
拿结果
这种方式的好处是流程清晰,但是缺点是主 Agent 在相当长的时间内等于什么都没有做,就只是一直在等着,效率不高。
异步模式
异步模式就是我们小学数学学到的,烧水的时候,我们可以去做其他的。主 Agent 交给 Subagent 任务后,自己再去干其他的事情,等 Subagent 们完成任务了再看结果。
老板
↓
派活
↓
继续干别的