agents 参数在 SDK 中定义和使用子代理。
概述
您可以通过三种方式创建子代理:- 以编程方式:在您的
query()选项中使用agents参数。请参阅 TypeScript 和 Python 参考文档 - 基于文件系统:在
.claude/agents/目录中将代理定义为 markdown 文件。请参阅将子代理定义为文件 - 内置通用代理:Claude 可以随时通过 Agent 工具调用内置的
general-purpose子代理,无需您定义任何内容
description 字段确定是否调用它。编写清晰的描述,说明何时应使用子代理,Claude 将自动委派适当的任务。您也可以在提示词中按名称显式请求子代理,例如”使用代码审查员代理来…”。
使用子代理的好处
上下文隔离
每个子代理在其自己的新对话中运行。中间工具调用和结果保留在子代理内部;只有其最终消息返回到父代理。请参阅子代理继承的内容以了解子代理上下文中的确切内容。 示例:research-assistant 子代理可以探索数十个文件,而这些内容都不会在主对话中累积。父代理收到的是简洁的摘要,而不是子代理读取的每个文件。
并行化
多个子代理可以并发运行,因此独立的子任务完成时间为最慢的一个,而不是所有任务的总和。 示例: 在代码审查期间,您可以同时运行style-checker、security-scanner 和 test-coverage 子代理,而不是按顺序运行。
专门的指令和知识
每个子代理都可以有定制的系统提示词,具有特定的专业知识、最佳实践和约束。 示例:database-migration 子代理可以具有关于 SQL 最佳实践、回滚策略和数据完整性检查的详细知识,这些在主代理的指令中将是不必要的噪音。
工具限制
子代理可以限制为特定工具,降低意外操作的风险。 示例:doc-reviewer 子代理可能只能访问 Read 和 Grep 工具,确保它可以分析但永远不会意外修改您的文档文件。
创建子代理
以编程方式定义(推荐)
使用agents 参数直接在代码中定义子代理。Claude 通过 Agent 工具调用子代理,因此在 allowedTools 中包含 Agent 以自动批准子代理调用,无需权限提示。
本页面上的大多数示例仅打印最终结果。要确认 Claude 委派给了子代理而不是直接回答,请参阅检测子代理调用。
此示例创建两个子代理:一个具有只读访问权限的代码审查员和一个可以执行命令的测试运行器。
AgentDefinition 配置
在 Python SDK 中,多字词字段名称(如
disallowedTools 和 mcpServers)保持其 camelCase 拼写以匹配线路格式,而不是遵循 Python 的 snake_case 约定。有关详细信息,请参阅 AgentDefinition 参考。
Claude Code v2.1.198 中的两个子代理行为发生了变化:
- 子代理默认在后台运行。省略
run_in_background输入的 Agent 工具调用会启动后台子代理,当 Claude 需要结果后才继续时,它会设置run_in_background: false。在 v2.1.198 之前,省略run_in_background会同步运行子代理。设置background字段为true以强制特定代理进行后台执行,无论 Claude 请求什么。 - 子代理继承主会话的扩展思考配置。在早期版本中,无论主会话的设置如何,扩展思考在子代理内被禁用。
自 Claude Code v2.1.172 起,子代理可以生成自己的子代理。位于主代理下方五个级别的子代理无法生成进一步的子代理,无论其是在前台还是后台运行。要防止子代理生成其他子代理,请从其
tools 数组中省略 Agent 或将其添加到 disallowedTools。有关完整的深度规则,请参阅嵌套子代理。基于文件系统的定义(替代方案)
您也可以在.claude/agents/ 目录中将子代理定义为 markdown 文件。有关此方法的详细信息,请参阅 Claude Code 子代理文档。以编程方式定义的代理优先于具有相同名称的基于文件系统的代理。
即使不定义自定义子代理,Claude 也可以生成内置的
general-purpose 子代理。这对于委派研究或探索任务而无需创建专门的代理很有用。在 allowedTools 中包含 Agent 以便这些调用自动批准,无需权限提示。子代理继承的内容
子代理的上下文窗口从新开始,没有父对话,但不是空的。从父代理到子代理的唯一内容是 Agent 工具的提示词字符串,因此请直接在该提示词中包含子代理需要的任何文件路径、错误消息或决策。 具有SendMessage 工具的子代理会从会话中运行的其他命名代理列表开始,因此它知道可以向哪些名称发送消息。Claude Code 会自动在子代理的第一轮中添加该列表。fork 不会获得该列表,因为它继承了父对话。该列表需要 Claude Code v2.1.206 或更高版本。
父代理逐字接收子代理的最终消息作为 Agent 工具结果,但可能在其自己的响应中总结它。要在面向用户的响应中逐字保留子代理输出,请在您传递给主
query() 调用的提示词或 systemPrompt 选项中包含一条指令。Agent terminated early due to an API error,后跟错误详情。有关前台和后台行为,请参阅 API errors in subagents。
这种部分输出处理需要 Claude Code v2.1.199 或更高版本。在 v2.1.199 中,速率限制、过载或服务器错误会导致仅工具调用的形状出现空的部分结果,仅包含中断注记。
调用子代理
自动调用
Claude 根据任务和每个子代理的description 自动决定何时调用子代理。例如,如果您定义了一个 performance-optimizer 子代理,其描述为”用于查询调优的性能优化专家”,当您的提示词提到优化查询时,Claude 将调用它。
编写清晰、具体的描述,以便 Claude 可以将任务匹配到正确的子代理。
显式调用
要保证 Claude 使用特定的子代理,请在您的提示词中按名称提及它:动态代理配置
您可以根据运行时条件动态创建代理定义。此示例创建一个安全审查员,具有不同的严格级别,对严格审查使用更强大的模型。检测子代理调用
Claude 通过 Agent 工具调用子代理。要检测何时调用子代理,请检查tool_use 块,其中 name 是 "Agent"。来自子代理上下文内的消息包含 parent_tool_use_id 字段。
工具名称在 Claude Code v2.1.63 中从
"Task" 重命名为 "Agent"。当前 SDK 版本在 tool_use 块中发出 "Agent",但在 system:init 工具列表和 result.permission_denials[].tool_name 中仍使用 "Task"。检查 block.name 中的两个值可确保跨 SDK 版本的兼容性。message.content 访问。在 TypeScript 中,SDKAssistantMessage 包装 Claude API 消息,因此内容通过 message.message.content 访问。
此示例遍历流式消息,记录何时调用子代理以及后续消息何时源自该子代理的执行上下文。
恢复子代理
您可以恢复子代理以继续中断的地方,而不是重新开始。恢复的子代理保留其完整的对话历史,包括所有先前的工具调用、结果和推理。 当子代理完成时,Agent 工具结果包含一个包含agentId: <id> 的文本块。内置的 Explore 和 Plan 代理 是一次性的,不返回 agentId,因此当您需要恢复时,请使用自定义代理或 general-purpose。要以编程方式恢复子代理:
- 捕获会话 ID:在第一个查询期间从消息中提取
session_id - 提取代理 ID:从 Agent 工具结果文本中解析
agentId - 恢复会话:在第二个查询的选项中传递
resume: sessionId,并在您的提示词中包含代理 ID
您必须恢复同一会话以访问子代理的记录。默认情况下,每个
query() 调用都会启动一个新会话,因此请传递 resume: sessionId 以在同一会话中继续。使用自定义代理时,在两个查询的 agents 参数中传递相同的代理定义。endpoint-finder 代理。第一个查询运行它并从 Agent 工具结果中捕获会话 ID 和代理 ID,然后第二个查询恢复会话以提出需要来自第一个分析的上下文的后续问题。
- 主对话压缩:当主对话压缩时,子代理记录不受影响。它们存储在单独的文件中。
- 会话持久性:子代理记录在其会话内持久存在。您可以通过恢复同一会话在重启 Claude Code 后恢复子代理。
- 自动清理:记录根据
cleanupPeriodDays设置进行清理,默认为 30 天。
工具限制
子代理可以通过tools 字段具有受限的工具访问:
- 省略该字段:代理继承所有可用工具(默认)
- 指定工具:代理只能使用列出的工具
常见工具组合
使用动态工作流进行扩展
子代理适用于每轮委派的几个任务。对于协调数十到数百个代理的运行,请使用Workflow 工具,它将编排移到运行时在对话上下文外执行的脚本中。请参阅动态工作流以了解工作流与逐轮子代理委派的区别。
Workflow 工具在 TypeScript Agent SDK v0.3.149 及更高版本中可用。在 allowedTools 中包含 Workflow 以自动批准工作流运行。工具输入和输出架构列在 TypeScript 参考中。
故障排除
Claude 不委派给子代理
如果 Claude 直接完成任务而不是委派给您的子代理:- 检查 Agent 调用是否被批准:在
allowedTools中包含Agent以自动批准子代理调用。如果没有它,Agent 调用将转到您的canUseTool回调,或在dontAsk模式下被拒绝 - 使用显式提示:在您的提示词中按名称提及子代理,例如”使用代码审查员代理来…”
- 编写清晰的描述:准确解释何时应使用子代理,以便 Claude 可以适当地匹配任务
基于文件系统的代理未加载
Claude Code 监视~/.claude/agents/ 和 .claude/agents/,并在几秒内拾取新的或编辑的代理文件,无需重启。如果定义从未出现,请排查这些原因:
- 新的
agents目录:监视程序仅覆盖会话启动时存在的目录,因此新目录中的第一个文件需要会话重启。这是最常见的原因。 - 无效的 frontmatter 或重复的
name:检查文件的 YAML,以及现有代理是否已使用该name。 --disable-slash-commands:使用此标志启动的会话不监视这些目录,始终需要重启以加载新文件。- 具有相同名称的程序化代理:传递给
query()的agents会覆盖具有相同名称的文件系统代理。
Windows 上的长提示词失败
在 Windows 上,具有非常长提示词的子代理可能因命令行长度限制(8191 个字符)而失败。保持提示词简洁或使用基于文件系统的代理来处理复杂指令。相关文档
- Claude Code 子代理:包括基于文件系统的定义的全面子代理文档
- 动态工作流:从脚本编排许多子代理,用于对话过大的工作
- SDK 概述:Claude Agent SDK 入门