子 Agent 协作
类比:主 Agent 像项目经理,子 Agent 像各专业工程师。
想象你是一个装修队的总包。你自己不可能同时刷墙、装水电、铺地板——你把水电交给水电师傅、刷墙交给油漆师傅、铺地板交给木工师傅,各自独立干活,最后你来验收。主 Agent 就是总包(你对话里的 Claude),子 Agent 就是各工种师傅。
技术定义:子 Agent(subagent) 是 Claude Code 派出去的独立工作者:普通子 Agent 在独立上下文中完成一项委派任务,再把结果返回主对话。它不读取主对话历史,但会按官方加载规则收到委派消息、适用的 CLAUDE.md/项目记忆、启动时 Git 状态和预加载 Skill;内置 Explore/Plan 等 Agent 有例外。fork 模式则会继承父上下文,不能把“完全从零”当作所有子 Agent 的固定行为。
术语速查:
| 词 | 含义 |
|---|---|
| 主 Agent | 你当前对话里的 Claude,负责任务拆分、委派与汇总 |
| 委派 | 把一项写清楚的任务交给子 Agent 执行 |
| fork | 一种继承父对话上下文的子 Agent 模式(与“空白上下文”的普通子 Agent 不同) |
/agents |
查看/管理自定义 Agent 定义的命令 |
@agent-name |
在对话里点名调用某个自定义 Agent |
核心洞察:“子 Agent 解决的不是’做不完’的问题,而是’做不细’的问题。你在主对话里让 Claude 同时审查 5 个文件的安全、性能和可读性——它可能每个维度都粗粗过一遍。但如果你派 3 个子 Agent 各自专注一个维度,每个都能深入。”
子 Agent 和 Hook、Skill、Verify 的关系:
- Hook 解决“每次 X 发生时自动做 Y”的确定性检查
- Skill 解决“用户说要 X 时执行多步流程”的灵活工作流
- Verify 解决“AI 写的代码真的能跑吗”的验收检查
- 子 Agent 解决“多个独立任务同时做、各自深入”的并行分工
四者不重叠——它们解决的是不同维度的问题。
什么时候用子 Agent
Section titled “什么时候用子 Agent”决策树——三问判断:
1. 任务能拆成互不依赖的独立块吗?
能——继续下一问。不能——不要用子 Agent。B 的输入必须等 A 的输出,这种任务在主对话里逐个做更快,子 Agent 反而增加协调成本。
2. 每个独立块的复杂度够大吗?
够大——单个任务需要读多个文件、做非平凡决策、输出有意义的结果。不够大——不要用子 Agent。单文件小修改的启动成本(创建独立上下文、读取文件)大于实际工作时间。
3. 你需要每个块都深入而不是泛泛过一遍吗?
需要——用子 Agent。不需要——在主对话里批量做更快。
用得着的典型场景:
- 多文件并行修改:3 个独立组件可以同时改,互不依赖
- 多维度独立审查:安全审查 + 性能审查 + 代码风格审查,三个角度各派一个
- 大范围搜索:4-5 个目录各自搜,汇总结果(比主 Agent 逐个搜快得多)
- 独立子任务:写文档 + 写测试 + 重构,三个互不依赖的任务可以同时做
用不着的典型场景:
- 单文件小修改:启动成本大于实际工作,直接在对话里改更快
- 强依赖任务:后续任务的输入依赖前序任务的输出,不能并行
- 简单问答:“这个函数是干什么的”不需要派 Agent
决策口诀:“能并行且互不依赖 → 子 Agent。有先后依赖 → 自己干。不确定?先自己干。”
怎么触发子 Agent
Section titled “怎么触发子 Agent”在对话中描述需要并行或独立完成的任务,Claude Code 会自动判断是否需要子 Agent。你也可以明确提示:
用子 Agent 并行搜索 src/ 和 tests/ 目录下所有用到 getUserById 的地方Claude Code 会在后台启动独立的子 Agent 进程来执行。你不需要手动管理进程——主 Agent 会自动收集结果并汇总。
怎么给子 Agent 写任务
Section titled “怎么给子 Agent 写任务”任务描述的黄金法则:假设子 Agent 对你的项目一无所知。
它看不到主对话历史。虽然适用的 CLAUDE.md 和项目记忆通常会加载,当前任务的目标、输入、输出和约束仍要在委派消息里写清楚,不能假设它知道刚才讨论的细节。
一个可检查的只读 Agent
Section titled “一个可检查的只读 Agent”项目级自定义 Agent 放在 .claude/agents/<name>.md。下面的最小定义只允许读取与搜索:
---name: read-only-reviewerdescription: Review a change without modifying filestools: Read, Grep, Globmodel: inherit---
Read the requested files and return findings with file paths and evidence. Do not modify files.用 /agents 检查它是否被发现;用 @read-only-reviewer 可保证本次任务调用该 Agent。自然语言点名通常会触发委派,但仍由 Claude 判断。本站 fixture 只做结构与工具 allowlist 检查;真实账户中的发现和调用属于人工验收。
必须包含 5 个要素:
1. 目标 — 一句话说清楚要做什么
Bad:“优化一下 UserService” Good:“重构 UserService 类,把验证逻辑抽到单独的 validateUser 函数”
2. 上下文 — 它需要知道的项目背景
文件路径、技术栈、命名约定、不能违反的规则。假设它从零开始读你的项目——你需要告诉它哪些关键信息。
3. 输入 — 明确列出需要读哪些文件
不要写“看相关文件”——给它精确路径。src/services/UserService.ts、src/types/user.ts、src/utils/validation.ts。
4. 输出 — 期望的文件路径和格式
“创建 src/utils/validateUser.ts,导出 validateUser 函数”——不是“把验证代码放到合适的地方”。子 Agent 不知道哪里是“合适的地方”。
5. 约束 — 明确不能做什么
不能改哪些文件、不能装新依赖、不能修改测试文件、不能改变现有 API 签名。约束越具体,子 Agent 越不容易做多余的事。
Good vs Bad 对比:
# Bad -- 太模糊帮我优化一下这个组件的性能
# Good -- 精确审查 src/components/Dashboard.astro 的性能。关注:不必要的 re-render、大的依赖包、未使用的 import。输出:一个 markdown 列表,每项注明问题、严重度、建议修复。不要改代码,只出报告。进阶技巧 — 用 plan 文件做任务描述:
Jason 的日常做法:把任务描述写成一个 markdown plan 文件,子 Agent 直接读这个文件。好处是:
- 任务描述可以复用(同一个 Task 如果失败,重新派给子 Agent 时任务描述不变)
- 可以迭代修改(在子 Agent 跑的时候,你可以修改下一个 Task 的 plan 文件)
- 可追溯(每个 Task 完成的依据是什么,plan 文件里写得清清楚楚)
# Task 1: 重构 UserService 验证逻辑
目标:把 UserService.ts 中的验证逻辑抽到独立的 validateUser.ts输入:src/services/UserService.ts、src/types/user.ts输出:src/utils/validateUser.ts(新文件)约束:不改变 UserService 的公开 API 签名验收标准:现有的 UserService 测试全部通过怎么验证子 Agent 的结果
Section titled “怎么验证子 Agent 的结果”子 Agent 和主 Agent 一样会犯错——同样遵循 验证方法论 中的“AI 生成的代码不是 100% 正确”原则。验证流程和验证主 Agent 的输出完全一样,三层体系同样适用:
第一层:看 diff
git diff --stat # 先看改了什么文件,数量对吗?git diff # 逐行看,每条 + 行和 - 行都对吗?子 Agent 最常见的多做事:改了你没让它碰的文件、顺手“优化”了无关代码、删了它以为没用但你需要的导入。
第二层:grep 检查
子 Agent 新增的函数名、变量名,在定义处和调用处拼写一致吗?被改函数的调用方都更新了吗?grep 一遍,确认每个名称至少出现两次且拼写完全一致。
第三层:实际运行验证
代码能跑起来。npm run dev 或 npm test,确认没有运行时错误。子 Agent 的输出和主 Agent 的输出适用完全相同的验收标准——能跑才是真能用。
子 Agent 特有的验证技巧 — 交叉审查:
让一个子 Agent 审查另一个子 Agent 的工作。这对安全敏感任务特别重要:
审查 Task 3 子 Agent 对 src/auth.ts 的修改,看有没有安全漏洞。输出:安全问题列表(如果有)、逻辑问题列表、建议改进。核心原则:不要因为“是 AI 写的”就降低标准。 子 Agent 不会说“我不确定”——它会自信地提交错误代码。子 Agent 的输出和人类同事的 PR 适用完全相同的验收标准。
Subagent-driven Development 完整流程
Section titled “Subagent-driven Development 完整流程”这是 Jason 日常使用的标准流程(简版)。完整流程见 工作流编排思路:
- 写好计划文档:每个 Task 完全独立、有完整上下文、有明确的输入输出
- 代码修改类任务一次派一个 — 详见下方关键原则
- 子 Agent 实现 → 自我审查 → 提交
- 你审查:spec 合规(做对了吗?) → 代码质量(做得好吗?)
- 通过 → 下一个 Task。不通过 → 子 Agent 修复 → 回到第 4 步
- 全部完成 → 最终审查(一个子 Agent 整体看一遍所有改动)
关键原则:代码修改类任务一次派一个——不要同时让多个子 Agent 改同一个模块。 并行派多个修改任务 = 合并冲突地狱。但搜索、审查、分析类任务可以并行派发(比如同时搜 4 个目录、同时从 3 个维度审查代码),这些只读任务不会产生冲突。
子 Agent 之间的依赖关系处理起来很痛苦——这就是为什么计划阶段就应该尽量让 Task 独立。如果两个 Task 之间有强依赖,把它们合并成一个 Task,或者让一个子 Agent 顺序执行它们(而不是分派给两个并行子 Agent)。
常见坑与失败恢复
Section titled “常见坑与失败恢复”1. 任务描述太模糊
“帮我重构一下” → 子 Agent 乱改一通。投入时间写清楚目标、输入、输出、约束——这 2 分钟的投资能省下 20 分钟的修复时间。失败恢复:停掉当前委派,用五要素重写任务(或 plan 文件),再派一次。
2. 并行派太多 Agent
并发数量没有适用于所有项目的固定上限。写操作任务先检查文件是否重叠;后台 Agent 遇到需要交互授权的工具会自动拒绝,因此权限敏感任务优先在前台运行。失败恢复:先只保留一个写操作 Agent;只读搜索/审查可以继续并行。
3. 不验证直接合并
子 Agent 不会说“我不确定”——它会自信地提交错误代码。永远走一遍三层验证流程再合并。失败恢复:git diff --stat → 逐文件 diff → 跑测试/启动程序;不通过就让同一 Agent 按验收标准修复,不要直接 merge。
4. 把不需要子 Agent 的任务也派出去
单文件小修改、简单搜索、问答类任务——启动成本大于实际工作。自己干更快。失败恢复:下次先过三问决策树;不确定就先在主对话做。
5. 任务之间有隐藏依赖
Task B 改了 Task A 也会碰的文件 → 合并时冲突。计划阶段就识别依赖:grep 每个 Task 涉及的文件列表,看有没有重叠。有重叠 = 不能并行。失败恢复:合并成一个 Task,或改成顺序执行。
6. 给子 Agent 的约束太少
没说不让装新依赖 → 子 Agent 可能 npm install 一堆东西。没说测试不能改 → 子 Agent 可能为了让结果“看起来正确”而修改测试。失败恢复:在委派消息里补上禁止项;用 git diff 检查是否出现了未授权的依赖或测试改动,必要时回退。
7. 自定义 Agent 发现不了
失败恢复:确认文件在 .claude/agents/<name>.md;frontmatter 含 name;运行 /agents;必要时重启会话后再用 @name 点名。
最小可验证动作
Section titled “最小可验证动作”一次坐下来约 15 分钟:
- 创建
.claude/agents/read-only-reviewer.md(内容见上文只读示例) - 运行
/agents,确认能发现read-only-reviewer - 在对话中:
@read-only-reviewer 审查当前仓库里任意一个测试或源文件,列出发现(含路径与证据)。不要修改任何文件。- 检查:
git statusgit diff --stat成功标准: Agent 返回带路径/证据的发现;工作区无因该 Agent 产生的文件修改。若发现不了 Agent,按坑 7 排查。
Checkpoint
Section titled “Checkpoint”- □ 我能用三问决策树判断:这个任务该不该用子 Agent
- □ 我能写出包含目标、上下文、输入、输出、约束的委派说明
- □ 我完成了上面的「最小可验证动作」,只读 Agent 可发现且未改文件
- □ 我知道写操作应一次一个、只读审查/搜索可以并行
- □ 我能说明普通子 Agent、fork 与后台 Agent 在上下文/权限上的差异
- □ 我会对子 Agent 输出走三层验证(搜索 / diff / 实际运行),不降标准