AI 编程教程中文版
从原理到实战

07 · 派助手去干活

SubAgents 的核心不是并行,而是把会污染主对话的搜索、日志和改动放进独立上下文,只把结论带回来。

翔宇第一次用 SubAgents(子代理)的时候,以为重点是“一个 Claude 变三个,速度翻三倍”。真正用久以后才发现,速度只是副作用。真正重要的是:主对话终于不用再吞下那些临时搜索、测试日志和无关文件了。——翔宇

这一篇用 15 分钟换什么:第 6 篇讲了 Skills(技能)怎么复用流程。这一篇讲 SubAgents:什么时候把任务交给另一个独立上下文做,怎么指定它,怎么限制它,什么时候不要用。读完后,你会少犯一个常见错误:把“多派几个 AI”当成万能加速器。

1. 从一张被弄乱的桌子开始

想象一个很普通的开发场景。

你正在和 Claude Code 讨论认证模块。你们已经聊了十几轮,桌面上摆着这些信息:

  • JWT 登录流程
  • middleware/auth.ts 的判断逻辑
  • session 存储位置
  • 刚刚定下来的重构边界
  • 你已经否掉的两个方案

这张桌子暂时很清楚。

这时你突然想起一件事:

👤 你:先帮我查一下项目里有没有用到 Redis。

Claude 自己去查。它搜索 redisiorediscache,打开十几个文件,读配置、读服务层、读测试。最后回答你:

🤖 Claude:项目里有 3 处 Redis 用法:缓存层、session 存储、队列消费。

答案是有用的。但代价是什么?

Redis 搜索过程中读过的文件、grep 结果、配置片段、分析过程,都被塞进了同一个主对话。你本来正在讨论认证重构,现在桌子上多了一堆 Redis 资料。下一轮继续聊认证时,Claude 要在两堆资料里判断“哪些还相关”。

这就是主对话被污染。

第一性原理:SubAgent 解决的不是“一个 AI 不够聪明”,而是“某些子任务的过程不值得放进主上下文”。

这句话比“并行”更重要。因为即使只派一个子代理,只要它把脏活留在自己的上下文里,你的主对话就会更干净。

2. 子代理到底多了什么

SubAgent 不是一个更聪明的 Claude,也不是插件。

它是 Claude Code 临时派出去的另一个 Agent(智能代理)。这个代理有自己的上下文窗口、自己的系统提示、自己的工具权限。它完成任务后,把最终结果带回主对话。

用刚才的 Redis 例子看,流程变成这样:

flowchart LR
    Main["主对话<br/>认证重构资料"]
    Need["临时问题<br/>项目有没有 Redis?"]
    Agent["SubAgent<br/>独立上下文"]
    Mess["搜索结果<br/>文件片段<br/>日志输出"]
    Result["返回摘要<br/>3 处 Redis 用法"]
    Continue["主对话继续<br/>认证讨论不被打散"]

    Main --> Need
    Need --> Agent
    Agent --> Mess
    Mess --> Agent
    Agent --> Result
    Result --> Main
    Main --> Continue

    style Main fill:#dbeafe,stroke:#3b82f6,stroke-width:2px
    style Agent fill:#dcfce7,stroke:#22c55e,stroke-width:2px
    style Mess fill:#fef3c7,stroke:#f59e0b
    style Result fill:#f3e8ff,stroke:#a855f7,stroke-width:2px

注意这里有两个动作:

  1. 展开:子代理在自己的上下文里读文件、跑命令、分析。
  2. 压缩:子代理只把最后的摘要交回主对话。

官方文档对这个设计说得很直白:Subagents 适合处理会让主对话塞满搜索结果、日志或文件内容的旁支任务;它们在自己的上下文里工作,只返回摘要。完整说明见 Create custom subagents

SubAgent 上下文怎么"独立":派 SubAgent 时 Claude Code 启动一个新的 Claude 会话——这个新会话有自己的 system prompt(包括它自己的 frontmatter 指令)+ 自己的 conversation history(默认从空开始,仅注入你给它的任务说明)。它不会自动看到主对话之前讨论过什么——这就是"独立上下文"的工程实现。代价:你要在派任务时显式说清背景,因为它不知道你之前跟主 Claude 聊过什么。例外:实验性的 forked subagent(CLAUDE_CODE_FORK_SUBAGENT=1)会继承主对话历史快照——见本篇 §8 details。

一句话理解:SubAgent 像你派同事去资料室查东西。同事可以翻很多资料,但回来只给你结论,不把资料室搬到你的办公桌上。

3. 并行只是第二层收益

很多人第一次看到 SubAgents,会先想到并行:

一个 Claude 查认证模块
一个 Claude 查数据库模块
一个 Claude 查 API 模块
三个人同时查,肯定更快

这个理解不算错,但不够底层。

如果并行是唯一目标,在一个主对话里同时跑三段搜索也可以“看起来并行”。问题是三段搜索都会把结果倒进同一张桌子。速度变快了,桌子也更乱了。

SubAgents 的关键不是“同时做”,而是“分开做”。

判断维度在主对话里做派 SubAgent 做
中间文件和日志进入主上下文留在子上下文
主对话注意力容易被打散只看到摘要
是否能并行取决于工具和任务可以并行
适合任务快速、相关、需要互动自包含、输出很多、只要结论

回到 Redis 例子。如果你只问一句“项目有没有 Redis”,真正需要的是最后的 3 条结论,不需要看它翻过的每个文件。那就该派出去。

反过来,如果你正在和 Claude 一起设计认证重构方案,每一步都需要你不断纠正、追问、改边界,这种任务放在主对话更合适。因为过程本身就是上下文。

新手坑:不要为了“看起来高级”把所有事都派给子代理。需要频繁来回讨论、需要共享大量上下文、需要你逐步校准方向的任务,留在主对话。

4. 什么时候该派助手

判断标准可以很简单:这个子任务的中间过程,你后面还要不要用?

应该派出去

适合派 SubAgent 的任务通常有三个特征:

  • 输出过程很长:测试日志、grep 结果、依赖树、构建错误。
  • 任务边界清楚:查 Redis 用法、审查某个文件、跑测试并归纳失败项。
  • 主对话只需要结论:有几处、失败在哪、建议怎么改。

Redis 查询就是典型例子:

任务:查项目有没有 Redis
过程:搜关键字、读配置、读调用链
主对话需要:是否使用、在哪些地方、风险是什么

过程很多,结论很短。适合派出去。

不该派出去

不适合派 SubAgent 的任务也很明显:

  • 任务很小:改一个变量名、解释一行报错。
  • 需要连续追问:你还没想清楚目标,边聊边改。
  • 过程必须留在主线:架构决策、需求澄清、和用户一起取舍。
  • 子任务之间要互相沟通:前端、后端、测试需要持续对齐。

最后一类就是下一篇 Agent Teams(代理团队)的主题。SubAgents 只向主对话汇报,它们之间不会像团队成员那样互相发消息、共享任务列表。

flowchart TB
    Start["有一个旁支任务"]
    Small{"一步就能完成?"}
    Interactive{"需要频繁来回确认?"}
    Noisy{"过程会产生很多文件/日志/搜索结果?"}
    Summary{"主对话只需要摘要?"}
    Team{"子任务之间需要互相沟通?"}
    Main["留在主对话"]
    Sub["派 SubAgent"]
    Teams["考虑 Agent Teams"]

    Start --> Small
    Small -->|是| Main
    Small -->|否| Interactive
    Interactive -->|是| Main
    Interactive -->|否| Team
    Team -->|是| Teams
    Team -->|否| Noisy
    Noisy -->|否| Main
    Noisy -->|是| Summary
    Summary -->|是| Sub
    Summary -->|否| Main

    style Sub fill:#dcfce7,stroke:#22c55e,stroke-width:2px
    style Main fill:#dbeafe,stroke:#3b82f6
    style Teams fill:#f3e8ff,stroke:#a855f7,stroke-width:2px
    style Small fill:#fef3c7,stroke:#f59e0b
    style Team fill:#fef3c7,stroke:#f59e0b

底层逻辑:SubAgent 是上下文隔离工具,不是任务拆分仪式。先问“过程会不会污染主线”,再决定派不派。

5. 内置三种工位

Claude Code 自带几类内置 SubAgents。官方文档列出的核心内置类型是 Explore、Plan 和 general-purpose。它们不是“智商等级”,而是不同工位。

类型模型 / 权限最适合什么Redis 例子里怎么用
ExploreHaiku;只读工具快速搜索、文件发现、代码库探索查哪些文件出现 Redis
Plan继承主会话模型;只读工具plan mode 里做代码库调研先理解认证模块再给改造计划
general-purpose继承主会话模型;全部工具复杂多步任务、需要读写和执行查 Redis 后顺手改配置或补测试

官方说明里,Explore 是 fast、read-only,适合 codebase exploration;Plan 用在 plan mode 里做研究;general-purpose 用于需要探索和行动的复杂多步任务。见 Built-in subagents

为什么是这三类不是别的:三类对应三种"派任务"模式——

  • Explore(Haiku 只读):成本最低、速度最快,适合纯查找("项目里有几处用了 Redis")。用 Sonnet/Opus 跑这种纯搜索是杀鸡用牛刀。
  • Plan(继承模型 + 只读):你要它"先调研再给方案"——读代码不动手,避免它在调研中途擅自改文件。
  • general-purpose(继承模型 + 全工具):你要它"调研完顺手把简单的修一下"——能写、能跑命令。

三类覆盖"快查 / 调研 / 调研+执行"三个常见场景。Anthropic 没单独做"只跑命令"或"只写文件"的 SubAgent——因为这些场景用主对话或 Hook 更合适,单开 SubAgent 反而把简单任务搞复杂。

这三个名字不用硬背。按中文直觉记就行:

  • Explore:侦察员,只看不动手。
  • Plan:参谋,先调研再给计划。
  • general-purpose:执行员,能读、能写、能跑命令。

不要误用:只是查资料,优先只读。能用 Explore 就不要让能写文件的 agent 进去乱跑。权限越大,越要有明确任务和验收标准。

6. 怎么点名派谁

SubAgent 可以自动触发,也可以你手动点名。Claude 会根据你的请求、当前上下文和子代理的 description 判断是否委派。比如你说:

查一下项目里 Redis 相关代码都在哪里,只返回文件和用途。

这类请求边界清楚、偏搜索、只要摘要,Claude 就可能自动派 Explore。

如果你自定义了一个 security-reviewerdescription 要写清触发场景:

description: Reviews authentication, authorization, token handling, and input validation for security issues. Use proactively after auth-related code changes.

当你说“审查一下认证相关改动有没有安全问题”,Claude 就更容易匹配上。

手动指定有三种层级:

层级写法适合什么时候
自然语言请让 code-reviewer 子代理审查这次认证相关的改动。想表达意图,但允许 Claude 组织任务
@ 提及@agent-code-reviewer 审查 auth 模块的改动必须指定某个本地 agent
会话级claude --agent code-reviewer整场会话都要变成 reviewer 模式

官方还支持在选择器里输入:

@"code-reviewer (agent)" 看一下这次认证相关的改动

如果要让项目默认用某个 agent,可以在 .claude/settings.json 写:

{
  "agent": "code-reviewer"
}

实用顺序:普通请求先让 Claude 自动判断;重要任务用自然语言点名;必须指定某个 agent 时用 @agent-name;整场会话都要同一种角色时再用 --agent

7. 自定义一个子代理

内置类型够用时,不需要急着自定义。

但如果你反复派同一种角色,比如“认证安全审查员”,每次都要说同一套检查规则,那就可以写成自定义 SubAgent。

项目级文件放在:

auth-reviewer.md

最小版本可以这样写:

---
name: auth-reviewer
description: Reviews authentication and authorization code for security issues. Use when code changes touch login, sessions, JWT, permissions, or user identity.
tools: Read, Grep, Glob
model: sonnet
---

You are an authentication security reviewer.

Review only the authentication and authorization surface:

1. Token creation, validation, expiration, and storage.
2. Session lifecycle and logout behavior.
3. Permission checks and role boundaries.
4. Input validation for login, registration, and password reset.

Return:

- High-risk findings first.
- File paths and exact symbols.
- Why the issue matters.
- A minimal fix suggestion.
- "No high-risk auth issues found" if nothing serious is found.

这个文件分两层:

  • frontmatter(文件头元数据):告诉 Claude 什么时候用、能用什么工具、用什么模型。
  • 正文:告诉这个子代理按什么角色、流程和输出格式工作。

它和 Skill 很像,但目标不同。

对比SkillSubAgent
解决什么复用一段流程隔离一个工作上下文
运行在哪里通常进入主对话独立上下文
返回什么主对话继续按流程执行子代理最终摘要
适合例子PDF 处理流程、发布清单代码审查、搜索、跑测试、日志分析

第 6 篇讲过,Skill 是“遇到某类任务时怎么做”的说明书。SubAgent 更像“找一个按这套说明做事的人”。

写好 description:自动委派主要靠它。不要写 “Helpful reviewer”。要写清楚任务类型、触发场景和边界,比如 auth、JWT、session、permissions。

8. 权限、资源和记忆

SubAgent 真正变好用,靠的不是“写一个很响亮的角色名”,而是把边界写清楚:它放在哪里、能用什么工具、要不要带额外资源。

放在哪里

新手最常用两个位置:项目级 .claude/agents/,适合随仓库共享;个人级 ~/.claude/agents/,适合自己跨项目复用。更高阶的来源还包括管理设置、--agents 当前会话和 plugin。多个位置出现同名 agent 时,高优先级会覆盖低优先级。

边界提醒:项目级 SubAgent 会进入版本库。别把公司内部密钥、私人路径、真实客户信息写进去。规则可以公开,凭据不可以。

限制它能做什么

可以用 tools 做 allowlist(允许列表):

tools: Read, Grep, Glob

这表示它只能读和搜,不能写文件。

也可以用 disallowedTools 做 denylist(拒绝列表):

disallowedTools: Write, Edit

这表示它继承主会话大部分工具,但明确不能写和改。

如果你给“代码审查员”全部写权限,它可能在审查时顺手修改文件。那不是审查员,是执行员。不是不能这样做,而是你要有意识。

常见角色的权限边界可以这样记:

  • 代码搜索员:Read, Grep, Glob。只需要找信息。
  • 安全审查员:Read, Grep, Glob, Bash。可能需要跑只读检查。
  • 测试执行员:Read, Grep, Glob, Bash。需要跑测试,但不一定改代码。
  • 修复执行员:读写 + Bash。需要真正落地改动。

Claude Code 还支持 permissionMode、subagent 级 hooks、MCP(Model Context Protocol,模型上下文协议)服务器作用域、预加载 Skills、持久 memory(记忆)等配置。官方完整字段见 Supported frontmatter fields

最容易出事故的写法:给一个描述很宽的 agent 全部工具权限,然后让它“use proactively”。它会很积极,但你未必想要它那么积极。

给它带资源

SubAgent 不只是“另一段 prompt”。它可以带自己的资源。

你可以在 subagent frontmatter 里写:

skills:
  - api-conventions
  - error-handling-patterns

官方说明里强调:这些 Skill 的完整内容会在子代理启动时注入上下文,不只是放在旁边等它调用。子代理不会自动继承父会话里的 Skills,想要就要显式列出来。

如果某个 agent 才需要数据库只读工具或浏览器测试工具,可以把 MCP server 配在这个 subagent 里,让工具只在它启动时可用。这样主对话不用背工具描述,权限也更窄。

SubAgent 还能配置 memory:

memory: project

官方给出三个作用域:user 跨所有项目,project 项目内共享,local 项目本地私有。比如 auth-reviewer 可以逐渐记住这个项目的认证路径、常见安全问题、历史决策。以后再审查时,它不必每次从零开始。

🔍 深一层:forked subagents 是什么

普通命名 SubAgent 默认从自己的定义和你传给它的任务开始,不继承主对话完整历史。这样隔离最好,但有时也麻烦:你得把背景讲清楚。

Claude Code 现在还有实验性的 forked subagents。启用 CLAUDE_CODE_FORK_SUBAGENT=1 后,fork 可以继承当前主会话到目前为止的完整上下文,但它自己的工具调用仍留在 fork 里,最后只把结果带回来。

它适合“需要完整背景,但过程不要污染主线”的任务。代价是隔离没那么纯,因为它一开始就继承了主会话历史。官方标注它是 experimental,并要求 Claude Code v2.1.117 或更新版本。

9. 编排模式和团队边界

真正用起来后,SubAgents 常见有三种编排模式。

模式一:隔离噪音

这是最常用的。

让一个子代理跑完测试套件,只回报失败用例的文件路径和错误信息。

测试可能输出几千行日志。主对话不需要每一行,只需要失败项、错误信息、建议下一步。

模式二:并行研究

当几个方向互不依赖,可以同时派出去。

分别派子代理并行调研 authentication、database、API 三个模块,最后汇总成一份架构摘要。

这比串行快,也避免三个模块的搜索过程混在主上下文里。

模式三:串联交接

一个子代理先做审查,另一个再修复。

先用 code-reviewer 子代理找出认证相关的高风险改动,再让一个 general-purpose 子代理只修复已确认的问题。

这里要注意:串联会产生信息损耗。第一个子代理给第二个的是摘要,不是完整过程。所以摘要必须写清文件、符号、风险和建议。

实操建议:派出去前,把输出格式说死。比如"只返回文件路径、行号、问题、建议修复",不要让它写一篇散文式总结。

新手最常见的两类误用

  1. 把 SubAgent 当并行加速器:所有任务都派——结果 5 个子代理同时跑同一个仓库,互相不知道对方在做什么,可能重复读同一批文件、给出冲突的建议、合起来反而更乱。SubAgent 的核心是上下文隔离不是并行加速——能在主对话讨论的就不该派出去。
  2. 派出去后忘了"输出契约":让 general-purpose 子代理"看看 auth 模块"——它返回一篇 800 字散文式分析,主对话还得花一轮把散文压成可执行的 todo。修复方式:派任务时显式说"返回格式:① 文件路径 ② 风险描述 ③ 建议改法,每条 ≤30 字"。把"输出格式"当 §4 件套的"验收"来对待。

和 Agent Teams 的边界

SubAgents 不是 Agent Teams。

SubAgents 是主从结构:

主对话 -> 子代理 A -> 回摘要
主对话 -> 子代理 B -> 回摘要
主对话负责汇总

子代理之间不互相聊天,也不共享任务列表。它们各做各的,然后向主对话汇报。

Agent Teams 是协作结构。官方文档说,Agent Teams 有 shared tasks、inter-agent messaging 和 centralized management。也就是说:团队成员能互相发消息,有共享任务列表,有 lead 负责协调。见 Run agent teams

边界可以这样判断:

  • 查三个互不依赖的模块:用 SubAgents 合适,Agent Teams 太重。
  • 跑测试并只看失败摘要:用 SubAgents 合适,Agent Teams 太重。
  • 前端、后端、测试要互相对齐:SubAgents 不够,Agent Teams 更合适。
  • 多个假设要互相反驳:SubAgents 勉强,Agent Teams 更合适。
  • 成本敏感:SubAgents 通常更低,Agent Teams 通常更高。

回到 Redis 例子:只是查 Redis 用法,不需要团队。SubAgent 就够。

但如果你要让一个 agent 改后端 Redis session,另一个 agent 改前端登录态,第三个 agent 写集成测试,而且它们需要互相确认字段、状态和进度,那就开始接近 Agent Teams。

记住边界:只要结论,用 SubAgent。需要成员互相通信和共享任务状态,才考虑 Agent Teams。

10. 本章自检

试着用自己的话回答这 3 个问题:

  1. 有人说"SubAgents 的核心价值是并行加速"。这个说法漏掉了哪个更底层的价值?对应 §1-§3。
  2. 为什么 Redis 查询这种任务适合派 SubAgent?请用"过程"和"结论"的区别解释。对应 §4。
  3. 动手题 ⭐:列出你最近一次 Claude Code 会话里"中途让 Claude 查一下 X" 的 3 个时刻(比如查依赖、查接口、查测试覆盖)。每个判断:当时该派 Explore 还是留在主对话?派出去能省多少主对话上下文?这一题做完你会发现日常有 1/3 的"中途查一下"应该派 SubAgent,但你之前都没派。对应 §5。

过关标准:能用一句话说清:SubAgent 是把会污染主对话的子任务放进独立上下文,只把可用摘要带回来。

📖 本篇术语速查表
  • SubAgent:子代理。在独立上下文里完成子任务的 Claude Code agent。
  • Agent:智能代理。能围绕目标使用工具、推进任务的 AI 执行单元。
  • context window:上下文窗口。当前会话能同时看到的信息范围。
  • frontmatter:文件头元数据。Markdown 顶部 --- 包住的配置字段。
  • description:触发描述。Claude 判断是否委派给某个 agent 的关键字段。
  • tools:工具允许列表。限定子代理能使用哪些工具。
  • permissionMode:权限模式。控制子代理如何处理工具审批。
  • MCP:模型上下文协议。让 Agent 接外部工具和服务的协议。
  • memory:记忆。子代理跨会话保留项目经验或个人经验的目录。
  • Agent Teams:代理团队。多个 Claude Code 会话协作、通信和共享任务列表的机制。

官方资料

接下来去哪

如果只记一句:SubAgent 不是为了显得多人协作,而是为了让主对话少吞不必要的过程。

本页目录