avatar


4.SubAgent

简介

Claude Code的本质是"大模型+工具调用循环+有限上下文窗口",窗口不仅有限,而且是主对话唯一的工作台,读进来的文件、跑出来的命令输出,全都堆在这一块地方。《3.Skills》把工作流做成了按需加载的Skill(技能),但按需加载解决的只是"指令"的成本,活儿本身仍然在同一个窗口里干:检索代码、分析日志、跑测试这类子任务,会把成百上千行中间产物灌进主上下文。

这些中间产物有一个共同特点:高噪声。500行错误日志里,真正有价值的可能只有3行错误栈;200行测试输出里,我们要的往往只是"哪几个失败了"。噪声进了主上下文就赖着不走,挤占窗口空间、稀释关键信息,还会诱发更早的上下文压缩。窗口越用越脏,回答质量随之下降,这就是上下文污染。

本章讲Claude Code对这个问题的解法:Sub-Agent(子智能体),把高噪声子任务委派到一个独立的上下文窗口里执行,过程留在那边,只把结论带回来。它也是围绕上下文的三部曲的最后一块:Memory持久注入、Skills按需注入之后的隔离执行。

Sub-Agent的工作方式

Sub-Agent是在当前会话内运行的专用助手,它有自己独立的上下文窗口,跑自己完整的工具调用循环(agent loop):自己读文件、自己执行命令、自己迭代。它与主对话的交互只有两次,接收一段任务描述,返回一份结果摘要。逐步的中间输出不会回传,Sub-Agent读过的几十个文件、翻过的几百行日志,随着任务结束一起被丢弃,主上下文始终干净。

是否委派、委派给谁,由Claude自动决定:它拿当前任务与每个Sub-Agent的description字段做匹配,匹配上就委派。所以description不是注释,而是路由依据,它的写法直接决定这个Sub-Agent会不会被用起来。

注意:Sub-Agent的窗口同样有限,接近上限时它会在自己的窗口内独立做上下文压缩,与主会话互不影响。

从成本模型看,Sub-Agent有两种形态。

  • Fork(分支)
    继承主对话至今的完整上下文、系统提示、工具与权限。因为与主对话共享同一段前缀,可以命中同一份prompt cache(提示词缓存,见《1.概述》),启动便宜。适合"需要带上全部背景的分身",比如从当前进度分出一条线去起草测试。
  • Named(具名)
    从全新的上下文启动,只装载自己的系统提示(即定义文件的正文)、工具限制和主对话传来的任务描述。prompt cache独立,首次调用有冷启动成本,换来的是彻底的隔离与定制。适合"背景必须干净的专家",比如只读的代码审查员。

内置Agent

不写任何配置,Claude Code已经自带几个内置Agent。

Agent 模型 工具 用途 可恢复
Explore Haiku 只读工具,无Write/Edit 文件发现、代码搜索、快速探索
Plan 继承主会话 只读工具 计划模式下的前置研究
general-purpose 继承主会话 全部工具 复杂多步任务、需要改动文件
statusline-setup Sonnet - 服务于/statusline命令 -
claude-code-guide Haiku - 回答Claude Code功能问题 -

其中Explore和Plan有三个刻意的设计。

  • 只读
    两者都没有写工具,怎么调用都不会改动文件系统。
  • 跳过CLAUDE.md与git状态
    为了快和省,它们启动时不加载CLAUDE.md层级,也不读git状态,CLAUDE.md机制见《2.Memory》。其他Sub-Agent则会加载完整的CLAUDE.md层级、git状态与预加载的Skill。
  • 一次性
    执行完即销毁,不可恢复。这不是缺陷而是设计:探索类任务的中间过程本身就是要丢弃的噪声,留着没有意义。需要接着干活的任务,改用可恢复的general-purpose

Explore跳过CLAUDE.md,会不会让它"不懂规矩"?通常不会有影响:主会话拿到Explore的结果后,是在自己的完整上下文(含CLAUDE.md)里使用的。只有当某条规则必须在探索阶段本身生效时,才需要在委派的任务描述里把规则重述一遍。

自定义Sub-Agent

内置Agent是通用的,真正的价值在自定义:为特定任务定义专职的Sub-Agent,并随项目共享给团队。

定义位置

Sub-Agent定义是Markdown文件,可以放在多个位置,同名时按优先级从高到低胜出。

优先级 位置 说明
1 Managed设置目录内的.claude/agents/ 组织统一下发
2 CLI参数--agents传入的JSON 仅当次会话有效
3 项目级.claude/agents/ 随项目提交、团队共享,支持子目录递归
4 用户级~/.claude/agents/ 个人所有项目可用
5 插件内的agents/目录 随插件分发

项目级定义会从工作目录向上逐级扫描各层.claude/agents/;同名时,离当前工作目录最近的定义胜出。

文件格式与字段

定义文件由YAML front matter和Markdown正文组成,正文就是这个Sub-Agent的系统提示。front matter字段如下,只有namedescription必填。

字段 必填 说明
name 小写字母加连字符的唯一标识,在Hook(钩子)事件中以agent_type传递
description 自动委派的路由依据
tools 工具白名单,省略则继承主对话的全部工具
disallowedTools 工具黑名单,与tools同时出现时在白名单基础上再剔除(黑名单优先)
model sonnet/opus/haiku别名、完整模型ID或inherit,默认inherit
permissionMode default/acceptEdits/auto/dontAsk/bypassPermissions/plan
maxTurns 最大轮数上限
skills 预加载的Skill列表,启动时注入完整内容,Skill机制见《3.Skills》
mcpServers 可用的MCP(Model Context Protocol,模型上下文协议)服务器,支持内联定义或按名称引用,机制见《6.MCP》
hooks 生命周期Hook配置,机制见《5.Hooks》
memory user/project/local,开启跨会话的持久化记忆目录,记忆机制见《2.Memory》
background true时默认后台运行,默认false
effort low/medium/high/xhigh/max,覆盖会话级设置
isolation 设为worktree时在临时分支中运行,无改动的分支自动清理
color UI显示颜色:red/blue/green/yellow/purple/orange/pink/cyan
initialPrompt --agent作为整会话身份运行时,自动提交的首轮提示

注意:插件里的Agent不支持hooksmcpServerspermissionMode三个字段,写了会被忽略;需要这些能力时,把定义复制到项目的.claude/agents/。插件机制见《9.Plugins》

调用与管理

除了自动委派,我们还有一组显式手段。

方式 用法 说明
自动委派 正常提需求 Claude按description匹配后自动委派
显式指定 @agent-code-reviewer 看一下auth模块 @agent-<name>点名,不经过自动匹配
/agents 会话内输入/agents 管理UI,Running标签看运行中的Agent,Library标签创建与编辑定义
--agents claude --agents '<JSON>' 会话级临时定义,不持久化
--agent claude --agent code-reviewer 整个会话以该Agent身份运行,此时initialPrompt作为首轮提示自动提交
/fork /fork draft unit tests 开一个继承完整上下文的Fork分支去干活

自动委派是主路径:日常使用时不必记住每个Sub-Agent的名字,把description写清楚"做什么、什么时候用",Claude会在合适的时机自己委派;description里写上"use proactively",委派会更积极。显式指定和/fork是补充:前者用于"我明确知道该谁干",后者用于"我要一个带着全部背景的分身"。

注意:CLI的--disallowedTools "Agent(Explore)"可以按名字禁用某个Agent。

示例

下面三个示例围绕同一个场景:一个正在迭代的业务项目,我们希望审查有人管、排错有专家、项目知识能沉淀。

项目级的code-reviewer

把审查员定义进项目仓库,团队每个人都能用。

示例代码(.claude/agents/code-reviewer.md):

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
---
name: code-reviewer
description: 资深代码审查专家,审查代码质量、安全漏洞与最佳实践。代码有改动时主动使用(use proactively)。
tools: Read, Grep, Glob, Bash
model: sonnet
---

你是一名资深代码审查员。被调用时:

1. 运行`git diff`找出本次改动
2. 聚焦被修改的文件
3. 按优先级组织反馈:严重、警告、建议
4. 每条反馈附带具体的修改示例

不要输出你读过的文件内容,只输出审查结论。

两个要点:tools只给了读取检索类工具加Bash(用来跑git diff),没有EditWrite,审查员永远改不了代码;正文最后一句约束了回传内容,确保带回主对话的是结论而不是噪声。

会话级的临时debugger

有些Sub-Agent只为当前这一次排查服务,不值得在仓库里留文件,用--agents在启动时临时定义。

示例代码:

1
2
3
4
5
6
7
8
claude --agents '{
"debugger": {
"description": "Debugging specialist for errors",
"prompt": "You are an expert debugger. Analyze errors, identify root causes, provide fixes.",
"tools": ["Read", "Edit", "Bash"],
"model": "sonnet"
}
}'

会话结束即消失,不落盘、不污染项目配置。

带持久记忆的领域专家

Sub-Agent本身是一次性的,但配上memory字段,它可以跨会话积累知识。

示例代码(.claude/agents/domain-expert.md):

1
2
3
4
5
6
7
8
---
name: domain-expert
description: 本项目的领域知识专家,回答架构、约定与历史决策类问题时使用。
memory: project
---

你是本项目的领域专家。回答问题时优先查阅你的记忆。
每次任务结束前,把新确认的架构模式、团队约定和反复出现的问题更新进记忆。

memory: project让它在项目级的持久化记忆目录中读写。用得越多,这个专家越懂项目——执行是一次性的,沉淀下来的记忆不是。

经验

  • 改了定义文件,Sub-Agent没变
    定义只在会话启动时加载。直接编辑.claude/agents/下的文件后,要重启会话才生效;用/agents管理UI创建的立即生效。

  • Sub-Agent用的模型不是我指定的
    模型选择有一条优先级链:环境变量>调用时参数>front matter的model字段>主会话模型。排查时先看环境变量CLAUDE_CODE_SUBAGENT_MODEL,它的优先级最高,会盖掉定义文件里的model

  • 权限模式从主会话级联,Sub-Agent覆盖不了
    主会话处于bypassPermissionsacceptEdits时,Sub-Agent的permissionMode无法覆盖它;主会话是auto时,Sub-Agent也进入auto。各权限模式的定义见《1.概述》

  • 嵌套有深度上限
    Sub-Agent可以再委派Sub-Agent,但深度超过5就无法继续生成;深度在生成那一刻固定,之后恢复也不会改变。

  • toolsdisallowedTools对MCP工具的语义不对称
    tools: Read, Bash的含义是"只允许这两个内置工具",主会话的MCP工具会被一并排除;要在限制工具的同时保留MCP工具,用黑名单,如disallowedTools: Write, Edit,未列入黑名单的工具(含MCP工具)照常继承。黑名单还能按MCP维度剔除:disallowedTools: mcp__github移除该服务器的全部工具,mcp__*移除所有MCP工具,这种通配写法只在disallowedTools里有效。

  • 需要反复交互的任务不要委派
    Sub-Agent的交互模型是"一段任务描述进,一份结果摘要出",中途没有来回;AskUserQuestion这类依赖UI的工具在Sub-Agent里也不可用。需要迭代反馈、边做边讨论的活,留在主对话。

  • 选型:不是所有问题都该用Sub-Agent

    维度 Sub-Agent Skill Background Agent
    运行位置 会话内的独立上下文 主上下文内 多个独立会话,中央监控
    上下文成本 隔离,只回传摘要 全部计入主对话 各自独立
    适用场景 隔离高噪声操作 跨任务复用指令 大规模并行、无需交互

    一句话分工:要复用指令,用Skill;要隔离噪声,用Sub-Agent;要大规模并行且全程无需交互,再考虑Background Agent。Skill已在上一章展开,Background Agent(后台智能体,在独立的后台会话中运行、由中央界面统一监控)不在本系列的展开范围,此处不赘述。

到这里,上下文三部曲完整了:持久注入、按需注入、隔离执行。但要看清它们共同的边界——CLAUDE.md是建议,Skill是按需加载的建议,委派也只是大概率发生的行为,模型遵守它们本质上是概率性的;有些事必须百分之百发生,这就需要确定性的机制,见《5.Hooks》

文章作者: Kaka Wan Yifan
文章链接: https://kakawanyifan.com/128040
版权声明: 本博客所有文章版权为文章作者所有,未经书面许可,任何机构和个人不得以任何形式转载、摘编或复制。

留言板