多智能体编排
当你的任务超出单个上下文窗口的容量时,你有两个选择:对抗限制,或者分配工作。多智能体编排就是你分配工作的方式。
Subagent 的架构
Subagent 是 Claude Code 中会话内的会话。它拥有自己的上下文窗口、自己的系统提示和受限的工具集。当它完成时,它会将摘要返回给父会话。然后它的上下文窗口被丢弃。
关键约束:subagent 不能生成其他 subagent。这创建了一个严格的两级层次结构。你有一个编排者(你的主会话)和工作者(subagent)。没有中间管理层,没有委托链,没有递归的智能体树。这是一个深思熟虑的设计决策,而不是限制。递归的智能体层次结构听起来很优雅,但会产生混乱。
Claude Code 内置了六种 subagent 类型:
Explore subagent 运行在更小、更便宜的模型上,针对速度进行了优化。它们是只读的——可以搜索文件、读取代码和浏览代码库,但不能修改任何内容。当你在决定做什么之前需要先了解某些内容时使用它们。它们足够快速和便宜,可以随意启动。
Plan subagent 继承主会话的模型。它们也是只读的,但它们将编排者模型的完整推理能力用于研究和规划任务。当规划本身足够复杂以至于需要专门的上下文时使用它们。
General-purpose subagent 可以访问所有工具。它们可以读取、写入、执行命令和执行多步骤任务。这些是你实现任务的主力军。
Bash subagent 专门用于命令执行。当你需要运行一系列 shell 命令而又不想用冗长的输出污染主上下文时,它们很有用。
Claude Code Guide subagent 专门用于回答关于 Claude Code 本身的问题——它的功能、配置和最佳实践。它们查阅产品自己的文档。
Statusline-setup subagent 处理配置终端状态栏集成这一狭窄任务。它们之所以存在,是因为设置过程足够繁琐,值得使用隔离的上下文。
你还可以将自定义 subagent 定义为带有 YAML frontmatter 的 Markdown 文件,指定系统提示、工具限制、模型偏好和轮次限制。这些定义存放在 .claude/agents/ 中(项目范围)或 ~/.claude/agents/ 中(用户范围)。插件也可以提供它们,但优先级最低。
自定义 Subagent 定义字段
除了系统提示和工具限制的基本配置之外,自定义 subagent 定义还支持几个以重要方式影响行为的字段:
maxTurns 限制 subagent 停止之前的智能体轮次数量。这是一个安全阀。一个探索代码库的 subagent 可能会陷入越来越离题的搜索中。设置 maxTurns: 20 可以限制探索并强制产出结果。没有它,走上死胡同的 subagent 会消耗 token 直到上下文耗尽。
mcpServers 配置特定 subagent 可以使用哪些 MCP 服务器。你可以通过名称引用 .mcp.json 中定义的服务器,或者内联完整的服务器配置。这意味着一个 database-reader subagent 可以访问你的数据库 MCP 服务器,而一个 code-reviewer subagent 则没有任何访问权限。工具访问范围限定在 subagent 的角色内,而不是会话的完整功能集。
skills 在启动时将 skill 内容预加载到 subagent 的上下文中。在主会话中,skills 按需加载——只有描述存在,直到 Claude 调用该 skill。Subagent 的工作方式不同。传递给 subagent 的 skills 在启动时完全注入其上下文,因为 subagent 需要立即行动,而没有交互式 skill 加载流程。这意味着你预加载的每个 skill 从第一轮开始就消耗上下文。
memory 启用持久记忆,本章后面将详细介绍。
--agents CLI 标志
对于快速测试或 CI 自动化,你可以在启动 Claude Code 时直接以 JSON 格式传递 subagent 定义,而无需编写 Markdown 文件:
claude --agents '{
"code-reviewer": {
"description": "Reviews code for style and correctness",
"prompt": "You are a code reviewer. Check for bugs, style violations, and security issues.",
"tools": ["Read", "Glob", "Grep"],
"model": "sonnet"
},
"debugger": {
"description": "Debugs failing tests",
"prompt": "You are a debugging specialist. Analyze test failures and suggest fixes.",
"tools": ["Read", "Glob", "Grep", "Bash"],
"model": "sonnet",
"maxTurns": 30
}
}'
--agents 标志接受与基于文件的定义相同的字段:description、prompt、tools、disallowedTools、model、permissionMode、mcpServers、hooks、maxTurns、skills 和 memory。这在无头管线中特别有用,你可以在不向仓库提交 Markdown 文件的情况下定义专门的智能体。
--agent 标志
一个相关但不同的标志:--agent 将自定义智能体定义作为主线程而非 subagent 运行。如果你在 .claude/agents/code-reviewer.md 中定义了一个 code-reviewer 智能体,运行 claude --agent code-reviewer 会使用该智能体的系统提示、工具和配置启动会话。该会话作为顶级智能体运行,而不是另一个会话中的工作者。你可以使用 Task(agent_type) 语法限制此顶级智能体可以生成哪些 subagent,创建受控的层次结构,其中审查智能体只能委托给探索型 subagent。
Context Isolation 才是关键
Subagent 给你的最重要的东西不是并行性,而是 context isolation。
当你让主会话读取一个大文件、解析冗长的测试输出或浏览庞大的目录树时,所有这些内容都会积累在主上下文窗口中。这样做足够多次,你就会达到第一章中描述的上限——指令被遗忘、工作被遗漏、质量下降。
Subagent 通过容纳混乱来解决这个问题。一个 subagent 可以读取五十个文件、解析一千行测试输出、浏览仓库中的每个目录,而主会话只看到摘要。冗余的中间工作留在 subagent 的上下文中,并在 subagent 完成时被丢弃。
这就是为什么经验丰富的用户即使在不需要并行性时,也会将消耗大量上下文的操作路由到 subagent。读取大型代码库模块?用 Subagent。运行全面的测试套件并分析失败?用 Subagent。在数百个文件中搜索使用模式?用 Subagent。目标是保持编排者的上下文精简,使其能够在数十个任务中有效协调而不会失去连贯性。
权衡在于摘要是会丢失信息的。返回详细结果的 subagent 会消耗与结果长度成比例的主上下文。如果你启动十个 subagent,每个返回一页发现,你的主窗口中就有十页结果。解决方案是指示 subagent 在返回时保持简洁——提供具体答案,而不是全面报告。
前台与后台执行
Subagent 可以在前台或后台运行,这种区别比看起来更重要。
前台 subagent 阻塞主对话。编排者等待它们完成后才继续。它们可以完全访问 MCP 工具,如果遇到困难可以提出澄清问题,并与权限系统无缝集成。当 subagent 的结果决定下一步操作时,使用前台执行。
后台 subagent 在主会话继续的同时并发运行。这是并行性真正发生的地方——你可以有多个后台 subagent 同时探索代码库的不同部分或实现不同的组件。但后台执行有限制:不能使用 MCP 工具,不能提出澄清问题,权限必须在启动前预先协商。如果后台 subagent 遇到需要人工批准但未预先批准的内容,它会自动拒绝并继续前进。
后台 subagent 如果完成时仍有未解决的问题或部分结果,可以在前台恢复。这对于作为后台探索开始但发现了需要交互讨论的内容的任务很有用。按 Ctrl+B 将正在运行的前台任务放到后台——它继续工作,而你重新获得主会话的控制权。如果后台 subagent 因缺少权限而失败,你可以在前台恢复它以使用交互式提示重试。
实际模式是:对于需要立即获得结果的任务使用前台执行,对于可以在你专注于其他事情时运行的任务使用后台执行。一个常见的编排工作流:启动三个后台 subagent 探索三个模块,在主会话中继续处理其他事情,然后在它们完成时查看结果。
恢复 Subagent
Subagent 的转录独立于主对话而持久保存。它们作为单独的文件存储在 ~/.claude/projects/{project}/{sessionId}/subagents/。当主对话压缩时,subagent 的转录不受影响。你可以通过恢复同一会话在重启 Claude Code 后恢复 subagent——让 Claude "continue that code review",它会从持久化的转录继续。
这种持久性意味着 subagent 的工作不会在主会话重置时丢失。一个花了二十分钟分析授权模块的 subagent 在磁盘上有其完整的转录。恢复时给它恢复了那个上下文,而无需重新做分析。
Subagent 自动压缩
Subagent 支持使用与主对话相同逻辑的自动压缩。默认情况下,自动压缩在约 95% 容量时触发。对于处理大量数据的 subagent——解析数千行测试输出、读取数十个文件——这意味着它们可以通过定期摘要和继续来处理超出其上下文窗口的内容。
将 CLAUDE_AUTOCOMPACT_PCT_OVERRIDE 设置为较低的百分比(例如 50)以更早触发压缩。这适用于主对话和 subagent。更早的压缩减少了峰值上下文消耗,代价是可能丢失早期轮次的细节。对于进行广泛探索的 subagent,更早的压缩通常是可以的。对于进行精确分析且每个细节都很重要的 subagent,让它们在压缩前运行到接近容量上限。
Subagent Hooks
自定义 subagent 支持在执行期间的特定点运行的生命周期 hooks。这些在智能体的 YAML frontmatter 中定义,使用与会话级 hooks 相同的事件模型(第二章),但作用范围限定在 subagent。
三个 hook 事件在 subagent 的执行中触发:PreToolUse 在 subagent 使用工具之前运行,可以阻止或修改调用。PostToolUse 在工具完成后运行,可以转换输出或触发副作用。Stop 在 subagent 完成时运行——但在运行时,它会自动转换为 SubagentStop 事件。
另外两个 hook 事件在项目级别触发,在 subagent 自身的上下文之外:SubagentStart 在任何 subagent 生成时触发,SubagentStop 在任何 subagent 完成时触发。这些在你的项目或用户设置中定义,而不是在 subagent 定义本身中。SubagentStart hook 可以向 subagent 注入 additionalContext——补充其系统提示的指令或数据,而无需修改智能体定义。SubagentStop hook 可以阻止 subagent 停止(退出代码 2),这对于强制 subagent 在被允许完成之前必须产出特定产物很有用。
一个实际示例:一个 database-reader subagent,带有 Bash 工具上的 PreToolUse hook,该 hook 检查命令是否包含 SQL 写操作(INSERT、UPDATE、DELETE、DROP)。如果 hook 检测到写语句,它返回一个拒绝决定,阻止 subagent 修改生产数据,无论其指令说了什么。这是纵深防御——subagent 的系统提示说"只读",而 hook 在机制上强制执行这一点。
Subagent 模式
三种模式在生产环境的 subagent 使用中反复出现。它们值得命名,因为它们解决了特定的编排问题。
链式 subagent 顺序运行,每个 subagent 完成其任务并将结果返回给编排者,编排者然后将相关信息传递给下一个 subagent。Subagent A 分析认证模块并返回漏洞列表。编排者将该列表传递给 Subagent B,后者生成修复方案。Subagent B 的输出传递给 Subagent C,后者编写测试。每个 subagent 拥有干净的上下文,只包含它需要的信息。链式结构在保持信息流的同时防止了上下文积累。
隔离高量操作,通过将产生大量输出的任何操作路由到 subagent。运行全面的测试套件可能会产生数千行输出。从 API 获取文档可能返回数百页。处理日志文件可能涉及扫描数兆字节的文本。如果这发生在主会话中,它会挤占其他所有内容。Subagent 吸收这些量并返回简洁的摘要:"14 个测试失败,全部在 auth 模块中,全部与会话过期相关。"
并行研究 同时启动多个 subagent 来调查问题的不同方面。三个 subagent 并行探索认证模块、数据库层和 API 端点。每个返回发现。编排者将它们综合成统一的理解。这比顺序探索更快,并使编排者的上下文不受中间探索步骤的影响。
Agent Teams:实验性层
Agent Teams 是完全不同的架构。Subagent 是会话中的工作者,而 Agent Teams 是通过共享基础设施协调的独立 Claude Code 会话。
启用 Agent Teams
Agent Teams 默认禁用。通过将 CLAUDE_CODE_EXPERIMENTAL_AGENT_TEAMS 环境变量设置为 1 来启用,可以在 shell 中设置,也可以通过 settings 设置:
{
"env": {
"CLAUDE_CODE_EXPERIMENTAL_AGENT_TEAMS": "1"
}
}
然后用自然语言描述你想要什么。Claude 创建团队、生成队友,并根据你的提示协调工作。
七个团队原语
系统提供七个工具来处理团队协调的完整生命周期。
TeamCreate 初始化团队。它在磁盘上创建团队目录和配置文件。team_name 参数是连接一切的命名空间——任务、消息和配置都存在于其下。
TeamCreate({ "team_name": "auth-refactor", "description": "Refactor authentication module" })
TaskCreate 定义一个工作单元。每个任务成为磁盘上的一个 JSON 文件。Lead 在生成队友之前创建任务,在描述中提供足够的细节,以作为接手该任务的智能体的提示。
TaskCreate({
"subject": "Extract JWT handling into jwt.ts",
"description": "Move all token signing and verification logic from auth.ts to a new jwt.ts module...",
"team_name": "auth-refactor"
})
TaskUpdate 推动工作在管线中前进。队友使用它来认领任务(将状态设置为 in_progress 并指定 owner)和标记任务完成。status 字段防止两个智能体同时处理同一任务。
TaskUpdate({ "taskId": "1", "status": "in_progress", "owner": "jwt-agent" })
TaskUpdate({ "taskId": "1", "status": "completed" })
TaskList 返回所有任务及其当前状态。队友在完成一个任务后调用此工具查找下一步工作。没有集中调度器——每个队友轮询 TaskList,找到未认领的待处理任务,并认领一个。这是共享协调机制。
Task(带 team_name) 生成一个队友。关键细节:每个队友是一个拥有自己上下文窗口的完整 Claude Code 会话。队友加载相同的项目上下文(CLAUDE.md、MCP 服务器、skills),但不继承 Lead 的对话历史。你可以为每个队友独立指定模型。
Task({
"subagent_type": "general-purpose",
"name": "jwt-agent",
"team_name": "auth-refactor",
"model": "sonnet"
})
SendMessage 是使团队区别于 subagent 的关键。任何队友都可以直接向任何其他队友发送消息。它支持四种消息类型:
- message:两个智能体之间的直接通信。一个队友向 lead 报告发现,或者一个队友向另一个队友询问信息。
- broadcast:一次到达所有队友。谨慎使用——成本随团队规模扩展,因为每个队友都要处理消息。
- shutdown_request / shutdown_response:优雅关闭协议。Lead 发送关闭请求;队友以响应确认。如果队友有未完成的工作,可以附带解释拒绝关闭。
- plan_approval_response:质量门。Lead 批准或拒绝队友的实施计划。
// Teammate reports findings to lead
SendMessage({
"type": "message",
"recipient": "lead",
"content": "JWT extraction complete. Created jwt.ts with signToken and verifyToken exports."
})
// Lead requests graceful shutdown
SendMessage({
"type": "shutdown_request",
"recipient": "jwt-agent",
"content": "All tasks complete, shutting down team."
})
TeamDelete 从磁盘中删除团队配置和所有任务文件。在所有队友关闭后调用。
Team Lead 抽象
使 Agent Teams 不仅仅是并行 subagent 的,是 team lead 的协调角色。Lead 是创建团队的会话。它负责创建任务和定义工作分解、以适当角色生成队友、通过任务列表监控进度、综合多个智能体的结果,以及处理优雅关闭。
磁盘上的任务文件和 SendMessage 是唯一的协调渠道——没有共享内存。队友各自拥有自己的对话历史和上下文窗口,独立于 Lead 和彼此。这种独立性既是架构优势(具有完整 context isolation 的真正并行工作)的来源,也是其成本(每个队友是一个独立消耗 token 的完整 Claude Code 会话)的来源。
Lead 可以被置入委托模式(启动团队后按 Shift+Tab)。在委托模式下,Lead 不能自己执行任务——它只能协调:生成、消息、关闭队友和管理任务。这防止了 Lead 做本应分配给队友的工作,这是一个出奇常见的失败模式。
显示模式
Agent Teams 支持三种显示模式,通过 teammateMode 设置或 --teammate-mode 标志配置:
auto(默认)如果你已经在 tmux 会话中运行,则使用分屏面板,否则使用进程内模式。
in-process 在主终端内运行所有队友。使用 Shift+Up/Down 选择队友并直接输入消息给他们。按 Enter 查看队友的会话,按 Escape 中断他们当前轮次,按 Ctrl+T 切换任务列表。在任何终端中工作,无需额外设置。
tmux 给每个队友自己的终端面板。你可以同时看到所有人的输出并点击面板直接交互。分屏模式需要 tmux 或 iTerm2——它不能在代码编辑器的集成终端中工作。
# Force in-process for a single session
claude --teammate-mode in-process
任务依赖和文件锁
任务可以依赖于其他任务。具有未解决依赖关系的待处理任务在依赖完成之前不能被认领。当队友完成其他任务所依赖的任务时,被阻塞的任务会自动解除阻塞。这创建了自然的波浪模式:独立任务首先并行运行,依赖任务随后跟进。
任务认领使用文件锁来防止多个队友同时尝试认领同一任务时的竞争条件。没有文件锁,两个同时轮询 TaskList 的智能体可能都试图认领同一任务,导致重复工作。锁确保每个任务恰好被一个智能体拥有。
计划审批
对于复杂或有风险的任务,你可以要求队友在实施之前先做计划。队友在只读计划模式下工作,直到 Lead 批准他们的方法:
生成一个架构师队友来重构认证模块。在做出任何更改之前要求计划审批。
当队友完成计划时,它会向 Lead 发送计划审批请求。Lead 审查计划并批准它(队友退出计划模式并开始实施)或带反馈拒绝它(队友留在计划模式,修订并重新提交)。你可以通过在提示中给出标准来影响 Lead 的判断:"只批准包含测试覆盖的计划"或"拒绝修改数据库 schema 的计划。"
这就是"信任智能体做正确的事"和"在花费 token 进行实施之前验证方法"之间的区别。对于一个五个智能体并行运行的团队,每分钟消耗数千 token,计划审批步骤是廉价的保险。
团队 Hook 事件
两个 hook 事件专门用于 Agent Teams:
TeammateIdle 在 Agent Teams 的队友即将空闲时触发——它已完成当前工作并准备停止。此 hook 的退出代码 2 强制队友继续工作。一个实际用途:一个 hook 在允许队友停止之前检查构建产物是否存在于预期的输出目录中。如果产物缺失,hook 拒绝空闲状态,队友继续工作。
TaskCompleted 在通过 TaskUpdate 将任务标记为完成时触发,或者当队友完成其轮次但仍有进行中的任务分配时触发。退出代码 2 阻止完成。这实现了质量门:一个 hook 在任务标记完成时运行测试套件,如果测试失败则阻止完成。队友看到失败输出并可以自我纠正。
Agent Teams 与 Subagent:详细对比
| Subagent | Agent Teams | |
|---|---|---|
| 上下文 | 自有窗口;结果返回给调用者 | 自有窗口;完全独立 |
| 通信 | 仅向主智能体报告结果 | 队友之间直接消息 |
| 协调 | 主智能体管理所有工作 | 共享任务列表,自我认领 |
| Token 成本 | 较低:结果摘要返回主会话 | 较高:每个队友是一个完整会话 |
| 最佳用途 | 只关心结果的聚焦任务 | 需要讨论和协作的复杂工作 |
当智能体需要彼此对话时,这种区别最为重要。一个完成类型定义并直接消息 UI 队友开始集成工作的 API 队友——这就是 Agent Teams 模式。如果每个工作者只是向编排者报告,subagent 更便宜也更简单。
局限性
Agent Teams 是实验性的,带有实际约束:
- 进程内队友没有会话恢复。如果队友崩溃,其工作和上下文将丢失。
- 任务状态可能滞后——队友有时忘记将任务标记为完成,这可能阻塞依赖任务。
- 每个会话一个团队。 你不能从一个 Lead 会话运行嵌套团队或多个团队。
- 分屏面板需要 tmux 或 iTerm2,不能是代码编辑器的集成终端。
- 所有队友以 Lead 的权限设置启动。 你不能给一个队友比 Lead 更广泛的权限。
Subagent 与 Teams:何时使用哪种
在 subagent 和 teams 之间的选择映射到范围、成本和协调复杂性。
Subagent 适用于以下情况:工作可以分解为无需协调即可完成的独立任务,每个任务适合单个 subagent 会话,并且你需要快速且廉价地获得结果。典型的 subagent 工作流耗时几分钟,成本只是主会话的一小部分。
Teams 适用于以下情况:工作需要专家之间的持续协调,任务具有需要跟踪的依赖关系,或者问题需要不同智能体维护关于系统不同方面的长期上下文。典型的团队工作流耗时更长,成本是 subagent 的数倍。
两者都不适用,当一个良好提示的单个会话可以处理任务时。这比你想象的更常见。在寻求多智能体编排之前,先问任务是否真正超出了单个上下文窗口的处理能力。如果答案是否定的,一个带有清晰指令的单智能体每次都会胜过多智能体设置。多智能体系统的协调开销不是免费的,而且它引入了单智能体所没有的失败模式。
偏好的层次:单智能体优先,需要 context isolation 时用 subagent,需要持续协调时用 teams。从下往上,而不是从上往下。
Agent Teams 案例研究
QA 集群
一位实践者用单个提示将 Agent Teams 指向他们的博客:使用一组智能体团队在生产部署前对博客进行 QA。Lead 创建了五个任务并生成了五个并行智能体,每个运行在更便宜的模型上:
| # | 任务 | 智能体 | 检查内容 |
|---|---|---|---|
| 1 | 核心页面响应 | qa-pages | 16 个 URL 的正确 HTTP 状态码 |
| 2 | 博客文章渲染 | qa-posts | 83 篇文章的标题、meta 标签、可用图片 |
| 3 | 导航和链接完整性 | qa-links | 146 个内部 URL 的断链检查 |
| 4 | RSS、站点地图、SEO 元数据 | qa-seo | RSS 有效性、robots.txt、Open Graph 标签 |
| 5 | 可访问性和 HTML 结构 | qa-a11y | 标题层级、ARIA 属性、主题切换 |
每个智能体独立完成并通过 SendMessage 发回结构化报告。智能体使用 bash 和 curl 获取页面并直接解析 HTML——没有浏览器自动化,没有测试框架。当所有五个完成时,Lead 将它们的发现综合成按严重程度排序的优先报告(主要、中等、次要)。然后 Lead 发送关闭请求,队友确认,TeamDelete 清理。
整个生命周期——从提示到最终报告——花了大约三分钟。五个智能体,超过 146 个 URL 被测试,83 篇博客文章被检查。成本比单个会话顺序执行相同工作更高,但挂钟时间只是一小部分。
认证模块重构
一个更依赖协调的示例:重构认证模块,一个队友负责 API 层,一个负责前端组件,一个持续运行测试。与 subagent 的关键区别:API 队友完成类型定义后直接消息 UI 队友说"接口准备好了,这是变更内容。"测试队友可以请求 API 队友启动开发服务器。自我协调,无需通过 Lead 路由每个交互。
这是 Agent Teams 证明其成本的模式的场景。智能体需要实时对彼此的工作做出反应。使用 subagent,编排者将成为瓶颈——每个工作者向父级报告,父级转达给下一个工作者,周而复始。使用团队,工作者直接对话。
先计划,后并行
最有效的 Agent Teams 模式是两步方法:先用计划模式规划,然后将计划交给团队并行执行。
第一步:在计划模式下启动。让编排者探索代码库、识别文件并产生逐步实施计划。审查它。调整它。这很便宜——计划模式只读取文件。编排者可能产生类似如下的内容:
Plan:
1. Create src/auth/jwt.ts -- extract token signing/verification
2. Create src/auth/sessions.ts -- extract session logic
3. Create src/auth/middleware.ts -- extract Express middleware
4. Update src/auth/index.ts -- re-export public API
5. Update 12 import sites across the codebase
6. Update tests in src/auth/__tests__/
第二步:作为团队执行计划。计划已经有了任务分解。Lead 看到依赖图并分波生成队友:
- 第一波(并行):jwt.ts + sessions.ts + middleware.ts——三个队友
- 第二波(第一波之后):index.ts 桶文件 + 更新导入——一到两个队友
- 第三波(第二波之后):更新测试——一个队友
计划模式大约花费 10,000 个 token。一个走向错误方向的团队花费 500,000 或更多。在提交并行执行之前花几秒钟审查计划,可以避免在集群中途进行昂贵的路线修正。
持久记忆
Subagent 可以维护跨会话存活的持久记忆目录。通过智能体定义中的 memory 字段配置,指定一个范围:
- user:跨所有项目共享。存储在
~/.claude/agent-memory/{agent-name}/。用于知识在各处都适用的智能体——编码风格偏好、常见调试模式、个人工作流规则。 - project:在项目内共享。存储在
~/.claude/projects/{project}/agent-memory/{agent-name}/。用于项目特定的智能体——一个学习此代码库约定的代码审查器,一个了解此项目测试模式的测试智能体。 - local:特定于一个工作目录。当同一项目的不同分支或 worktree 需要不同的智能体知识时使用。
记忆目录包含一个 MEMORY.md 入口点和可选的主题文件:
~/.claude/projects/{project}/agent-memory/code-reviewer/
├── MEMORY.md # Concise index, loaded into every session
├── style-patterns.md # Detailed notes on code style observations
└── common-issues.md # Recurring problems this codebase has
MEMORY.md 作为索引。前 200 行在每次调用开始时加载到 subagent 的系统提示中。超过 200 行的内容不会自动加载——Claude 被指示通过将详细笔记移到单独的主题文件中来保持索引简洁。Subagent 在其整个执行过程中读取和写入此目录中的文件,使用 MEMORY.md 跟踪存储了什么以及在哪里。
在多次调用中,subagent 积累知识:它观察到的模式、有效的决策、需要避免的错误。一个学习你团队约定的代码审查智能体在十次运行后比一次运行后产生更好的审查。一个记住哪些测试模式捕获了真实 bug 的测试生成智能体专注于高价值测试用例。
这与 CLAUDE.md 不同,后者是主会话的始终在线上下文(第三章)。持久记忆是智能体特定的,只在该智能体运行时加载。这是在不膨胀主会话上下文的情况下为专门智能体提供领域知识的方式。
基于向量的经验检索
一位构建自主交易系统的实践者走得比平面文件记忆更远。该系统将智能体经验存储在向量数据库中,当智能体遇到新情况时使用相似性搜索检索相关的过去场景。智能体不是将所有历史加载到上下文中,而是查询与当前市场条件相似的经验,并仅加载那些。
这种模式——对过去决策进行向量相似性搜索而非线性 MEMORY.md 文件——在积累经验量太大而无法用 200 行索引容纳时是相关的。一个做出数千决策的交易智能体不能将所有决策保存在摘要文件中。但向量数据库可以让它为任何新场景找到五个最相关的过去决策,这可以轻松地放入 subagent 的上下文中。
这种方法不限于交易。任何处理重复但多变任务的智能体——事件响应、跨多个仓库的代码审查、客户问题分类——都受益于随过去工作量扩展的经验检索。
成本优化:昂贵的大脑,廉价的双手
最具成本效益的多智能体模式在概念上很简单:使用昂贵、有能力的模型进行编排,使用便宜、快速的模型进行执行。
你的编排者——主会话——做规划、分解和质量评估。这是推理质量最重要的地方,所以它运行在可用的最有能力的模型上。你的 subagent 做实施、探索和粗活。它们中的许多可以运行在更小的模型上而没有有意义的质量损失。
Explore subagent 已经实现了这种模式,默认使用更小、更快的模型。你可以通过在智能体定义中指定模型偏好将其扩展到自定义智能体。
这种经济学成立是因为编排只占总 token 使用量的一小部分。规划一次重构可能消耗 10,000 个 token。在二十个文件中执行该重构可能消耗 500,000 个 token。如果执行运行在每个 token 成本仅为五分之一的模型上,你已将总成本削减了约 80%,而规划质量没有损失。
这映射到一个组织隐喻:一个设计系统的高级架构师和实现它的初级开发者。架构师的时间昂贵,他们的决策有杠杆效应。实现者的时间更便宜,他们的工作由架构师的计划指导。你不会以架构师的费率付钱让人写样板代码。也不要以编排者的 token 费率为 subagent 的粗活买单。
计划优先的并行化
多智能体编排中代价最高的错误是在制定计划之前启动并行智能体。
没有计划,每个智能体独立地解释目标。它们做出不同的假设。它们编写冲突的代码。它们以不兼容的方式解决重叠的问题。然后你花在解决冲突上的时间比通过并行化节省的时间还多。这不是理论上的担忧——这是幼稚并行化的默认结果。
计划优先模式几乎不花费成本就能防止这种情况。编排者花费大约 10,000 个 token 创建详细计划:每个智能体将做什么,每个智能体拥有哪些文件,它们需要遵守什么接口,集成点是什么。然后,也只有然后,它才将任务交给智能体进行并行执行。
这种前期规划投资与执行成本相比微不足道。一个十智能体团队运行一小时可能消耗数十万 token。规划阶段可以忽略不计。但它将执行从混乱的集群转变为协调的努力。
计划应该指定:任务边界(哪个智能体拥有哪些文件)、接口契约(哪些函数/API 必须兼容)、依赖顺序(什么必须在什么之前完成)和验收标准(每个智能体如何知道自己完成了)。拥有这种前置结构的智能体产生兼容的代码。没有的智能体产生合并冲突。
治理故事:成功、失败与简化
这是一个真实多智能体系统的完整弧线,分三幕讲述。它从成功开始,跌入失败,并得出关于简单性的教训。
第一幕:治理拯救了资本
一位运行自主交易实验的实践者构建了一个具有专门角色的多智能体治理系统:一个用于战略决策的 CEO 智能体,一个用于风险分析的顾问智能体,一个用于实施的工程师智能体,以及用于特定交易策略的策略智能体。
早期,治理系统决定性地证明了其价值。在一家大型芯片制造商因财报跳涨近 4% 的那一天,实践者想要追涨——一个典型的情绪化交易。多智能体治理否决了它。智能体识别了财报后的模式:最初的飙升往往会反转。相反,它们转向溢价出售策略。当天的损益是几百美元的小幅亏损,但治理系统阻止了追涨交易上估计约一万美元的损失。这正是系统按设计运作:多视角捕捉到单一决策者会遗漏的东西。
第二幕:性格冲突使系统瘫痪
然后系统崩溃了。不是因为技术故障。而是因为性格冲突。
顾问智能体,利用其关于风险管理的训练数据,变得过度规避风险。它将每个策略都标记为太危险。CEO 智能体,受训练数据中高管对专家顾问遵从的模式影响,顺从了顾问而不是否决它。工程师智能体未被使用——没有什么可以实施的,因为顾问否决了一切。系统使自己瘫痪了。精心设计的层次结构产生了比带有最少指令的单个智能体更差的结果。
第三幕:四个智能体变成一个
实践者最终的解决方案是彻底简化。多智能体层次结构从四个专门智能体退化为实际上只有一个带有最少指令的智能体:"自主交易到收盘。"复杂的性格系统——CEO、顾问、工程师、策略师——适得其反。智能体间通信和角色解释的开销消耗的价值超过了视角多样性产生的价值。
这不是孤立的轶事。它揭示了多智能体系统的一个结构性脆弱性。每个智能体利用模型的训练数据来解释其角色,而这些解释以你没有设计且无法轻易预测的方式相互作用。一个"谨慎的审查者"智能体可能会变得阻碍性。一个"激进的实现者"智能体可能会忽略有效警告。一个"善于外交的协调者"智能体可能会回避必要的冲突。
缓解措施有三方面。首先,从单个智能体开始,只有在你有证据表明单个智能体不足时才添加智能体。其次,当你确实构建多智能体系统时,保持角色定义具体且行为化,而不是抽象且基于性格的。"审查 src/api/ 中的所有文件以查找 SQL 注入漏洞"比"你是确保代码安全的顾问"更好。前者是一个任务。后者是一个角色,而角色有你未要求的观点。第三,愿意简化。实践者的四智能体系统短暂奏效,结构性失败,并被更简单的、优于它的架构所取代。多智能体复杂性必须持续证明其价值。
任务系统
在 subagent 和 Agent Teams 之下是一个共享的任务管理系统,它将工作持久化到磁盘并跨会话协调进度。
任务存储在 .claude/tasks/{session-id}/ 中作为 JSON 文件:
{
"id": "task-1",
"subject": "Create idb-helpers.ts",
"description": "Implement IndexedDB promise wrappers...",
"status": "pending",
"blocks": ["task-3", "task-4"],
"blockedBy": ["task-0"]
}
四个任务工具管理生命周期:TaskCreate 创建具有主题、描述和依赖的新任务。TaskUpdate 更改状态(从 pending 到 in_progress 到 completed)或修改依赖。TaskList 显示所有任务、其状态以及被阻塞的内容。TaskGet 检索特定任务的完整详情,包括其描述。
在交互会话中按 Ctrl+T 切换终端状态区域中的任务列表显示。一次最多可见 10 个任务,显示当前状态和进度。
多会话任务协调
任务系统支持跨多个 Claude Code 会话的协调。设置共享任务列表 ID:
CLAUDE_CODE_TASK_LIST_ID=myproject claude
或者将其添加到 .claude/settings.json:
{
"env": {
"CLAUDE_CODE_TASK_LIST_ID": "myproject"
}
}
当多个会话共享相同的任务列表 ID 时,它们都从相同的任务文件读取和写入。一个会话可以作为创建任务的编排者,而另一个会话处理它们。第三个会话可以监控已完成的任务并添加后续工作。这是一种轻量级协调机制,不需要完整的 Agent Teams 基础设施——只需磁盘上的共享状态。
自主循环模式
对于跨越数天或数周的项目,存在一种真正自主工作的模式:一个 bash 循环,反复将 Markdown 文件输入 Claude Code。每次迭代在一个全新的会话中运行,使用 Markdown 文件作为唯一的持久记忆。循环读取任务列表,选择下一个未完成的任务,以规范文档作为上下文运行 Claude Code,并将结果写回规范文件。然后循环继续。
这是无状态的,能够无限期运行。规范文件是唯一持久化的状态。每个会话干净启动,只读取需要的内容,完成工作,更新规范,然后退出。下一次迭代从上一次中断的地方继续。
权衡是显而易见的:没有对话历史,没有积累的上下文,除了规范文件中写入的内容之外,无法记住三次迭代前发生了什么。对于具有清晰规范和明确定义验收标准的任务,这已经足够。对于需要记住失败方法的探索性工作,则不够。
跨仓库的并行实例
最简单的多智能体工作形式完全不需要编排基础设施:在不同的终端窗口中运行多个 Claude Code 实例,每个实例在不同的仓库或 worktree 中工作。
每个实例都有自己的上下文窗口、自己的会话和自己的工具集。它们不知道彼此的存在,也不进行协调。当任务真正独立时这没问题——例如,更新三个共享 API 但不共享代码的微服务。
Git worktree(第九章)使这特别有效,为你在同一仓库的分支之间提供了具有完整代码隔离的并行开发。
这种模式被低估了,因为它很无聊。没有编排,没有智能体通信,没有共享任务列表。只有多个实例做独立的工作。但对于许多现实世界场景——跨仓库工作、维护多个分支、处理不相关的任务——它是可用的最有效的多智能体模式。
用于非工程工作的专门智能体
Subagent 不限于代码。相同的架构适用于任何受益于隔离上下文和专门指令的任务。
增长营销 Subagent 流水线
一个增长营销团队(一个非技术人员)构建了一个用于广告创意生成的智能体工作流,展示了这种模式。该工作流处理包含数百条现有广告及其性能指标的 CSV 文件,识别表现不佳的广告进行迭代,并生成满足严格字符限制(标题 30 个字符,描述 90 个字符)的新变体。
关键的架构选择:两个专门的 subagent 而不是一个通用智能体。一个标题 subagent 处理 CSV 并生成标题变体,受字符限制约束并参考性能数据。一个描述 subagent 对描述做同样的事情。分离关注点意味着每个智能体拥有更窄的任务,产生更高质量的输出,并在出现问题时更容易调试。
该工作流在几分钟内生成数百条新广告,而不需要跨多个广告活动的手动创建。以前需要两小时编写和复制粘贴的工作变成了十五分钟的自动化流水线。该团队从测试少量创意变体变为测试数百个,每个变体都满足手动流程经常违反的格式约束。
大规模层次化多智能体编排
一个劳动力管理平台使用层次化多智能体编排进行候选人处理,取得了显著成果。他们的系统使用中央编排智能体来协调用于候选人筛选、自动文档生成和情感分析的专门子智能体。结果是:筛选速度加快 50%,入职速度提高 40%,候选人转化率翻倍。一个物流客户从需要一周或更长时间来完全配备一个新的履行中心,到在 72 小时内完成。
这是多智能体架构在经济上证明自身价值的模式:结构化任务的大批量处理,其中每个子智能体有明确的专门化,编排开销分摊到数千个项目上。筛选一个候选人不需要多智能体编排。筛选数千个则需要。
通用模式
模式始终相同:在系统提示中定义智能体的角色,将其工具限制为所需的范围,给它一个聚焦的任务,并收集结果。智能体不需要编写代码。它需要读取输入、应用判断并产生结构化输出。
自定义智能体定义使这变得可及。一个带有 YAML frontmatter 的 Markdown 文件指定系统提示、可用工具和模型偏好就是你所需要的。团队可以为重复出现的非工程任务构建专门智能体库,并通过插件系统共享它们(第十一章)。
同样的成本优化也适用。执行评估或分析任务的智能体通常可以在更便宜的模型上运行良好。将昂贵的模型留给需要细致推理或复杂协调的任务。
单智能体何时胜出
多智能体编排并不总是更好。有时更差。
一个带有清晰指令、良好 CLAUDE.md 文件和强验证标准的单智能体可以在以下场景中胜过多智能体设置:
中小型任务。 如果任务适合一个上下文窗口且还有余量,多智能体的协调开销增加了成本和延迟而没有收益。
紧密耦合的变更。 如果每个文件变更都依赖于每个其他文件变更,并行化会产生顺序执行可以避免的集成问题。
不明确的分解。 如果你不能清楚地指定任务边界和接口契约,智能体会互相踩踏。一个顺序工作的单智能体至少能保持一致性。
新颖问题。 如果问题没有既定模式,智能体更可能以不可预测的方式偏离。一个单智能体可以迭代探索,在学习时调整方法。多个并行探索的智能体会产生多个不兼容的方法。
决策框架很简单:你能写出一个将工作干净地分解为具有清晰边界的独立任务的计划吗?如果能,多智能体会有帮助。如果你难以写出那个计划,从单个智能体开始,在更好地理解问题之后再重新考虑。
多智能体编排是一种强力工具。像所有强力工具一样,它放大了技能和错误。在任务需要时使用它,而不是因为它看起来很高级。
- Subagent 提供的 context isolation 胜过并行性——将冗余操作路由到 subagent 以保持编排者的上下文精简。
- 严格的两级层次结构(编排者和工作者,没有中间管理)是一个深思熟虑的设计选择,防止了递归混乱。
- 存在六种内置 subagent 类型(Explore、Plan、General-purpose、Bash、Claude Code Guide、statusline-setup),自定义 subagent 支持 maxTurns、mcpServers、skills 预加载、持久记忆和生命周期 hooks。
- Agent Teams 提供七个协调原语(TeamCreate、TaskCreate、TaskUpdate、TaskList、Task、SendMessage、TeamDelete),四种消息类型和三种显示模式。
- 始终在并行化之前先做计划;10,000 个 token 的规划可以防止 500,000 个 token 的浪费和冲突执行。
- 使用昂贵模型进行编排,使用便宜模型进行执行——经济学上严重偏向这种分工。
- 多智能体性格冲突是真实的,有时通过简化回单个智能体来解决;一个四智能体交易层次结构退化为一个,因为复杂性适得其反。
- 任务系统(Ctrl+T,以 JSON 存储在
.claude/tasks/中)通过 CLAUDE_CODE_TASK_LIST_ID 跨会话协调工作,实现无需完整 Agent Teams 的多会话编排。 - 从单个智能体开始,只有在你有证据表明单个智能体不足时才添加智能体。
- 最简单的多智能体模式——在不同终端中的多个独立实例——通常是最有效的。