Claude Code 智能体协作
Claude Code 智能体协作
创建自定义子智能体
14 分钟阅读
创建自定义子智能体
在 Claude Code 中创建并使用专属的 AI 子智能体,用于特定任务的工作流并改善上下文管理。
子智能体是处理特定类型任务的专属 AI 助手。当一个附属任务会用你不会再引用的搜索结果、日志或文件内容淹没你的主对话时,就可以使用子智能体:子智能体会在自己的上下文中完成这项工作,只返回摘要。当你反复用相同的指令生成同一类工作者时,就应该定义一个自定义子智能体。
每个子智能体都在自己的上下文窗口中运行,拥有自定义的系统提示词、特定的工具访问权限和独立的权限。当 Claude 遇到一个匹配某个子智能体描述的任务时,就会委派给该子智能体,由其独立完成工作并返回结果。要实际体验节省的上下文,可参阅上下文窗口可视化,其中展示了一个子智能体在自己独立的窗口中完成调研的会话。
子智能体能帮助你:
- 保留上下文,把探索和实现过程留在主对话之外
- 强制限制,限定子智能体可以使用哪些工具
- 跨项目复用配置,通过用户级子智能体实现
- 专注特定行为,为特定领域使用聚焦的系统提示词
- 控制成本,将任务路由给更快、更便宜的模型,例如 Haiku
Claude 会根据每个子智能体的描述来决定何时委派任务。创建子智能体时,请写一份清晰的描述,让 Claude 知道何时使用它。
Claude Code 内置了若干子智能体,例如 Explore、Plan 和 general-purpose。你也可以创建自定义子智能体来处理特定任务。
内置子智能体
Claude Code 内置了一些子智能体,Claude 会在合适的时候自动使用它们。每个内置子智能体都会继承父对话的权限,并附加额外的工具限制。
Explore 和 Plan 会跳过你的 CLAUDE.md 文件和父会话的 git 状态,以保持调研的快速与低成本。其他所有内置和自定义子智能体都会加载这两者。关于子智能体能获取哪些信息的完整说明,请参阅启动时加载的内容。
- Explore
- Plan
- General-purpose
- 其他
一个快速的只读智能体,专门用于搜索和分析代码库。
- 模型:继承主对话的模型,在 Claude API 上限制为不超过 Opus,因此 Explore 运行的模型永远不会比你已经为该会话选择的模型更贵
- 工具:只读工具;拒绝 Write 和 Edit
- 用途:文件发现、代码搜索、代码库探索
从 v2.1.198 开始,Explore 会继承主对话的模型,而不再总是运行在 Haiku 上。在 Claude API 上,继承的模型上限为 Opus:使用更高级别的主对话会让 Explore 运行在 Opus 上,使用 Sonnet 或 Haiku 的主对话则让 Explore 运行在同一模型上。在任何其他服务商上,例如 Amazon Bedrock、Google Cloud 的 Agent Platform、Microsoft Foundry 或 AWS 上的 Claude 平台,Explore 会直接继承主对话的模型。
一个名为 Explore 的用户级或项目级子智能体会覆盖内置版本,并保留自己的 model 字段,因此可以定义一个设置了 model: haiku 的版本,将探索保持在成本较低的模型上。
当 Claude 需要在不做任何更改的情况下搜索或理解代码库时,会委派给 Explore。这样探索结果就不会占用你的主对话上下文。
调用 Explore 时,Claude 会指定一个彻底程度:quick(快速)用于定向查找,medium(适中)用于均衡探索,very thorough(非常彻底)用于全面分析。
内置子智能体默认在交互式会话中注册。要限制它们:
- 要阻止某个特定的内置类型,将其加入
permissions.deny,如禁用特定子智能体所示。 - 要阻止 Claude 委派给任何子智能体,用
permissions.deny拒绝Agent工具本身。 - 要仅移除内置的
Explore和Plan子智能体,设置CLAUDE_CODE_DISABLE_EXPLORE_PLAN_AGENTS=1。Claude 会直接读取和探索文件,而不是委派给它们。需要 Claude Code v2.1.198 或更高版本。 - 在非交互模式和 Agent SDK 中,设置
CLAUDE_AGENT_SDK_DISABLE_BUILTIN_AGENTS=1可移除所有内置类型,只提供你自己的类型。
除了这些内置子智能体,你还可以用自定义提示词、工具限制、权限模式、钩子和技能创建自己的子智能体。以下各节介绍如何入手并自定义子智能体。
快速开始:创建你的第一个子智能体
子智能体是带有 YAML frontmatter 的 Markdown 文件。要创建一个,可以让 Claude 帮你写,也可以自己编写文件。
从 v2.1.198 开始,/agents 命令不再打开交互式创建向导;运行它会打印一条提醒,让你去问 Claude 或直接编辑 .claude/agents/。子智能体文件、frontmatter 字段,以及 .claude/agents/ 和 ~/.claude/agents/ 的位置都没有变化;只是移除了终端向导。
本教程会创建一个用户级子智能体,用于审查代码并提出改进建议。
让 Claude 创建该子智能体
在 Claude Code 中,描述你想要的子智能体以及要保存到哪里:
Claude 会写出包含 name、description、tools 列表、model 和系统提示词的文件。
查看该文件
打开 ~/.claude/agents/code-improver.md,确认 frontmatter 与你要求的一致。结果看起来像这样:
由于该文件位于 ~/.claude/agents/,这个子智能体在你机器上的每个项目中都可用。要将其限定到某一个项目,可将其移到该项目的 .claude/agents/ 目录下。选择子智能体范围比较了这两种方式。
试用它
让 Claude 委派给这个新的子智能体:
Claude 会委派给你的新子智能体,它会扫描代码库并返回改进建议。
如果 Claude 找不到这个新的子智能体,请重启 Claude Code 后重试。这种情况只会在 ~/.claude/agents/ 在会话启动前还不存在时发生,因为正在运行的会话无法检测到新创建的 agents 目录。
现在你有了一个可以在机器上任何项目中使用的子智能体,用于分析代码库并提出改进建议。
你也可以手动编写子智能体文件,通过 CLI 标志定义它们,或通过插件分发它们。以下各节涵盖所有配置选项。
在 Claude Code v2.1.197 及更早版本中,/agents 会打开一个交互式向导,其中有一个 Running 标签页列出正在运行的子智能体,还有一个 Library 标签页用于创建、编辑和删除它们。
配置子智能体
子智能体文件所在的位置决定了它对谁可用,其 frontmatter 决定了它能做什么。本节介绍子智能体文件存放的位置及其支持的每个字段。
选择子智能体的范围
根据范围将子智能体文件存放在不同位置。当多个子智能体共享相同名称时,Claude Code 会使用优先级更高位置中的那个。
| 位置 | 范围 | 优先级 | 创建方式 |
|---|---|---|---|
| 统一管理设置 | 组织范围 | 1(最高) | 通过统一管理设置部署 |
--agents CLI 标志 | 当前会话 | 2 | 启动 Claude Code 时传入 JSON |
.claude/agents/ | 当前项目 | 3 | 让 Claude 处理,或手动创建文件 |
~/.claude/agents/ | 你的所有项目 | 4 | 让 Claude 处理,或手动创建文件 |
插件的 agents/ 目录 | 插件启用所在范围 | 5(最低) | 随插件安装 |
项目子智能体(.claude/agents/)非常适合特定于某个代码库的子智能体。将其纳入版本控制,方便团队协作使用和改进。
项目子智能体的发现方式是从当前工作目录向上遍历,因此从那里到仓库根目录之间的每一个 .claude/agents/ 都会被扫描。从 v2.1.178 开始,当多个这样的嵌套目录定义了相同的 name 时,Claude Code 会使用离工作目录最近的那个定义。
用 --add-dir 添加的目录同样会被扫描:添加目录内部的 .claude/agents/ 文件夹会与项目子智能体一起加载。关于其他哪些配置类型会从 --add-dir 加载,请参阅额外目录。要在不使用 --add-dir 的情况下跨项目共享子智能体,请使用 ~/.claude/agents/ 或插件。
用户子智能体(~/.claude/agents/)是你在所有项目中都可用的个人子智能体。
Claude Code 会递归扫描 .claude/agents/ 和 ~/.claude/agents/,因此你可以把定义组织到子文件夹中,例如 agents/review/ 或 agents/research/。子目录路径不会影响子智能体的识别或调用方式,因为身份只取决于 name frontmatter 字段。
请在整个目录树中保持 name 值唯一:如果同一个 .claude/agents/ 目录(包括其子文件夹)下有两个文件声明了相同的名称,Claude Code 只会加载其中一个,具体由文件系统读取顺序决定,而非任何有文档记录的优先级。在嵌套的项目目录之间,如上所述,离工作目录最近的定义优先。/doctor 安装体检会报告同一目录中共享同一名称的文件,并建议重命名或删除除其中一个之外的所有文件。在 v2.1.205 之前,/doctor 会打开一个诊断界面,列出重复项并显示哪个定义处于生效状态。
插件的 agents/ 目录同样会被递归扫描。与项目和用户范围不同,插件 agents/ 目录内部的子文件夹会成为限定标识符的一部分:插件 my-plugin 中位于 agents/review/security.md 的文件会注册为 my-plugin:review:security。
CLI 定义的子智能体在启动 Claude Code 时以 JSON 形式传入。它们只存在于该次会话中,不会保存到磁盘,因此非常适合快速测试或自动化脚本。你可以在一次 --agents 调用中定义多个子智能体:
- macOS、Linux、WSL
- Windows PowerShell
--agents 标志接受的 JSON 与基于文件的子智能体使用相同的frontmatter字段:description、prompt、tools、disallowedTools、model、permissionMode、mcpServers、hooks、maxTurns、skills、initialPrompt、memory、effort、background、isolation 和 color。用 prompt 表示系统提示词,相当于基于文件的子智能体中的 markdown 正文。
统一管理的子智能体由组织管理员部署。将 markdown 文件放在统一管理设置目录内的 .claude/agents/ 中,使用与项目和用户子智能体相同的 frontmatter 格式。统一管理的定义优先于同名的项目和用户子智能体。
插件子智能体来自你已安装的插件。它们会与你的自定义子智能体一起加载,并以其限定名称出现在 @-提及的自动补全列表中。关于创建插件子智能体的详情,请参阅插件组件参考。
出于安全原因,插件子智能体不支持 hooks、mcpServers 或 permissionMode frontmatter 字段。从插件加载智能体时,这些字段会被忽略。如果你需要这些字段,可以将该智能体文件复制到 .claude/agents/ 或 ~/.claude/agents/。你也可以在 settings.json 或 settings.local.json 中的 permissions.allow 里添加规则,但这些规则会应用于整个会话,而不仅限于该插件子智能体。
以上任意范围中的子智能体定义,也可用于智能体团队:生成一个团队成员时,你可以引用一个子智能体类型,该成员会使用其 tools 和 model,并将该定义的正文作为附加指令追加到该成员的系统提示词中。关于这条路径上适用哪些 frontmatter 字段,请参阅智能体团队。
编写子智能体文件
子智能体文件使用 YAML frontmatter 进行配置,随后是 Markdown 形式的系统提示词:
Claude Code 会监视 ~/.claude/agents/ 和 .claude/agents/。当你在磁盘上添加或编辑一个子智能体文件,或让 Claude 帮你写一个时,Claude Code 会在几秒钟内检测到变化,下一次委派就会使用更新后的定义,无需重启。
以下两种情况仍需要重启:
- 监视器只覆盖会话启动时已存在的目录,因此在某个范围内的一个新
agents目录中创建第一个智能体文件后,需要重启才能加载它。 - 用
--disable-slash-commands启动的会话根本不会监视这些目录。
frontmatter 定义了子智能体的元数据和配置。正文则成为指导该子智能体行为的系统提示词。子智能体只会收到这份系统提示词,加上诸如工作目录之类的基本环境信息,而不是完整的 Claude Code 系统提示词。
在非交互模式中,--append-subagent-system-prompt 标志会把你提供的文本追加到每个子智能体系统提示词的末尾,包括嵌套的子智能体。需要 Claude Code v2.1.205 或更高版本。
子智能体从主对话当前的工作目录开始运行。在子智能体内部,cd 命令不会在 Bash 或 PowerShell 工具调用之间保留,也不会影响主对话的工作目录。要让子智能体获得该仓库的独立隔离副本,可以设置 isolation: worktree。
设置了 isolation: worktree 的子智能体会在其 worktree 内部运行 Bash 和 PowerShell 命令。如果某条命令的工作目录改为解析到你的主检出(例如因为该 worktree 目录在子智能体运行期间被删除),会以错误失败。在 v2.1.203 之前,这类命令可能会在主检出中运行。
支持的 frontmatter 字段
YAML frontmatter 中可以使用以下字段。只有 name 和 description 是必需的。
| 字段 | 是否必需 | 说明 |
|---|---|---|
name | 是 | 使用小写字母和短横线的唯一标识符。钩子会将该值作为 agent_type 接收。文件名不必与之匹配 |
description | 是 | Claude 何时应委派给该子智能体 |
tools | 否 | 该子智能体可使用的工具。省略时继承所有工具。要将 Skills 预加载到上下文中,请使用 skills 字段,而不要在此处列出 Skill |
disallowedTools | 否 | 要拒绝的工具,会从继承或指定的列表中移除 |
model | 否 | 要使用的模型:sonnet、opus、haiku、fable、完整的模型 ID(例如 claude-opus-4-8),或 inherit。默认为 inherit |
permissionMode | 否 | 权限模式:default、acceptEdits、auto、dontAsk、bypassPermissions、plan,或 作为 default 别名的 manual。manual 别名需要 Claude Code v2.1.200 或更高版本。对插件子智能体会被忽略 |
maxTurns | 否 | 子智能体停止前允许的最大智能体轮次数 |
skills | 否 | 启动时预加载到子智能体上下文中的技能。会注入完整的技能内容,而不仅是描述。子智能体仍可通过 Skill 工具调用未列出的项目、用户和插件技能 |
mcpServers | 否 | 该子智能体可用的MCP 服务器。每个条目既可以是引用已配置服务器的名称(例如 "slack"),也可以是以服务器名为键、完整MCP 服务器配置为值的内联定义。对插件子智能体会被忽略 |
hooks | 否 | 限定于该子智能体的生命周期钩子。对插件子智能体会被忽略 |
memory | 否 | 持久化记忆范围:user、project 或 local。启用跨会话学习 |
background | 否 | 设为 true 可让该子智能体始终以后台任务运行,即使 Claude 需要立即获得其结果。未设置时由 Claude 决定,从 v2.1.198 开始默认在后台运行子智能体 |
effort | 否 | 该子智能体处于活动状态时的 effort 级别。覆盖会话的 effort 级别。默认:继承自会话。选项:low、medium、high、xhigh、max;可用级别取决于模型 |
isolation | 否 | 设为 worktree,即可在一个临时的 git worktree 中运行该子智能体,为其提供一份独立隔离的仓库副本,默认从你的默认分支分出,而不是父会话的 HEAD。如果子智能体未做任何更改,该 worktree 会被自动清理 |
color | 否 | 该子智能体在任务列表和记录中显示的颜色。可选 red、blue、green、yellow、purple、orange、pink 或 cyan |
initialPrompt | 否 | 当该智能体作为主会话智能体运行时(通过 --agent 或 agent 设置),自动作为首个用户轮次提交。会处理命令和技能。会置于用户提供的任何提示词之前 |
选择模型
model 字段控制子智能体使用哪个AI 模型:
- 模型别名:使用其中一个可用别名:
sonnet、opus、haiku或fable - 完整模型 ID:使用完整的模型 ID,例如
claude-opus-4-8或claude-sonnet-5。接受与--model标志相同的值 - inherit:使用与主对话相同的模型
- 省略:默认为
inherit,使用与主对话相同的模型
当 Claude 调用一个子智能体时,还可以为该次特定调用传入一个 model 参数。Claude Code 会按以下顺序解析子智能体的模型:
CLAUDE_CODE_SUBAGENT_MODEL环境变量,当其被设为某个模型别名或模型 ID 时- 该次调用传入的
model参数 - 子智能体定义中的
modelfrontmatter - 主对话的模型
从 v2.1.196 开始,将 CLAUDE_CODE_SUBAGENT_MODEL 设为 inherit,效果等同于不设置它:解析会继续检查该次调用的 model 参数,然后是 frontmatter。在更早的版本中,inherit 会强制子智能体使用主对话的模型,并忽略这两个来源。
Claude Code 会将环境变量、单次调用参数和 frontmatter 中的值与你组织的 availableModels 允许列表进行核对。它会跳过解析为受排除模型的值,改用继承的模型运行该子智能体。
从 v2.1.198 开始,子智能体还会继承主对话的扩展思考配置:如果你的会话中启用了思考,子智能体也会启用;如果关闭了,也保持关闭。没有针对单个子智能体的思考设置。在 v2.1.198 之前,子智能体运行时会禁用扩展思考,无论主对话的设置如何。
控制子智能体的能力
你可以通过工具访问权限、权限模式和条件规则来控制子智能体能做什么。
可用工具
子智能体默认继承主对话中可用的内部工具和 MCP 工具。以下工具依赖主对话的界面或会话状态,即使在 tools 字段中列出,子智能体也无法使用它们:
AskUserQuestionEnterPlanModeExitPlanMode,除非该子智能体的permissionMode是planScheduleWakeupWaitForMcpServers
要限制工具,可以将 tools 字段用作允许列表,或将 disallowedTools 字段用作拒绝列表。以下示例用 tools 只允许 Read、Grep、Glob 和 Bash。该子智能体无法编辑文件、写入文件,或使用任何 MCP 工具:
以下示例用 disallowedTools 继承主对话中除 Write 和 Edit 之外的所有工具。该子智能体保留 Bash、MCP 工具及其他一切:
如果两者都设置了,会先应用 disallowedTools,再基于剩余的工具池解析 tools。同时出现在两者中的工具会被移除。
除了精确的工具名称,这两个字段都接受 MCP 服务器级别的模式:mcp__<server> 或 mcp__<server>__* 会授予或移除该服务器的全部工具。在 disallowedTools 中,mcp__* 还会移除任何服务器的所有 MCP 工具。以下示例移除 github MCP 服务器的所有工具,同时保留其他服务器的工具和所有内置工具:
限制可以生成哪些子智能体
当一个智能体通过 claude --agent 作为主线程运行时,它可以用 Agent 工具生成子智能体。要限制它能生成哪些子智能体类型,可在 tools 字段中使用 Agent(agent_type) 语法。
Task(...) 引用仍可作为别名使用。这是一个允许列表:只能生成 worker 和 researcher 子智能体。如果该智能体尝试生成任何其他类型,请求会失败,该智能体在其提示词中只能看到被允许的类型。要在允许其他所有智能体的同时阻止特定智能体,请改用 permissions.deny。
要允许无限制地生成任何子智能体,使用不带括号的 Agent:
如果 tools 列表中完全省略了 Agent,该智能体就无法生成任何子智能体。
Agent(agent_type) 允许列表语法只适用于通过 claude --agent 作为主线程运行的智能体。在子智能体定义中,在 tools 中列出 Agent 可让该子智能体生成嵌套子智能体,但括号内的任何类型列表都会被忽略。
为子智能体限定 MCP 服务器范围
使用 mcpServers 字段,可以让子智能体访问主对话中不可用的 MCP 服务器。这里定义的内联服务器会在子智能体启动时连接,在其完成时断开。字符串引用则共享父会话的连接。
列表中的每个条目,既可以是一个内联服务器定义,也可以是一个引用会话中已配置的 MCP 服务器的字符串:
内联定义使用与 .mcp.json 服务器条目相同的模式,以服务器名为键,支持 stdio、http、sse 和 ws 类型。
要让某个 MCP 服务器完全不进入主对话、避免其工具描述占用主对话的上下文,请在此处以内联方式定义它,而不是放在 .mcp.json 中。子智能体会获得这些工具;父对话则不会。
从 v2.1.153 开始,适用于主会话的 MCP 限制同样覆盖子智能体 frontmatter 中声明的服务器:
当这些限制阻止某个服务器时,Claude Code 会跳过它,并显示一条警告,列出被阻止的服务器。
统一管理设置的限制适用于每个子智能体,无论其定义方式如何。--strict-mcp-config 不会过滤你通过 --agents 或 SDK 的 agents 选项以内联方式传入的服务器,因为那些是调用方显式提供的输入。
权限模式
permissionMode 字段控制子智能体如何处理权限提示。子智能体会继承主对话的权限上下文,并可以覆盖该模式,除非父级模式按下文所述具有优先权。
| 模式 | 行为 |
|---|---|
default | 标准权限检查,带提示 |
acceptEdits | 对工作目录或 additionalDirectories 中的路径,自动接受文件编辑和常见的文件系统命令 |
auto | 自动模式:由一个后台分类器审查命令和受保护目录的写入操作 |
dontAsk | 自动拒绝权限提示(明确允许的工具仍可正常使用) |
bypassPermissions | 跳过权限提示 |
plan | 计划模式(只读探索) |
如果父级使用 bypassPermissions 或 acceptEdits,则该模式具有优先权,无法被覆盖。如果父级使用自动模式,子智能体会继承自动模式,其 frontmatter 中的任何 permissionMode 都会被忽略:分类器会用与父会话相同的阻止和允许规则来评估该子智能体的工具调用。
将技能预加载到子智能体中
使用 skills 字段,可以在启动时将技能内容注入子智能体的上下文中。这能让子智能体获得领域知识,而不必在执行过程中自行发现并加载技能。
列出的每个技能的完整内容都会在启动时注入子智能体的上下文中。该字段控制哪些技能会被预加载,而不是控制子智能体能访问哪些技能:如果不设置它,子智能体在执行过程中仍可通过 Skill 工具发现并调用项目、用户和插件技能。要让子智能体完全无法调用技能,请从tools 列表中省略 Skill,或将其加入 disallowedTools。
你无法预加载设置了 disable-model-invocation: true 的技能,因为预加载取用的是 Claude 可以调用的同一批技能。如果列出的某个技能缺失或已禁用,Claude Code 会跳过它,并在调试日志中记录一条警告。
这与在子智能体中运行技能正好相反。在子智能体中使用 skills 时,子智能体控制系统提示词并加载技能内容;在技能中使用 context: fork 时,技能内容会被注入你指定的智能体中。两者使用相同的底层机制。
启用持久化记忆
memory 字段为子智能体提供一个能跨对话保留的持久化目录。子智能体会用这个目录随时间积累知识,例如代码库模式、调试洞察和架构决策。
根据记忆应适用的范围广度来选择:
| 范围 | 位置 | 适用场景 |
|---|---|---|
user | ~/.claude/agent-memory/<智能体名称>/ | 该子智能体应在所有项目中记住学到的经验 |
project | .claude/agent-memory/<智能体名称>/ | 该子智能体的知识是特定于该项目的,且可通过版本控制共享 |
local | .claude/agent-memory-local/<智能体名称>/ | 该子智能体的知识特定于该项目,但不应纳入版本控制 |
启用记忆功能后:
- 该子智能体的系统提示词会包含读写记忆目录的说明。
- 该子智能体的系统提示词还会包含记忆目录中
MEMORY.md的前 200 行或 25KB(以先达到者为准),并附有当其超出该限制时应如何整理MEMORY.md的说明。 - Read、Write 和 Edit 工具会自动启用,以便子智能体管理自己的记忆文件。
持久化记忆使用建议
-
project是推荐的默认范围。它使子智能体的知识可通过版本控制共享。 -
让子智能体在开始工作前先查阅自己的记忆:“审查这个 PR,并查看你的记忆中是否有你之前见过的模式。”
-
让子智能体在完成任务后更新自己的记忆:“既然你已经完成了,把你学到的东西保存到你的记忆中。”随着时间推移,这会建立一个知识库,让该子智能体更加有效。
-
直接在子智能体的 markdown 文件中加入记忆相关的指令,使其主动维护自己的知识库:
用钩子设置条件规则
要对工具使用进行更动态的控制,可以使用 PreToolUse 钩子在操作执行前进行校验。当你需要允许某个工具的部分操作、同时阻止其他操作时,这很有用。
以下示例创建了一个只允许只读数据库查询的子智能体。PreToolUse 钩子会在每次 Bash 命令执行前,运行 command 中指定的脚本:
Claude Code 会以 JSON 形式将钩子输入通过 stdin 传给钩子命令。该校验脚本会读取这份 JSON、提取 Bash 命令,并在检测到写操作时以退出码 2 退出以阻止其执行:
关于完整的输入模式,请参阅钩子输入;关于退出码如何影响行为,请参阅退出码。在 Windows 上,请用 PowerShell 编写钩子脚本,并在钩子条目中加入 shell: powershell,如在 PowerShell 中运行钩子所示。
禁用特定子智能体
你可以将特定子智能体加入设置中的 deny 数组,以阻止 Claude 使用它们。使用格式 Agent(subagent-name),其中 subagent-name 要匹配该子智能体的 name 字段。
这对内置和自定义子智能体都适用。你也可以使用 --disallowedTools CLI 标志:
关于权限规则的更多详情,请参阅权限文档。
为子智能体定义钩子
子智能体可以定义在其生命周期中运行的钩子。有两种配置钩子的方式:
- 在子智能体的 frontmatter 中:定义只在该子智能体活动期间运行的钩子
- 在
settings.json中:定义在主会话中、子智能体启动或停止时运行的钩子
子智能体 frontmatter 中的钩子
直接在子智能体的 markdown 文件中定义钩子。这些钩子只在该特定子智能体活动期间运行,并在其完成时被清理。
当该智能体通过 Agent 工具或 @-提及作为子智能体生成时,以及当该智能体通过 --agent 或 agent 设置作为主会话运行时,frontmatter 钩子都会触发。在作为主会话的情况下,它们会与 settings.json 中定义的任何钩子一起运行。
支持所有钩子事件。子智能体最常用的事件是:
| 事件 | 匹配器输入 | 触发时机 |
|---|---|---|
PreToolUse | 工具名称 | 子智能体使用工具之前 |
PostToolUse | 工具名称 | 子智能体使用工具之后 |
Stop | (无) | 子智能体完成时(运行时会转换为 SubagentStop) |
以下示例用 PreToolUse 钩子校验 Bash 命令,并在文件编辑后用 PostToolUse 运行一个 linter:
当该智能体被作为子智能体调用时,frontmatter 中的 Stop 钩子会自动转换为 SubagentStop 事件。
针对子智能体事件的项目级钩子
在 settings.json 中配置钩子,以响应主会话中的子智能体生命周期事件。
| 事件 | 匹配器输入 | 触发时机 |
|---|---|---|
SubagentStart | 智能体类型名称 | 子智能体开始执行时 |
SubagentStop | 智能体类型名称 | 子智能体完成时 |
这两个事件都支持用匹配器按名称定位特定的智能体类型。对于项目级和用户级子智能体,匹配器的值是该智能体 frontmatter 中的 name;对于插件子智能体,则是限定标识符,例如 my-plugin:db-agent。限定名称包含冒号,因此会被当作无锚定的正则表达式来处理;用 ^ 和 $ 锚定它,例如 ^my-plugin:db-agent$,可以只匹配该智能体。
以下示例只在 db-agent 子智能体启动时运行一个设置脚本,并在任何子智能体停止时运行一个清理脚本:
在 Claude Code v2.1.195 或更高版本上,像 db-agent 这样带短横线的匹配器会精确匹配。在更早的版本上,它会被当作无锚定的正则表达式处理,也会对任何包含它的智能体类型触发,例如 prod-db-agent;在这些版本上,请将其锚定为 ^db-agent$。
关于完整的钩子配置格式,请参阅钩子。
使用子智能体
理解自动委派
Claude 会根据你请求中的任务描述、子智能体配置中的 description 字段以及当前上下文,自动委派任务。要鼓励 Claude 主动委派,可以在子智能体的描述字段中加入类似“主动使用”这样的措辞。
显式调用子智能体
当自动委派不够用时,你可以自己请求某个子智能体。有三种方式,从一次性建议逐步升级到会话范围的默认设置:
- 自然语言:在提示词中提及该子智能体的名称;由 Claude 决定是否委派
- @-提及:确保该子智能体运行于这一个任务
- 会话范围:整个会话都使用该子智能体的系统提示词、工具限制和模型,通过
--agent标志或agent设置实现
对于自然语言,没有特殊语法。提及子智能体的名称,Claude 通常会委派:
@-提及该子智能体。 输入 @ 并从自动补全列表中选择该子智能体,就像 @-提及文件一样。这可以确保运行那个特定的子智能体,而不是把选择权留给 Claude:
你的完整消息仍会发给 Claude,由它根据你的要求写出该子智能体的任务提示词。@-提及只控制 Claude 调用哪个子智能体,不控制它收到什么提示词。
由已启用插件提供的子智能体,会以其限定名称出现在自动补全列表中,例如 my-plugin:code-reviewer,或者当插件将智能体组织进子文件夹时,例如 my-plugin:review:security。会话中当前正在运行的已命名后台子智能体,也会出现在自动补全列表中,并在名称旁显示其状态。
你也可以不使用选择器,手动输入提及内容:本地子智能体使用 @agent-<名称>,插件子智能体使用 @agent- 后跟限定名称,例如 @agent-my-plugin:code-reviewer。
将整个会话作为子智能体运行。 传入 --agent <名称>,即可启动一个会话,其主线程本身采用该子智能体的系统提示词、工具限制和模型:
该子智能体的系统提示词会完全替换默认的 Claude Code 系统提示词,方式与 --system-prompt 相同。CLAUDE.md 文件和项目记忆仍会通过正常的消息流程加载。智能体名称会以 @<name> 的形式出现在启动头部,方便你确认它已生效。
这适用于内置和自定义子智能体,并且这个选择会在你恢复会话时保留。
对于插件提供的子智能体,你只需传入智能体名称,Claude Code 就能找到它:
如果多个插件提供了同名的智能体,传入限定名称即可消除歧义:
如果该插件将该智能体放在其 agents/ 目录的子文件夹中,请在限定名称中包含该子文件夹,例如 claude --agent my-plugin:review:security。
要让它成为某个项目中每个会话的默认设置,请在 .claude/settings.json 中设置 agent:
如果两者都存在,CLI 标志会覆盖该设置。
在前台或后台运行子智能体
子智能体可以在前台或后台运行:
- 前台子智能体会阻塞主对话,直到完成。权限提示会照常传递给你。
- 后台子智能体会在你继续工作的同时并发运行。从 v2.1.186 开始,当一个后台子智能体遇到需要权限的工具调用时,该提示会浮现在你的主会话中,并说明是哪个子智能体在请求。批准即可让该子智能体继续,或按 Esc 拒绝这一次工具调用,而不会停止该子智能体。在 v2.1.186 之前,后台子智能体会自动拒绝任何本会触发提示的工具调用。
从 v2.1.198 开始,子智能体默认在后台运行。当 Claude 需要先获得结果才能继续时,会在前台运行子智能体。这个默认值改变的是子智能体运行在哪里,而不是它被允许做什么:后台子智能体仍会在你的主会话中浮现每一个权限提示。在 v2.1.198 之前,Claude 会根据任务在前台和后台之间做选择。
你也可以自己引导这一点:
- 让 Claude 在后台或前台运行某个任务
- 按 Ctrl+B 将一个正在运行的任务转入后台
要关闭所有后台任务功能,将 CLAUDE_CODE_DISABLE_BACKGROUND_TASKS 环境变量设置为 1。请参阅环境变量。
当 CLAUDE_CODE_FORK_SUBAGENT 设置为 1 时,每次生成子智能体都会在后台运行,frontmatter 中的 background 字段不再生效,因为分叉模式会从 Agent 工具中移除 run_in_background 参数。CLAUDE_CODE_DISABLE_BACKGROUND_TASKS 优先于分叉模式,会让生成的子智能体保持在前台。
子智能体中的 API 错误
从 v2.1.199 开始,一个因 API 错误(例如用量限制或反复的服务器错误)而结束运行的子智能体,会将该失败报告给 Claude,而不是把错误文本当作子智能体自己的调研结果返回。Claude 收到的内容取决于该子智能体运行在哪里:
- 前台:如果一次速率限制、过载或服务器错误中断了一个已经产生文本输出的子智能体,Agent 工具会返回那部分输出,并附带一条说明该子智能体被中断、未完成任务的提示。一个没有产生任何输出、或输出只有工具调用的子智能体,会以
Agent terminated early due to an API error失败,并附带错误详情。在 v2.1.199 中,中断了“仅工具调用”这种情况的速率限制、过载或服务器错误,会改为返回一个只包含中断提示的空结果。 - 后台:该子智能体会被标记为失败,Claude 在其结束时收到的消息会说明该 API 错误,并包含该子智能体的最后一次输出,因此部分工作不会丢失。
一旦底层 API 错误消失,让 Claude 重试该任务,或恢复该子智能体。
常见模式
隔离高产出量的操作
子智能体最有效的用途之一,就是隔离会产生大量输出的操作。运行测试、获取文档或处理日志文件都会消耗大量上下文。将这些操作委派给子智能体,冗长的输出会保留在该子智能体的上下文中,只有相关摘要会返回你的主对话。
运行并行调研
对于相互独立的调研任务,可以生成多个子智能体同时工作:
每个子智能体独立探索自己的领域,然后 Claude 汇总各方发现。当各调研路径彼此不依赖时,效果最好。
对于需要持续并行、或超出你上下文窗口容量的任务,智能体团队能为每个工作者提供各自独立的上下文。
串联子智能体
对于多步骤工作流,可以让 Claude 依次使用多个子智能体。每个子智能体完成自己的任务并将结果返回给 Claude,Claude 再把相关上下文传给下一个子智能体。
在子智能体与主对话之间做选择
在以下情况使用主对话:
- 任务需要频繁的来回沟通或迭代式打磨
- 多个阶段共享大量上下文,例如规划、实现和测试
- 你正在进行一次快速、有针对性的改动
- 延迟很重要。子智能体从零开始,可能需要时间来收集上下文
在以下情况使用子智能体:
- 任务会产生你不需要留在主上下文中的冗长输出
- 你想强制施加特定的工具限制或权限
- 该工作是自包含的,可以返回一份摘要
如果你想要的是能在主对话上下文中运行的可复用提示词或工作流,而不是隔离的子智能体上下文,可以考虑改用技能。
对于关于对话中已有内容的快速提问,请使用 /btw,而不是子智能体。它能看到你完整的上下文,但没有工具访问权限,其答案会被丢弃,不会加入历史记录。
生成嵌套子智能体
从 Claude Code v2.1.172 开始,一个子智能体可以生成自己的子智能体。当一个被委派的任务本身又拆分为多个并行子任务时,可以使用这个功能,例如一个审查者子智能体为每项发现分派一个验证者,这样中间输出就永远不会到达你的主对话。只有最顶层子智能体的摘要会返回给你。
嵌套子智能体的配置方式与顶层子智能体相同,并从同一批范围中解析。
提示输入框下方的子智能体面板会显示完整的树状结构:每一行会显示其后代数量的 (+N) 计数,从 v2.1.193 开始,展开某一行会显示该子智能体的同级和直接子级,以及一条通向 main 的路径。
深度是指主对话之下的子智能体层级数,无论每一层是运行在前台还是后台。处于第五层深度的子智能体不会获得 Agent 工具,无法再继续生成。这个限制是固定的,不可配置。
从 Claude Code v2.1.187 开始,一个后台子智能体的深度在其首次生成时就固定下来,之后恢复它不会改变这个深度。例如,如果你的主对话生成了子智能体 A,A 又生成了一个深度为二的后台子智能体 B,那么当你直接从主对话恢复 B 时,它仍处于深度二。从一个更浅的上下文恢复某个子智能体,并不会让它获得深度限制已经阻止的额外层级。
要阻止某个特定子智能体生成其他子智能体,请从其tools 列表中省略 Agent,或将其加入 disallowedTools。
一个分叉仍然无法生成另一个分叉。它可以生成其他类型的子智能体,这些子智能体同样计入深度限制。
管理子智能体上下文
启动时加载的内容
每个子智能体都以全新、隔离的上下文窗口启动。它看不到你的对话历史、你已经调用过的技能,也看不到 Claude 已经读取过的文件。Claude 会撰写一条概括任务的委派消息,子智能体从那里开始工作。例外情况是分叉,它会继承父对话,而不是从零开始。
一个非分叉子智能体的初始上下文包含:
- 系统提示词:该智能体自己的提示词,加上 Claude Code 附加的环境详情,而不是完整的 Claude Code 系统提示词。自定义子智能体在markdown 正文或
prompt字段中定义自己的提示词。内置智能体拥有预定义的提示词。 - 任务消息:Claude 交接工作时撰写的委派提示词。
- CLAUDE.md 与记忆:主对话所加载的记忆层级中的每一级,包括
~/.claude/CLAUDE.md、项目规则、CLAUDE.local.md以及统一管理的策略文件。内置的 Explore 和 Plan 智能体会跳过这一项。 - Git 状态:在父会话开始时拍摄的一份快照。当工作目录不是 Git 仓库,或
includeGitInstructions为false时不存在。Explore 和 Plan 无论如何都会跳过它。 - 预加载的技能:该智能体
skills字段中命名的任何技能的完整内容。内置智能体不会预加载技能。
Explore 和 Plan 是唯二会省略 CLAUDE.md 和 git 状态的子智能体。没有任何 frontmatter 字段或按智能体的设置可以改变哪些智能体会跳过它们。
主对话是带着完整的 CLAUDE.md 上下文来阅读 Explore 和 Plan 的结果的,因此大多数规则不需要传达给子智能体本身。如果某条规则必须传达,例如“忽略 vendor/ 目录”,请在你委派给 Claude 的提示词中重新说明它。
恢复子智能体
每次调用子智能体都会创建一个带有全新上下文的新实例。要继续一个已有子智能体的工作,而不是从头开始,可以让 Claude 恢复它。
被恢复的子智能体会保留其完整的对话历史,包括之前的所有工具调用、结果和推理过程。该子智能体会准确地从中断处继续,而不是从零开始。
当一个子智能体完成时,Claude 会收到其智能体 ID。内置的 Explore 和 Plan 智能体是一次性的,不会返回智能体 ID,因此无法恢复;如果需要继续工作,请使用 general-purpose 或自定义子智能体。
Claude 会用 SendMessage 工具,以该智能体的 ID 或名称作为 to 字段来恢复它。SendMessage 不要求启用智能体团队;只有像 shutdown_request 和 plan_approval_response 这样的结构化团队协议消息才需要。
要恢复一个子智能体,可以让 Claude 继续之前的工作:
如果一个已停止的子智能体收到一条 SendMessage,它会在后台自动恢复,无需新的 Agent 调用。
恢复会在同一个 ID 下启动该智能体的一次新运行,因此一个已经失败或已完成的子智能体,会在任务列表和 Agent SDK 的任务事件中重新显示为正在运行。在 v2.1.205 之前,恢复的运行在工作期间,仍会继续显示其之前的失败或已完成状态。
从 v2.1.199 开始,SendMessage 会检查某个名称是否仍指向它在对话中先前接触到的同一个智能体。如果一个更新的智能体占用了该名称(例如一个被重新生成、并复用了该名称的后台智能体),Claude Code 会拒绝发送,而不是将其送到错误的智能体,错误信息会说明该名称现在指向哪个智能体,以便 Claude 重新定位目标。要在早先那个智能体仍在运行时联系到它,Claude 会用其生成结果中的智能体 ID 来寻址。这项检查限定于当前对话,并会在 /clear 时重置。
从 v2.1.198 开始,子智能体会把来自启动它的那个智能体的消息当作正常的任务指令来处理,包括任务中途的方向修正,并在自身的权限设置范围内对其采取行动。无论消息来自谁,以下两条限制始终有效:任何智能体发出的消息都不能算作你对待处理权限提示的批准;任何智能体消息都不能更改子智能体的权限设置、CLAUDE.md 或配置。只有权限系统本身或你自己发出的消息才能授予批准。
如果你想明确引用某个智能体 ID,也可以直接问 Claude,或者在 ~/.claude/projects/{project}/{sessionId}/subagents/ 的记录文件中查找。每份记录都以 agent-{agentId}.jsonl 的形式存储。
子智能体的记录独立于主对话持久保存:
- 主对话压缩:主对话压缩时,子智能体的记录不受影响。它们存储在独立的文件中。
- 会话持久化:子智能体的记录在其会话内持久保存。重启 Claude Code 后,你可以通过恢复同一个会话来恢复某个子智能体。
- 自动清理:记录会依据
cleanupPeriodDays设置进行清理,该设置默认为 30 天。
自动压缩
子智能体支持使用与主对话相同的逻辑进行自动压缩。压缩会在相同条件下触发,CLAUDE_AUTOCOMPACT_PCT_OVERRIDE 同样适用于子智能体。关于该覆盖何时生效,请参阅环境变量。
压缩事件会记录在子智能体的记录文件中:
preTokens 值显示压缩发生前使用了多少 Token。
分叉当前对话
分叉子智能体需要 Claude Code v2.1.117 或更高版本。从 v2.1.161 开始,/fork 命令默认启用;在更早的版本上,需要将 CLAUDE_CODE_FORK_SUBAGENT 环境变量设置为 1。让 Claude 自行生成分叉是实验性功能,未来版本中可能会变化。作为分阶段推出的一部分,该能力也可能在交互式会话中被启用。
分叉是一种继承目前为止整个对话、而非从零开始的子智能体。这会去掉子智能体通常提供的输入隔离:分叉能看到与主会话相同的系统提示词、工具、模型和消息历史,因此你可以把一个附属任务交给它,而不必重新解释情况。分叉自身的工具调用仍会留在你的对话之外,只有其最终结果会返回,因此你的主上下文窗口保持干净。当一个命名子智能体需要过多背景信息才能发挥作用时,或者你想从同一个起点并行尝试几种方案时,可以使用分叉。
要不受分阶段推出影响、自行控制分叉模式,可将 CLAUDE_CODE_FORK_SUBAGENT 设为 1 以显式启用,或设为 0 以禁用它。该变量在交互模式下,以及通过 SDK 或 claude -p 时都会生效。
启用分叉模式会以两种方式改变 Claude Code 的行为:
- Claude 可以通过明确请求
fork子智能体类型来生成一个分叉。未指定子智能体类型的生成仍使用general-purpose 子智能体,命名子智能体(例如 Explore)仍照常生成。 - 每次生成子智能体都会在后台运行,无论是分叉还是命名子智能体。将
CLAUDE_CODE_DISABLE_BACKGROUND_TASKS设为1可保持生成同步进行。
你可以自己用 /fork 加上一条指令来启动一个分叉,无论是否设置了该变量。Claude Code 会根据该指令的开头词语为分叉命名。以下示例分叉对话以起草测试用例,同时你在主会话中继续实现工作:
该分叉会出现在你的提示词下方的一个面板中,并在你继续工作的同时在后台运行。它完成后,其结果会作为一条消息出现在你的主对话中。下一节介绍在分叉运行期间用于观察和引导它们的面板控制。
观察和引导正在运行的分叉
正在运行的分叉会出现在提示输入框下方的一个面板中,主会话占一行,每个分叉各占一行。使用以下按键与面板交互:
| 按键 | 操作 |
|---|---|
↑ / ↓ | 在各行之间移动 |
Enter | 打开选中分叉的记录,并向其发送后续消息 |
x | 关闭一个已完成的分叉,或停止一个正在运行的分叉 |
Esc | 将焦点返回提示输入框 |
在打开某个分叉或子智能体的记录时,后续消息和技能会发给该智能体,但内置命令仍在你的主对话中运行。从 v2.1.199 开始,在该视图中输入 /model 或 /fast,会显示一条提示,说明这会更改主对话的模型或快速模式,而不是所查看智能体的,而不再是悄悄地执行它。
分叉与命名子智能体的区别
分叉会继承主会话在其生成那一刻拥有的一切。命名子智能体则从自己的定义开始。
| 分叉 | 命名子智能体 | |
|---|---|---|
| 上下文 | 完整对话历史 | 使用你传入提示词的全新上下文 |
| 系统提示词和工具 | 与主会话相同 | 来自该子智能体的定义文件 |
| 模型 | 与主会话相同 | 来自该子智能体的 model 字段 |
| 权限 | 提示会浮现在你的终端中 | 在后台运行时,提示会浮现在你的主会话中 |
| Prompt 缓存 | 与主会话共享 | 独立缓存 |
由于分叉的系统提示词和工具定义与父级完全相同,它的第一次请求会复用父级的prompt 缓存。这使得对于需要相同上下文的任务,分叉比生成一个全新子智能体更省钱。
当 Claude 通过 Agent 工具生成一个分叉时,可以传入 isolation: "worktree",让该分叉的文件编辑写入一个独立的 git worktree,而不是你的检出内容。
限制
将 CLAUDE_CODE_FORK_SUBAGENT=1 会在交互式会话、非交互模式和 Agent SDK 中启用分叉模式;设为 0 则会在包括任何服务端推出的所有场景中禁用分叉模式。一个分叉无法再生成其他分叉。
子智能体示例
以下示例展示了构建子智能体的有效模式。可将它们作为起点,或让 Claude 生成一个定制版本。
代码审查者
一个只读的子智能体,用于审查代码而不修改它。这个示例展示了如何设计一个工具访问受限的专注子智能体(排除 Edit 和 Write),并配有一份详细的提示词,明确指出要查找什么以及如何格式化输出。
调试器
一个既能分析又能修复问题的子智能体。与代码审查者不同,这个子智能体包含 Edit,因为修复 bug 需要修改代码。该提示词提供了从诊断到验证的清晰工作流程。
数据科学家
一个用于数据分析工作的领域专属子智能体。这个示例展示了如何为典型编码任务之外的专门工作流创建子智能体。它显式设置了 model: sonnet,以获得更强的分析能力。
数据库查询校验器
一个允许 Bash 访问、但会校验命令、只允许只读 SQL 查询的子智能体。这个示例展示了当 tools 字段提供的控制力不够精细时,如何用 PreToolUse 钩子实现条件校验。
Claude Code 会以 JSON 形式将钩子输入通过 stdin 传给钩子命令。该校验脚本会读取这份 JSON、提取正在执行的命令,并将其与一份 SQL 写操作列表进行比对。如果检测到写操作,该脚本会以退出码 2 退出以阻止执行,并通过 stderr 向 Claude 返回一条错误消息。
在你的项目中任意位置创建该校验脚本。路径必须与你钩子配置中的 command 字段一致:
在 macOS 和 Linux 上,将该脚本设为可执行:
在 Windows 上,请用 PowerShell 编写校验脚本,并在钩子条目中加入 shell: powershell。请参阅在 PowerShell 中运行钩子。
该钩子会通过 stdin 接收 JSON,Bash 命令位于 tool_input.command 中。退出码 2 会阻止该操作,并将错误消息反馈给 Claude。关于退出码的详情请参阅钩子,关于完整的输入模式请参阅钩子输入。
后续步骤
既然你已经理解了子智能体,可以进一步探索以下相关功能:
- 用插件分发子智能体,跨团队或项目共享子智能体
- 用 Agent SDK 以编程方式运行 Claude Code,用于 CI/CD 和自动化
- 使用 MCP 服务器,让子智能体访问外部工具和数据