Skip to content

ClaudeCode 工程化学习 · 子代理篇:Sub-Agents 核心概念与应用价值

跑完测试 → 500 行日志;搜一遍代码 → 200 行 grep;分析错误 → 一堆中间推理——这些执行过程对当下必要,对后续决策全是噪声。让 Claude 记得更少、但记得对。

一句话开场

如果让一个人同时干调研、写代码、跑测试、写文档,最后他脑子里塞满细节,已经记不清最初的目标是什么了。但如果给一个团队,每人负责一件事,做完只回一份结论——决策者拿到的是干净的报告,执行过程永远不会污染主对话。

子代理(Sub-Agents)就是给 Claude 配的那个"团队"。

为什么需要 Sub-Agents:上下文污染问题

什么是上下文污染

我们先看一个典型场景:让 Claude 跑一遍测试。

跑测试 → 500 行日志
搜代码 → 200 行 grep
分析错误 → 一堆中间推理过程

这些内容有两个共同特征:

维度表现
对执行过程必要——少了它们 Claude 无法判断对错
对后续决策噪声——主对话并不需要这些细节
持续时间默认不会过期,永久占用上下文窗口

根因在于:Claude Code 不会自动过期临时数据,它默认把这些临时的过程数据存储为了长期决策记忆。

污染的具体后果

执行噪声越堆越多,主对话真正关心的"结论"反而被淹没。这就是上下文污染。

核心概念:主代理与子代理

什么是主代理

主代理就是当前的主对话本身。它继承了 CLAUDE.md 的全部记忆、当前任务上下文、以及所有主对话级别的工具权限。

什么是子代理

子代理是一个有独立规则、工具权限、上下文窗口、为完成某一类任务的专职助手。

类比职场:一个岗位做一件事,并且有明确的权限边界。

上下文隔离机制

关键特性:子代理天然拥有独立的上下文窗口,执行完即丢弃,只把结论带回来。这是 Claude Code 里唯一一个结构上允许"执行完即丢弃"的组件。

四句话概括子代理的核心:

  • 不是为了 Claude 做得更多
  • 而是为了 Claude 记得更少
  • 但记得对
  • 执行过程不再污染主对话

用与不用的本质区别

方式一:事必躬亲

亲自调研市场(输出 200 行分析)、亲自写代码(输出 500 行日志)、亲自测试(又是 300 行)、亲自写文档……最后主对话里塞满了各种细节,已经记不清最初的目标是什么了。

方式二:专人专岗

安排一个市场专员去调研,只需要他给你一份 1 页的报告;安排一个测试工程师去跑测试,只需要他告诉你结果是"通过"还是"有 3 个失败";安排一个技术文档专员去写文档……每个人带着明确的任务出去,完成后只把结论带回来。

对照表:

维度事必躬亲(不用子代理)专人专岗(用子代理)
主对话承载内容全量执行过程仅结论
上下文窗口快速膨胀保持清洁
注意力分配被过程分散专注决策
并行能力串行多任务并行

子代理的四大工程价值

价值一:隔离——解决上下文污染

通过独立的上下文窗口,把"对当前执行有用但对后续决策毫无价值"的日志、搜索结果、中间推理挡在主对话之外。子代理执行完即丢弃,只把结论带回来。

反例:在主对话里直接 pnpm test,500 行日志直接进上下文。 正例:派 test-runner 子代理去跑,回报"3 个失败,在 src/auth/login.test.ts"。

价值二:约束——把行为边界变成系统规则

通过工具权限边界,把"我希望你别这么做"变成"你物理上做不到"。代码审查只能读、修 bug 才能写——角色职责不再依赖提示词自觉。

反例:主对话里加一段提示词"请不要修改 migrations 目录",Claude 大概率会忘掉。 正例:在子代理的 frontmatter 中只配置 tools: Read, Grep, Glob,物理上就不能写文件。

价值三:复用——把经验沉淀为版本化资产

当子代理被定义成文件、放进版本控制后,好的使用方式就从一次性对话,变成了可共享、可迭代的工程资产

反例:每次都口头描述"帮我跑一下测试",表述每次都略有不同。 正例.claude/agents/test-runner.md 文件在团队仓库共享,新人 clone 仓库后立刻可用。

价值四:并行——天然的多任务加速器

子代理可以后台运行,让原本串行的复杂任务同时推进。

反例:依次在主对话里调研认证逻辑、数据库设计、API 接口,每个调研都挤占主上下文。 正例:同时派 3 个子代理并行调研,最后主对话只拿到 3 份结论报告。

这四点合在一起,标志着 Claude Code 的使用方式,从"对话技巧"正式跨入"工程系统"。

什么时候该用子代理?

子代理的价值不在于"能不能用",而在于"该不该用"。判断的简单标准:主对话到底需不需要承载执行过程本身

适合用子代理的四类任务

第一类:高噪声输出的任务

执行过程中会产生大量中间信息,但主对话真正关心的,往往只有一个结论。

  • 跑测试套件(数千行输出 → "3 失败")
  • 检索大代码库(成百上千 grep 结果 → 路径列表)
  • 分析错误日志(一堆中间推理 → 根因 + 修复建议)

第二类:角色边界必须明确的任务

有些事情,你只希望 Claude"看",而不希望它"动手";有些操作只能在特定目录、特定范围内发生。

  • 代码审查(只能读)
  • 数据库只读分析(Read-Only 工具)
  • 敏感文件分析(不能写)

第三类:可以并行展开的研究型任务

当探索之间相互独立时,与其串行调研,不如并行派子代理。

  • 同时调研认证、数据库、API 三个模块
  • 对比多种技术方案
  • 从多个视角分析同一个问题

第四类:可拆成清晰阶段的流水线式任务

每个阶段的目标、权限、输出都明确时,用子代理固定责任。

定位代码 → 代码审查 → 修改 → 测试验证

不适合用子代理的场景

  • 需要频繁来回讨论和即时调整的对话
  • 主对话需要看到完整执行过程才能决策的情况
  • 任务本身很轻,启动子代理反而增加开销

一条关键约束:子代理不能嵌套子代理

这是架构硬约束,所有编排必须由主对话完成。

这意味着:

  • 如果你需要"先审查再修复",必须由主对话依次调用两个子代理,而不是让第一个子代理去调用第二个。
  • 流水线的"调度中心"只有一个,就是主对话本身。
  • 如果需要在子代理内复用知识,skills 字段预加载(而非再嵌套一个子代理)。

配置详解:子代理的 frontmatter

子代理使用 Markdown + YAML frontmatter 格式:

yaml
---
name: <代理名称>
description: <何时被调用>
tools: <工具列表>
disallowedTools: <禁止工具列表>
model: <sonnet|opus|haiku>
permissionMode: <default|acceptEdits|bypassPermissions|plan>
skills: <预加载的 skill 列表>
hooks: <子代理专属生命周期 Hook>
---

<正文 = 子代理的系统提示词>

子代理只会收到这段系统提示词和基本环境信息(工作目录等),不会继承主对话的完整系统提示词

description 的设计艺术

description 字段决定了 Claude 何时自动调用你的子代理——这是配置中最重要的设计决策。

yaml
---
name: code-reviewer
description: Review code for quality, security, and best practices. Use proactively after code modifications.
tools: Read, Grep, Glob, Bash
---

要点:

  • 说明做什么(审查代码质量、安全、规范)
  • 说明什么时候用(代码修改后,或用户请求时)
  • Proactively 关键词会鼓励 Claude 在合适的时机主动委派任务

tools vs disallowedTools:白名单与黑名单

表达方式适用场景
tools: [Read, Grep]子代理只需要少数工具,白名单更清晰
disallowedTools: [Edit, Write]子代理需要大部分工具但排除个别,黑名单更简洁

不要同时使用两者——选一种即可。

工具权限应遵循最小权限原则:能用 Read 完成的任务,就不要给 Edit。

常见子代理的工具组合推荐:

子代理类型推荐 tools
代码审查Read, Grep, Glob
测试运行器Bash(配合 hooks 限制命令)
数据库只读Bash(配 validate-readonly-query.sh 校验)
影响分析Read, Grep, Glob, Bash
文档撰写Read, Write, Glob

model:模型选择与默认值

model 字段决定子代理使用哪个模型。可选 sonnet / opus / haiku,留空则继承主对话模型。

权衡原则:

  • 复杂推理任务(架构分析、复杂 Bug 定位)→ opus
  • 常规任务(代码审查、测试运行)→ sonnet
  • 简单批量任务(文件查找、格式校验)→ haiku

permissionMode:权限模式

控制子代理在执行过程中遇到需要权限的操作时如何处理:

模式行为
default每次需要权限都询问
acceptEdits自动接受文件编辑
bypassPermissions跳过所有权限检查
plan先规划再执行(Plan 子代理默认)

子代理会继承主对话的权限上下文,但可以通过此字段覆盖。

skills:为子代理预加载知识

yaml
---
name: impact-analyzer
description: Analyze impact scope of code changes on the full call chain.
tools: Read, Grep, Glob, Bash
skills:
  - chain-knowledge    # 链路拓扑和 SLA 约束
  - recent-incidents   # 近期事故记录
---

这是"子代理内复用知识"的正确做法——通过 skills 字段预加载,而不是嵌套另一个子代理。

hooks:子代理专属的生命周期 Hook

子代理可以在自己的 frontmatter 中定义 Hook——这些 Hook 只在该子代理运行期间生效,子代理结束后自动清理。

yaml
---
name: db-reader
description: Execute read-only database queries.
tools: Bash
hooks:
  PreToolUse:
    - matcher: "Bash"
      hooks:
        - type: command
          command: "./scripts/validate-readonly-query.sh"
---

典型用法:

  • PreToolUse 校验命令是否安全
  • PostToolUse 记录执行日志
  • 子代理结束时清理临时文件

子代理的存放位置与优先级

位置路径适用场景
项目级(仅当前项目可用)./.claude/agents/项目特有的角色,比如针对特定框架的测试运行器
用户级(所有项目可用)~/.claude/agents/通用角色,比如日志分析器、通用代码审查器

优先级:项目级覆盖用户级,同名时项目级优先生效。

创建子代理的三种方式

方式一:交互式创建

在 Claude Code 中输入 /agents,按照向导操作:

  1. 输入 /agents
  2. 选择 "Create new agent"
  3. 选择存放位置(User-level 或 Project-level)
  4. 选择 "Generate with Claude" 并描述功能
  5. 选择需要的工具
  6. 选择模型
  7. 保存

方式二:手写配置文件

直接创建 .claude/agents/your-agent.md 文件。优势是更精细的控制,方便版本管理,可以从其他项目复制。

方式三:CLI 参数临时创建

通过 --agents 参数,可以在启动 Claude Code 时传入 JSON 格式的子代理定义。这种方式创建的子代理仅在当前会话中存在,不会保存到磁盘。

特别适合 CI/CD 自动化时在流水线中临时创建任务专用的子代理:

bash
claude --agents '{"test-runner": {"description": "Run tests", "tools": ["Bash"]}}'

实战:一个最小可用的子代理配置

yaml
---
name: code-reviewer
description: Review code for quality, security, and style issues. Use proactively after any code modification.
tools: Read, Grep, Glob
model: sonnet
permissionMode: default
---

You are a senior code reviewer. When reviewing code:

1. Check for security issues (hardcoded secrets, SQL injection, XSS)
2. Check for style consistency with the codebase
3. Check for missing tests
4. Provide a structured report with severity levels (blocker / major / minor / nit)

Do NOT modify code. Only report findings.

配置要点解读:

  • description 中明确"after any code modification",配合 "Use proactively" 鼓励自动触发
  • tools 只给只读工具,物理上不能修改代码(约束价值
  • permissionMode: default 让敏感操作保持询问
  • 系统提示词明确职责与边界,不给它越权空间

常见陷阱速查

错误做法后果正确做法
description 写得太泛子代理从不触发,或触发时机不准明确"做什么 + 什么时候用",用 "Proactively" 关键词
tools 和 disallowedTools 同时用配置冲突报错二选一
想让子代理再调用子代理架构不支持,主对话必须亲自调度skills 字段预加载复用知识
用子代理跑小任务启动开销 > 收益小任务直接主对话处理
子代理配置里给太多工具违反最小权限原则,行为不可控只给完成任务必需的最小工具集
项目级和用户级同名子代理行为不一致,调试困难用命名空间区分,或明确选用哪一层
期望子代理继承主对话系统提示词实际只继承工作目录和环境信息把核心指令写在子代理自己的 frontmatter 与正文中
把子代理当 Skill 用子代理有独立上下文,启动开销大静态规则用 Skill,动态隔离任务用 Sub-Agent

局限性声明

子代理不是万能药,几个边界必须诚实指出:

  • 不能嵌套:架构硬约束,复杂流水线必须由主对话统一调度
  • 启动开销:每个子代理启动都有固定 token 成本,简单任务直接交给主对话更划算
  • 模型限制:子代理与主对话使用同一权限上下文,敏感操作仍需主对话授权
  • 调试成本:子代理的执行过程对主对话不可见,问题排查需要看子代理的返回结果反推
  • CI/CD 临时场景:临时子代理(CLI 方式)只在当前会话存在,复杂流水线需要持久化定义
  • 并行数量:同时派 N 个子代理意味着 N 倍的 token 消耗,需权衡收益与成本

核心要点回顾

  • 子代理的核心是隔离:通过独立的上下文窗口,把执行噪声挡在主对话之外,只回结论
  • 四大工程价值:隔离、约束、复用、并行,对应内存管理、安全边界、组织效率三大经典软件工程命题
  • 四类适用任务:高噪声输出 / 角色边界明确 / 可并行研究 / 流水线式阶段任务
  • 架构硬约束:子代理不能嵌套子代理,所有编排由主对话完成
  • 配置核心字段description(决定何时触发)+ tools(最小权限原则)+ model(性能/成本权衡)
  • 存放优先级:项目级覆盖用户级

子代理把"对话技巧"升级为"工程系统"——这是 Claude Code 从 ChatGPT 进化为团队编排平台的关键组件。


延伸阅读