Claude Code Subagents 设计指南:把 AI 拆成可协作角色

0阅读10分钟

上个月我在一个中等复杂度的项目里尝试用 Claude Code 完成一次完整的 feature 开发——包含 API 改造、前端适配、测试补充和文档更新。一个 Agent 从头做到尾,前 40 分钟一切顺利,到第 50 分钟它开始在 Review 自己写的代码时「忘记」之前测试阶段发现的边界条件。上下文窗口被消耗殆尽,判断力随之衰减。

这不是 Agent 不够聪明,而是上下文工程的问题。Anthropic 在 2025 年 9 月发布的工程博客「Effective Context Engineering for AI Agents」中明确指出:当 Token 数量增加时,模型的回忆准确性会下降,他们称之为 context rot。Transformer 架构中的注意力机制需要处理 n² 对关系,上下文越长,每个 Token 分到的注意力越少。

Subagents 提供了一种结构化的解法:把不同职责的工作分发给独立的 Agent 实例,每个实例带着干净的上下文窗口处理聚焦任务,只向主流程返回浓缩结果。

核心原理:什么时候该拆,什么时候不该拆

Anthropic 在 2024 年 12 月发布的「Building Effective Agents」中给出了一个基础判断框架:从最简单的方案开始,只在简单方案不够用时才引入多步架构。这个原则同样适用于 Subagent 拆分。

我把实际使用中摸出来的判断标准整理成一张表:

维度适合单 Agent适合拆分 Subagent
任务耦合度各步骤紧密依赖,后一步需要前一步的完整上下文子任务可以独立描述,结果可以摘要传递
上下文噪声低——所有信息都和当前判断相关高——某类任务需要大量探索但只有少量结论值得保留
任务可重复性每次执行的步骤差异很大同类任务反复出现,可以形成稳定模式
输出格式直接产出最终结果需要结构化中间产物供下游消费
并行可能性步骤间有严格顺序多个子任务可以同时进行

Anthropic 把常见的 Agent 编排模式分成五类:Prompt Chaining(链式调用)、Routing(路由分发)、Parallelization(并行化)、Orchestrator-Workers(编排者-工作者)和 Evaluator-Optimizer(评估-优化循环)。Subagent 设计主要用到后三种——把一个需要动态分配的大任务交给 orchestrator,让它决定哪些子任务可以并行,再由 worker 各自执行。

四个设计边界

职责边界:一个 Subagent 对应一种可重复任务

职责模糊是 Subagent 设计中最常见的失败模式。我曾经过一个名为 code-helper 的 Subagent,让它既做 Review 又做测试分析还顺手改几行代码。结果是它在三种角色之间来回切换,哪个都做不好。

<!-- ❌ 职责过宽:一个 Agent 干三件事 -->
---
name: code-helper
description: 代码相关任务都找它
tools: Read, Write, Bash, Grep
---
你负责代码审查、测试分析和文档更新。
根据用户的具体需求灵活处理。
<!-- ✅ 职责聚焦:只做测试失败分析 -->
---
name: test-failure-analyst
description: 测试失败、类型检查失败或构建失败时使用
tools: Read, Grep, Bash
---
你负责分析失败原因,不直接改文件。
 
流程:
1. 读取失败命令和完整输出。
2. 判断失败属于环境、测试夹具、类型契约还是实现逻辑。
3. 定位最可能相关的文件。
4. 输出最小修复建议和需要重新运行的验证命令。
 
输出:
- 失败分类
- 证据片段
- 相关文件
- 建议修复路径
- 不建议修改的区域

两者的核心差异在于:聚焦的配置把角色边界写得足够窄,它不会和主 Agent 抢实现职责,但能显著提高特定任务的质量。Builder.io 的技术文章把这类任务总结为「noisy, bounded, and easy to summarize」——探索过程嘈杂但结果可以浓缩的任务最适合委派。

上下文边界:只给任务需要的信息

子 Agent 不继承主 Agent 的完整上下文,这在 Claude Code 中是默认行为。这个特性不是限制,而是设计优势。审查 Agent 需要规范和 diff,测试 Agent 需要失败日志和相关文件,文档 Agent 需要读者和结构要求。

# ❌ 上下文过载:把整个项目塞给子 Agent
context:
  - 整个 src/ 目录
  - 所有测试文件
  - 最近的 git log
  - package.json
  - tsconfig.json
  - 所有 CLAUDE.md 文件
# ✅ 上下文精准:只给审查需要的信息
context:
  - 本次 diff 涉及的文件
  - 项目的 code-style 规范文件
  - 相关的类型定义文件
  - 被修改函数的调用方(grep 结果)

精准上下文带来的好处不只是省 Token。当子 Agent 看到的都是和当前任务直接相关的信息时,它做出无关判断的概率会显著降低。

触发边界:人工点名、流程节点还是关键词路由

触发方式适用阶段优势风险
人工点名早期探索阶段精确控制,不会误触发需要人记住什么时候该调用
流程节点流程稳定后自动触发,不会遗漏需要在流程代码中硬编码触发点
关键词路由角色输出稳定后最自然的使用方式description 写得不够精确时容易误触发

我的建议是从人工点名开始。等你对某个 Subagent 的输出质量满意了,再考虑自动化。关键词路由最方便,也最容易出问题——如果 description 字段写得过于宽泛,Claude Code 的路由机制可能在错误的时机调用错误的角色。

输出边界:让结果可消费

子 Agent 的输出会被主 Agent 消费。如果输出格式不稳定,主 Agent 在整合结果时就会浪费额外的上下文来「理解」子 Agent 到底说了什么。

<!-- ❌ 输出不可预测:每次格式不同 -->
---
name: reviewer
description: 代码审查时使用
---
请审查这段代码,给出你的看法。
<!-- ✅ 输出格式明确:主 Agent 可以直接消费 -->
---
name: reviewer
description: 代码审查、PR Review 或评估代码质量时使用
tools: Read, Grep
---
按以下格式输出审查结果:
 
## 风险项
- [严重程度: 高/中/低] [文件:行号] [问题描述]
 
## 建议项
- [文件:行号] [改进建议]
 
## 确认无误
- [已检查的维度列表]
 
不要输出代码修改建议,只输出问题描述和定位。

一个完整的任务编排流程

用一张图说明 Subagent 在一次 feature 开发中的编排逻辑:

流程图画布 · 115%
Mermaid 流程图加载中...

这个流程中,research-agent、impl-agent 和 test-analyst 三个角色可以并行工作,因为它们之间没有数据依赖。主 Agent 等三个子任务都完成后再做整合,然后决定是否调用 reviewer-agent。reviewer-agent 是只读的,不会修改任何文件,它的输出是一份结构化的风险清单。

三个实战案例

案例一:代码审查中的上下文污染

场景:我让 Claude Code 实现一个用户权限模块,完成后让它自己 Review。它花了大约 8000 Token 来实现功能,然后用剩余的上下文来做 Review。Review 过程中它开始「发明」需求——声称某些边界条件需要处理,但实际上这些条件在需求中根本不存在。

问题出在上下文污染。实现阶段的细节(包括中间被否决的方案)占据了大量上下文,导致 Agent 在 Review 阶段无法准确区分「已经实现的」和「应该实现的」。

修复方案是引入独立的 reviewer-agent,它的上下文窗口只包含 diff、需求文档和代码规范,完全不知道实现过程中发生了什么。

<!-- reviewer-agent 配置 -->
---
name: reviewer
description: 代码审查、PR Review 或评估代码质量时使用
tools: Read, Grep
model: claude-sonnet-4-20250514
permissionMode: read
---
 
你负责审查代码变更,不修改任何文件。
 
审查依据(按优先级):
1. diff 中的实际变更
2. 需求文档中明确列出的功能点
3. 项目的代码规范
 
审查维度:
- 正确性:实现是否符合需求
- 安全性:是否有注入、越权、数据泄露风险
- 边界条件:是否有未处理的空值、溢出、并发场景
- 可维护性:命名是否清晰、职责是否单一
 
输出格式严格按照风险等级排列,不要输出「代码看起来不错」之类的泛泛评价。

案例二:并行 Agent 的文件冲突

场景:我在做一个数据库迁移功能时,同时启动了三个 Subagent——一个改 model 层,一个改 API 层,一个改测试。三个 Agent 都需要修改同一个 schema.ts 文件。结果主 Agent 在合并结果时发现三个版本互相矛盾。

这个错误的根因是我违反了 Agent Teams 的一个基本原则:每个 teammate 应该拥有不重叠的文件范围。

修复方案是调整任务拆分粒度,让每个 Subagent 只负责自己专属的文件集合:

# ❌ 错误拆分:多个 Agent 修改同一文件
agents:
  - name: model-agent
    files: [src/models/user.ts, src/models/schema.ts]
  - name: api-agent
    files: [src/api/user.ts, src/models/schema.ts]  # schema.ts 冲突!
  - name: test-agent
    files: [tests/user.test.ts, src/models/schema.ts]  # 又冲突!
# ✅ 正确拆分:文件范围不重叠
agents:
  - name: schema-agent
    files: [src/models/schema.ts, src/models/types.ts]
    # 单独负责 schema,先完成后再启动其他 Agent
  - name: api-agent
    files: [src/api/user.ts, src/api/middleware.ts]
    # 依赖 schema 的类型定义,但不直接修改 schema
  - name: test-agent
    files: [tests/user.test.ts, tests/api.test.ts]
    # 只改测试文件

对于必须修改同一文件的场景,更稳妥的做法是串行执行——先让 schema-agent 完成,再启动依赖新 schema 的其他 Agent。

案例三:子 Agent 的上下文启动开销

场景:我创建了一个 migration-planner Subagent 来制定数据库迁移计划。它的职责很清晰,但每次被调用时都要花大量 Token 来「理解」项目结构——读 CLAUDE.md、扫目录结构、看 package.json。这些上下文构建工作在 80% 的项目中都是重复的。

Claude Code 的子 Agent 每次都是「start fresh」,它不继承主 Agent 的上下文。Builder.io 的文章明确提到这一点,并建议让子 Agent 生成「durable artifacts」——比如 markdown 笔记——来降低跨 session 的重复成本。

我的做法是在 Subagent 配置中直接注入必要的项目事实,而不是让它自己去探索:

<!-- ❌ 让子 Agent 从零探索项目 -->
---
name: migration-planner
description: 数据库迁移规划
---
请分析当前项目并制定迁移计划。
<!-- ✅ 预置项目关键事实,减少探索开销 -->
---
name: migration-planner
description: 数据库迁移、schema 变更或数据格式升级时使用
tools: Read, Grep
---
 
项目背景(无需重新验证):
- ORM:Drizzle,schema 定义在 src/db/schema/
- 数据库:PostgreSQL 16
- 迁移工具:drizzle-kit
- 现有表数量:12,核心实体为 user、project、document
 
你的任务:
1. 读取变更涉及的 schema 文件
2. 分析向后兼容性(是否可在线迁移)
3. 输出分阶段迁移计划
 
输出格式:
- 变更摘要
- 兼容性风险
- 分阶段执行步骤(每步包含 SQL 和回滚方案)
- 需要人工确认的决策点

第二种配置把探索时间从平均 15 次工具调用降到了 3-4 次。子 Agent 的上下文窗口被有效利用在实际分析上,而不是项目结构探索。

Subagent 与 Agent Teams 的选择

Claude Code 目前提供两种多 Agent 协作方式。Subagent 是生产就绪的方案,适用于大部分场景。Agent Teams 是实验性功能,需要手动启用,引入了 mailbox 通信和共享任务列表等更复杂的协调机制。

特性SubagentAgent Teams
通信模型仅父子通信,子 Agent 之间隔离点对点 mailbox,任意 teammate 可通信
并行能力支持 background: true原生并行
上下文共享不共享,各自独立通过 mailbox 和共享任务列表
文件冲突处理通过 isolation: worktree 隔离需要手动划分不重叠的文件范围
适用场景独立的、可摘要的子任务需要跨 Agent 实时协调的复杂任务
Token 开销较低——每个子 Agent 独立消耗较高——mailbox 消息和协调消耗额外 Token
成熟度生产就绪实验性,需启用环境变量

一个简单的判断标准:如果你的子任务之间不需要在运行过程中交换信息,用 Subagent。如果前端 Agent 需要告诉后端 Agent「我把 API 响应格式改了」,用 Agent Teams。

Subagent 配置检查清单

在实际部署 Subagent 之前,我会逐项检查以下内容:

设计阶段

  • 这个 Subagent 的职责能用一句话说清楚吗?
  • 它的输入和输出格式是否已明确定义?
  • 它需要的工具列表是否已最小化(只给必要的工具)?
  • 它是否需要写文件?如果不需要,permissionMode 是否设为 read
  • 它和现有 Subagent 之间是否有职责重叠?

上下文设计

  • 它需要的项目背景信息是否已预置在 prompt 中?
  • 它是否需要访问和主 Agent 相同的文件?能否缩小范围?
  • 它是否会被频繁调用?如果是,是否考虑了上下文构建的重复开销?

集成验证

  • 在三种不同的类似任务上测试过输出稳定性吗?
  • 主 Agent 能直接消费它的输出,还是需要额外的「翻译」步骤?
  • 如果它和另一个 Subagent 需要修改同一文件,是否已规划串行执行或文件隔离?

运维

  • 它的 description 字段是否足够精确,不会在无关场景被误触发?
  • 是否已评估 Token 开销?多一个 Subagent 大约增加 2.5-4 倍的总 Token 消耗
  • 是否明确了什么时候该调用它?

常见角色模板

角色输入输出是否写文件推荐触发方式
Code Reviewerdiff、规范、类型定义风险列表、行号、严重程度实现完成后
Test Analyst失败日志、测试文件失败分类、证据片段、修复建议测试失败后
Docs Writer需求、实现摘要、目标读者文档草稿、术语表可选功能完成后
Security Checker数据流、权限模型、配置高风险点、缓解建议PR 创建时
Migration Planner旧结构、新目标、约束条件分阶段迁移计划、回滚方案架构变更前
API Contract Verifier接口定义、调用方、被调方不兼容变更列表、版本建议API 变更前

把写文件权限留给主 Agent 或极少数专用 Subagent。多个写入者同时工作,会增加冲突和 Review 成本。Anthropic 内部的 Claude Code Review 系统验证了这一点——他们在每个 PR 上部署五个专业化 Agent(正确性、安全性、性能、风格一致性、测试覆盖),全部是只读的,代码审查覆盖率从 16% 提升到了 54%。

评估一个 Subagent 是否值得保留

不要只看它回答得是否详细。我用来判断的实际指标是:

  1. 它是否减少了主 Agent 读无关文件的次数?
  2. 它是否比主 Agent 更早发现特定类别的风险?
  3. 它的输出是否能让主 Agent 在三次以内工具调用内完成整合?
  4. 它在三次以上类似任务中是否保持输出格式稳定?

如果以上四个问题中至少有三个答案是肯定的,这个 Subagent 值得保留。否则应该合并回主流程——一个做了太多事情但每件事都做得不够好的 Subagent,不如没有。

Anthropic 在「Building Effective Agents」中反复强调的一个原则在这里同样适用:从最简单的方案开始。如果一个主 Agent 加上好的 prompt 就能完成的工作,不需要拆成三个 Subagent。拆分是为了管理上下文噪声和职责混淆,不是为了展示架构复杂度。


参考资料

  1. Anthropic. Building Effective Agents. 2024-12-20.
  2. Anthropic. Effective Context Engineering for AI Agents. 2025-09-29.
  3. Builder.io. Claude Code Subagents: How to Create, Use, and Debug Them. 2026-04.
  4. Anthropic. Writing Effective Tools for AI Agents. 2025-09-11.
  5. Anthropic. Equipping Agents for the Real World with Agent Skills. 2025-10-16.
  6. Lush Binary. Claude Code Agent Teams: Multi-Agent Development Guide. 2026-04-07.
  7. Cai, Y. et al. Designing LLM-based Multi-Agent Systems for Software Engineering Tasks. arXiv:2511.08475. 2025-11.

评论 0

0 / 1000