章节导航 第 8 章 / 共 23 章
多代理架构
6 种内置代理的角色设计、工具权限矩阵、模型选择策略,以及协调器模式与 ForkSubagent 的协作机制
8.0 五层架构全景
Anthropic 官方博客发布了 Claude Code 的五层架构,为多代理系统提供了统一的分层视角。此前对多代理架构的理解多来自社区逆向分析,官方发布将以下五层明确定位:
┌─────────────────────────────────────────┐
│ Agent Teams (Swarm 协作层) │ ← 第5层:多 Agent 去中心化协作
│ ├── Team Lead + Teammate 消息邮箱 │
│ └── TaskList 共享 + 混合模型编排 │
├─────────────────────────────────────────┤
│ Subagents (独立子进程 Agent) │ ← 第4层:隔离执行,独立上下文
│ ├── ForkSubagent (worktree 隔离) │
│ └── batch (并行 worktree) │
├─────────────────────────────────────────┤
│ Agent (内置专用 Agent) │ ← 第3层:专业分工,工具权限矩阵
│ ├── Explore / Plan / Verification │
│ └── Guide / Statusline / General │
├─────────────────────────────────────────┤
│ Skills (可复用能力包) │ ← 第2层:领域知识 + 工具编排
│ ├── SKILL.md 定义 + 工具集 │
│ └── 按需加载,Prompt Caching 友好 │
├─────────────────────────────────────────┤
│ MCP (工具协议层) │ ← 第1层:外部工具集成标准
│ ├── 42+ 内置工具 │
│ └── MCP Server 动态注册 │
└─────────────────────────────────────────┘
每层的定位和交互方式:
| 层级 | 定位 | 职责 | 上下文共享 | 章节映射 |
|---|---|---|---|---|
| MCP | 基础设施 | 工具注册与调用 | 无(无状态协议) | Ch10 |
| Skills | 能力封装 | 领域知识 + 工具编排模板 | 共享主会话上下文 | Ch5/Ch6 |
| Agent | 专业执行 | 单一角色任务执行 | 共享主会话上下文 | Ch8.1-8.4 |
| Subagents | 隔离执行 | 风险任务/并行探索 | 独立上下文,可选持久记忆 | Ch8.5 |
| Agent Teams | 协作编排 | 多 Agent 协同完成复杂任务 | TaskList 共享 + 消息邮箱 | Ch8.5 |
五层架构的关键洞察:每一层都是对下一层的能力增强,而非替代。MCP 提供原子工具,Skills 封装工具组合,Agent 专业分工,Subagents 提供隔离,Agent Teams 实现协作。用户可以根据任务复杂度选择使用到哪一层——从简单的工具调用到完整的 Agent 团队协作。
8.1 不是一个代理,而是六个
Claude Code 不是一个单一的 AI Agent。它内置了 6 种专业代理,每种代理有不同的角色定位、工具权限和模型选择策略。这种设计的核心理念是专业分工——让不同的代理擅长不同的事,而不是让一个通用代理做所有事。
| 代理 | 角色 | 模型 | 权限模式 |
|---|---|---|---|
| General Purpose | 通用多步骤任务 | 继承主模型 | 全权限(tools: ['*']) |
| Explore | 代码库快速搜索 | Ant→主模型, 外部→Haiku | 只读 |
| Plan | 软件架构规划 | 继承主模型 | 只读 |
| Verification | 代码验证 | 需 Feature Flag | 只读 + 临时目录写入 |
| Claude Code Guide | 使用指导 | Haiku | 只读 + Web |
| Statusline Setup | 状态行配置 | Sonnet | Read + Edit |
源码引用:内置代理定义于 builtInAgents.ts,各代理实现位于 src/tools/AgentTool/built-in/。
上表”模型”列给出的是静态选择策略,读者容易误以为 agent 定义里的 model: 就是最终答案。实际上子 Agent 的模型解析是”三层优先级 + 一个强制开关”的动态结构,而且这套结构在四天内(v2.1.251 2026-08-28 → v2.1.257 2026-09-01)被反向调整了两次。
当前(v2.1.257 起)的解析顺序:
CLAUDE_CODE_SUBAGENT_MODEL_FORCE设了就一锤定音——把CLAUDE_CODE_SUBAGENT_MODEL(或主模型)应用到每一个子 Agent,忽略 per-spawn 与 agent 定义里的 model 覆盖。- 否则按优先级递减:per-spawn 显式模型 > agent 定义
model:>CLAUDE_CODE_SUBAGENT_MODEL> 主模型。
注意第 2 条里的第三档:CLAUDE_CODE_SUBAGENT_MODEL 自 v2.1.251 起只是默认值,不再是覆盖。时间线是:v2.1.251 把它从”覆盖一切”降级为”只设默认值”,v2.1.257 又新增 CLAUDE_CODE_SUBAGENT_MODEL_FORCE 把强制覆盖能力找补回来。两个版本方向相反,中间隔了 4 天。
由此得出的实践建议不是”记住这个顺序”,而是不要依赖任何固定顺序——这套优先级在本书写作期间仍在变动。要确认某个子 Agent 实际跑在哪个模型上,用 /tasks:v2.1.243 起它会显示每个子 Agent 实际运行的模型与 effort 级别。另需注意 v2.1.260 修的一个坑:model: fable 的 agent 曾忽略 ANTHROPIC_DEFAULT_FABLE_MODEL 上的 [1m] 标签,静默跑在 200K 上下文而非 1M。
同类的静默错配还有一处,但它暴露的是更普遍的问题:模型别名不是跨平台常量。model: "opus" 在 Bedrock / Vertex / Foundry 上,当 model id 无法识别出所属 model family 时,子 Agent 会离开会话正在用的模型——除非显式设置了 ANTHROPIC_DEFAULT_OPUS_MODEL(v2.1.274 修复)。注意这里的失败模式:不是报错,而是解析到了另一个模型并继续跑。子 Agent 的能力与成本也随之悄悄改变,而父 Agent 看到的只是一个正常返回的结果。
这把 8.1 表格”模型”列的适用边界说清楚了:那张表描述的是第一方 API 下的静态策略。换到第三方云托管时,opus / sonnet / haiku 这些别名要经一次”id → model family”的识别,识别不出来就没有兜底。要做跨平台确定性,就别依赖别名,直接写全 model id 或用 ANTHROPIC_DEFAULT_*_MODEL 系列变量把别名钉死。
模型之外还有第二条轴:effort(v2.1.292)。 上表有”模型”列但没有 effort 列,而 8.1 前文的实践建议是”要确认子 Agent 实际跑在哪个模型与 effort 上,用 /tasks”——也就是说,在 v2.1.292 之前 effort 只能看不能设:
Added an
effortparameter to the Agent tool, so Claude runs a sub-agent at the effort level you ask for
现在 Agent 工具接受 effort 参数,子 Agent 可以跑在指定的 effort 档上。把这条与 8.3 节新增的 autoCompactWindow(v2.1.296)放在一起读,可以看出子代理的可调参数正在从”模型”一个扩到三个:模型、effort、压缩窗口。三者互不隶属——同一个子 Agent 可以在主模型上跑低 effort,也可以在小模型上跑高 effort,还可以在比主会话更小的窗口上提前压缩。
⚠️
/tasks的计数口径变了(v2.1.285)。 上文建议用/tasks看实际模型与 effort,这仍然成立;但用它数”有几个子 Agent 在跑”会漏:官方把 Claude Code 为自己运行的后台工作折叠成一行 “System tasks”,按 Enter 才展开(“fold background work Claude Code runs for itself under one “System tasks” row”)。凡是以/tasks作为并发计数或资源预算依据的地方,都要记得展开这一行。
8.2 代理的条件加载
并非所有代理都始终可用。getBuiltInAgents() 函数根据环境条件决定加载哪些代理:
function getBuiltInAgents(): AgentDefinition[] {
// SDK 模式下可完全禁用内置代理
if (isEnvTruthy(process.env.CLAUDE_AGENT_SDK_DISABLE_BUILTIN_AGENTS)
&& getIsNonInteractiveSession()) {
return [];
}
// 协调器模式:返回专用的 Worker 代理集
if (feature('COORDINATOR_MODE')
&& isEnvTruthy(process.env.CLAUDE_CODE_COORDINATOR_MODE)) {
return getCoordinatorAgents();
}
const agents = [GENERAL_PURPOSE_AGENT, STATUSLINE_SETUP_AGENT];
if (areExplorePlanAgentsEnabled())
agents.push(EXPLORE_AGENT, PLAN_AGENT);
// 非 SDK 入口才加载 Guide 代理
if (isNonSdkEntrypoint)
agents.push(CLAUDE_CODE_GUIDE_AGENT);
// 需要 Feature Flag + 特定特性值
if (feature('VERIFICATION_AGENT') && getFeatureValue_CACHED(...))
agents.push(VERIFICATION_AGENT);
return agents;
}
SDK 用户可以通过 CLAUDE_AGENT_SDK_DISABLE_BUILTIN_AGENTS 环境变量禁用所有内置代理——这对于想要完全自定义代理行为的 SDK 调用方很有用。
8.3 Plan Agent:只读的架构师
Plan Agent 是一个有趣的设计——它的工具权限与 Explore Agent 完全相同(只读),但它被明确禁止使用以下工具:
const PLAN_AGENT: BuiltInAgentDefinition = {
agentType: 'Plan',
disallowedTools: [
AGENT_TOOL_NAME, // 不能启动子代理
EXIT_PLAN_MODE_TOOL_NAME, // 不能退出计划模式
FILE_EDIT_TOOL_NAME, // 不能编辑文件
FILE_WRITE_TOOL_NAME, // 不能写文件
NOTEBOOK_EDIT_TOOL_NAME, // 不能编辑 Notebook
],
omitClaudeMd: true, // 不加载 CLAUDE.md(节省 Token)
model: 'inherit',
};
omitClaudeMd: true 是一个精细的优化:Plan Agent 是只读的,可以直接 FileRead CLAUDE.md 如果需要;但在 System Prompt 中预加载它会浪费 Token。
同类字段还有 v2.1.248 新增的 experimental.cacheTtl(取值 "5m" 或 "1h"),即每个 Agent 独立的 prompt cache TTL,仅在未配置全局 subagent TTL 设置时生效。它与 v2.1.243 新增的全局 subagentPromptCacheTtl 构成一对:可以做到主会话保持 1 小时缓存、而子 Agent 只保持 5 分钟。
这给”精细优化”补上了第二个、且性质不同的例子。omitClaudeMd 优化的是 Token 维度(少加载多少内容),experimental.cacheTtl 优化的是成本维度(这份内容以什么价格被重复计费)。子 Agent 通常生命周期短、并发多、前缀重复率高,把它们的 TTL 压到 5 分钟而让主会话保持 1 小时,是两类负载的最优解不同导致的。这部分与第 9 章的 Prompt Caching 讨论相接。
第三个维度:压缩时机(v2.1.296)。 前两例优化的是”加载多少”与”以什么价格加载”。v2.1.296 加的 autoCompactWindow 优化的是第三件事——什么时候放弃已加载的:
Added
autoCompactWindowto subagent frontmatter and--agentsdefinitions, so a subagent can auto-compact earlier than the main conversation’s window
它进入子代理 frontmatter 与 --agents 定义,因此可以逐个 agent 设置,且允许子代理比主会话更早自动压缩。与前两例的关键差别在于它是第一个压缩时机维度的可配置项(第 9 章讨论的是压缩管线的机制,不是它的触发时机);放在 8.3 的脉络里,它与 omitClaudeMd(少加载)、experimental.cacheTtl(便宜地重复加载)构成一个完整的三段式:加载多少 / 以什么价格 / 何时丢弃。
一类新的模型覆盖:按 agent 类型而非按单个 agent(v2.1.296)。 同版本还加了一个本书此前没有的形态:
Added
CLAUDE_CODE_WORKFLOW_SUBAGENT_MODELto run every workflow agent on one model while other subagents keep theirs
把它与 8.1 已有的 CLAUDE_CODE_SUBAGENT_MODEL_FORCE(把某个模型应用到每一个子 Agent)并读,可以看出模型覆盖机制现在有两条正交的轴:
| 轴 | 取值 | 变量 |
|---|---|---|
| 范围 | 全局(每一个子 Agent)/ 按类型(workflow) / 单个(per-spawn、agent 定义) | ..._FORCE / ..._WORKFLOW_SUBAGENT_MODEL / Agent 工具的 model 参数 |
| 强制性 | 强制(忽略一切覆盖)/ 默认(可被更具体的覆盖) | ..._FORCE / CLAUDE_CODE_SUBAGENT_MODEL |
CLAUDE_CODE_WORKFLOW_SUBAGENT_MODEL 落在”按类型 + 默认”这一格:它只管 workflow agent,且其它子代理各自保持自己的模型。这个组合此前本章没有——8.1 那套”三层优先级 + 一个强制开关”里没有”按类型”这一层。
8.4 Verification Agent:对抗性验证
Verification Agent 是最具创新性的代理设计。它被明确要求”假设代码有 bug”,并识别两种验证失败模式:
- 验证避免(Verification Avoidance):找各种理由跳过检查
- 被表面完善迷惑(Swayed by Surface Polish):前 80% 看起来没问题就通过
这种对抗性验证(adversarial verification)策略在业界的多代理框架中几乎看不到。CrewAI、AutoGen 等框架的”验证代理”通常是让一个代理检查另一个代理的输出,但没有像 Claude Code 这样在系统提示词中明确编码认知偏差的防护。
验证策略的工程细节
Verification Agent 的设计揭示了几个深层考量:
权限约束:它只有只读权限 + 临时目录写入能力。“只读”不是因为验证不需要写入,而是物理上防止验证者修改被验证的代码。如果验证者能直接修改代码,它就不再是独立的第三方——这是审计原则的工程化。临时目录写入允许它运行测试或编译来验证正确性,但不污染原始工作区。
模型隔离:Verification Agent 需要 Feature Flag 才能启用,且走独立的模型调用路径。这意味着它的验证结果不会被主 Agent 的上下文”污染”——主 Agent 不知道验证者看到了什么中间结果,只知道最终的 PASS/FAIL。
提示词中的反模式目录:验证者的系统提示词显式列出了”不要做的事”——不要只检查语法、不要因为代码看起来整洁就跳过逻辑检查、不要信任注释的准确性。这种”反模式目录”(anti-pattern catalog)比正面指令更有效,因为模型的默认行为往往就是这些反模式。
为什么这很难在通用框架中实现
CrewAI 的 @crew.task 装饰器和 AutoGen 的 ConversableAgent 都支持”验证角色”,但它们缺少两个关键要素:
- 权限隔离不在框架层面。你可以给代理起名叫”验证者”,但它仍然拥有和其他代理相同的工具访问权限
- 认知偏差防护不是默认行为。你需要自己在 prompt 中编写防护逻辑,但大多数开发者不会想到”验证避免”和”表面完善迷惑”这些具体的失败模式
Claude Code 之所以能做到这个粒度,是因为它经历了大规模生产实践中的真实验证失败——这些防护策略不是理论推演出来的,而是从 bug 中学来的。
Verification Agent 需要 Feature Flag 才能启用,说明它可能还在实验阶段。但它的设计思想——在提示词中编码认知偏差防护——是目前业界多代理设计中最值得学习的模式之一。
学界进展:从提示词防护到可训练知识网络。南大/清华的 Solvita(2026-07)将对抗性验证从”提示词编码”推进到”可训练的图结构知识网络”——Hacker Agent(攻击性测试角色)的验证经验可跨任务复用,CF rating 超 3500(全球前十)。这与 Claude Code 的 Verification Agent 共享”对抗性验证”理念,但在实现路径上分野:Claude Code 靠提示词工程(anti-pattern catalog),Solvita 靠经验学习(graph-structured knowledge network)。两种路径并非替代关系——提示词防护是即插即用的第一道防线,可训练知识网络则适合长期积累验证经验的场景。
验证策略矩阵:10种变更类型适配
Verification Agent 针对不同变更类型采用专门的验证策略:
| 变更类型 | 验证策略 | 关键检查点 |
|---|---|---|
| 前端 | UI 组件测试 | 渲染正确性、交互逻辑、响应式布局 |
| 后端 | API 测试 | 接口契约、数据验证、错误处理 |
| CLI | 命令行测试 | 参数解析、输出格式、退出码 |
| 基础设施 | 配置验证 | 环境变量、网络配置、安全策略 |
| 库 | 兼容性测试 | API 向后兼容、依赖版本、文档更新 |
| Bug修复 | 回归测试 | 复现原问题、验证修复、检查副作用 |
| 移动端 | 跨平台测试 | iOS/Android 一致性、性能基准 |
| 数据管道 | 数据质量检查 | 输入输出格式、转换逻辑、错误恢复 |
| 数据库迁移 | 迁移脚本验证 | 数据完整性、回滚机制、性能影响 |
| 重构 | 行为保持测试 | 功能等价性、性能基准、API 兼容性 |
结构化输出要求
所有验证结果必须以 VERDICT 标签结尾:
VERDICT: PASS- 完全通过,无风险VERDICT: FAIL- 发现严重问题,阻止部署VERDICT: PARTIAL- 部分通过,有警告但可继续
启用条件
Verification Agent 需要同时满足:
VERIFICATION_AGENTFeature Flag 启用tengu_hive_evidenceFeature Flag 启用(实验性证据收集)
源码引用:验证策略矩阵参见 verificationAgent.ts#L120-189,结构化输出要求参见 verificationAgent.ts#L45-67。
8.5 四种协作模式
除了内置代理的”主代理调用子代理”模式,Claude Code 还支持两种更高级的协作模式:
协调器模式(Coordinator Mode)
协调器模式采用四阶段工作流,实现大规模任务的并行处理:
Research(研究阶段)
├── Worker A:并行研究代码库结构
├── Worker B:分析依赖关系和接口
└── Worker C:收集相关文档和示例
↓
Synthesis(合成阶段)
├── Coordinator:综合所有研究结果
├── 生成详细的任务规范
└── 分解为可并行执行的子任务
↓
Implementation(实现阶段)
├── Worker A:实现模块 A
├── Worker B:实现模块 B
└── Worker C:实现模块 C
↓
Verification(验证阶段)
├── Worker A:单元测试
├── Worker B:集成测试
└── Worker C:性能验证
↓
<task-notification> XML 标签异步返回结果
关键约束与设计原则
上下文传递约束:Worker 看不到 Coordinator 的对话历史,Coordinator 必须在指令中完整陈述上下文。这是为了确保 Worker 的独立性,防止信息泄露导致的偏见。
并发策略:
- 只读任务:自由并行(Research 阶段)
- 写任务:相同文件集时串行(Implementation 阶段)
- 冲突检测:自动检测文件修改冲突,必要时回退
工具权限矩阵:
- Coordinator:仅 4 个工具(AgentTool、TaskStopTool、SendMessageTool、SyntheticOutputTool)
- Worker:基础模式(Bash/Read/Edit)或标准模式(完整工具池排除内部工具)
- Scratchpad 目录:跨 Worker 知识共享的临时存储区
源码引用:协调器模式四阶段工作流参见 coordinatorMode.ts#L45-89,Worker 工具权限矩阵参见 tools.ts#L201-234。
ForkSubagent 隔离执行
v2.1.212 对 ForkSubagent 的触发方式做了根本性区分,原 ForkSubagent 的职责被拆分为两个命令:
/fork(v2.1.212+):背景会话。将当前对话复制到一个全新的独立背景会话中——拥有自己的 claude agents 行、独立进程、独立上下文。主会话不会被阻塞,背景 Agent 可以持续运行。适用于”长时间独立任务,我想继续在主会话中工作”的场景。
/subtask(v2.1.212+):会话内子 Agent。在父会话内部启动子 Agent,继承部分上下文和状态。这是 v2.1.212 之前 /fork 的原有行为。适用于”帮我尝试一个方案,结果直接反馈到当前会话”的场景。
两种模式的隔离级别差异:
/fork:完全独立的会话进程,与父会话的唯一联系是通过<task-notification>XML 标签异步返回结果。子 Agent 看不到父会话的后续对话,父会话不等待子 Agent 完成。/subtask:在父会话中运行,共享父会话的某些状态(如 TaskList、TeamMem),结果直接回显到父会话。
ForkSubagent 在 Git worktree 中创建隔离环境,子代理可以在独立的文件系统副本中工作。这对于”尝试一个方案,如果不行就丢弃”的场景特别有价值。
默认可用的范围按宿主分叉,且有一个入口明确永不提供(v2.1.302)。 上面以终端为主视角,官方在 v2.1.302 把默认可用范围扩到了四类宿主,并给了关法与例外:
Changed fork subagents (
subagent_type: "fork") to be on by default inclaude -p, the Agent SDK, the desktop app and VS Code, as they already are in the terminal;CLAUDE_CODE_FORK_SUBAGENT=0turns them off, andclaude mcp servenever offers them
三个细节:终端此前已经是默认;CLAUDE_CODE_FORK_SUBAGENT=0 可关;claude mcp serve 从不提供。最后这个例外值得单独记——它是本章唯一一处”某入口永不提供某能力”的官方表述。把它与 8.2 的 CLAUDE_AGENT_SDK_DISABLE_BUILTIN_AGENTS(SDK 下可完全禁用内置代理)并读,是同一条设计线:入口决定能力集,而不只是”功能在各宿主上的支持程度不同”。
子代理的上下文也有数量上限(v2.1.295)。 8.5 与 6.3.1 讨论过子代理”主小子大”的完整 System Prompt,但那只是体积侧。官方另给了一个数量约束:子代理从 skills 字段最多预加载 32 个技能,每个一次;持有 Skill 工具的子代理仍可调用其余的(原文:“Changed subagents to preload at most 32 skills from the skills field, each once; a subagent with the Skill tool can still invoke the rest”)。给”主小子大”补的限定是:子代理可以拥有比主代理更完整的决策上下文,但预加载的技能有 32 的硬顶,超出部分必须运行时取用——这与 6.1.0 Six Shifts 第 3 条 Progressive Disclosure 是同一条线,展开见第 6 章 6.9 节。
消息构建流程
// 1. 克隆父代理历史
const forkHistory = cloneParentHistory(parentSession);
// 2. 插入占位符 tool_result
forkHistory.push({
type: 'tool_result',
content: '<fork-boilerplate>',
tool_call_id: 'fork-placeholder'
});
// 3. 添加子代理指令
forkHistory.push({
type: 'user',
content: `在隔离环境中尝试:${taskDescription}`
});
防递归机制
- 标签检测:
<fork-boilerplate>标签标识 Fork 会话 - 历史扫描:
isInForkChild函数扫描历史中的标签,防止递归 Fork - 权限上浮:bubble 模式将子代理的权限提示回送到父终端
缓存优化与隔离模式
- 统一占位符:所有 Fork 使用相同的占位符文本确保 Prompt Cache 命中
统一占位符是必要条件而非充分条件。v2.1.265 一次性修了三处”提示前缀漂移导致 prompt cache 失效”,它们都不是占位符文本的问题:恢复一个前台 spawn 的子 Agent 会改变其工具列表与 system prompt 前缀;agent teammates 与已恢复的子 Agent 在后续轮次把 SubagentStart hook 上下文与预加载 skill 移出提示前缀;in-process agent-team teammate 在第二轮重复发送首轮的工具与 skill 公告(v2.1.261)。
抽象出来的判据是:任何进入提示前缀的内容,在恢复前后必须逐字节一致,否则整段缓存失效——占位符只是其中一项。这与第 9 章”前缀稳定性 > 单次压缩量”是同一原理在多 Agent 场景的复现。
- 两种隔离模式:
worktree:Git 工作树隔离(推荐,支持 Git 仓库)remote:仅 ant 用户可用(受限环境)
与协调器模式的关系
ForkSubagent 与协调器模式互斥——启用了协调器模式就不能用 ForkSubagent。
batch 批量处理模式
batch 技能在协调器模式下支持大规模并行处理(5-30个并行单元),专为大规模代码变更设计:
核心特性
- 自动任务分解:将大型任务自动分解为独立子任务
- 隔离 worktree:每个子任务在独立的 Git worktree 中执行
- 并行执行:支持 5-30 个并行单元,根据系统资源动态调整
- 结果聚合:自动收集所有子任务结果并生成综合报告
适用场景
- 大规模重构:同时修改多个模块的接口
- 代码迁移:将旧代码库迁移到新框架
- 测试生成:为大型项目生成测试用例
- 文档更新:批量更新 API 文档
技术实现
batch 模式依赖 Git 仓库环境,通过以下机制实现:
// 1. 任务分解
const subtasks = decomposeTask(mainTask, { maxParallel: 30 });
// 2. worktree 创建
const worktrees = subtasks.map(task =>
createWorktree(task.id, { isolate: true })
);
// 3. 并行执行
const results = await Promise.all(
worktrees.map(worktree =>
runInWorktree(worktree, task.executor)
)
);
// 4. 结果聚合
const finalReport = aggregateResults(results);
源码引用:batch 模式实现参见 batchMode.ts,并行任务调度参见 parallelScheduler.ts。这是因为两者都涉及并行执行,但采用不同的隔离策略:协调器模式是逻辑隔离(同一工作区),ForkSubagent 是物理隔离(独立工作区)。
源码引用:ForkSubagent 实现细节参见 forkSubagent.ts#L78-145,防递归检测参见 forkSubagent.ts#L201-234。
Teammate 团队协作(Agent Teams / Swarm Mode)
2026年2月随Opus 4.6发布的Agent Teams(Swarm Mode)是多代理架构的重大升级,从实验性功能升级为正式特性,支持 2-16 个 Claude Code 会话协作。官方文档已完善(code.claude.com/docs/en/agent-teams)。
核心架构:Team Lead + Teammate
Team Lead(团队领导,Opus 4.6)
├── Teammate A(研究员,Sonnet)→ 异步研究
├── Teammate B(编码员,Sonnet)→ 并行实现
└── Teammate C(验证员,Sonnet)→ 独立验证
关键特性:
- 混合模型编排:Lead 用 Opus(强推理),Teammate 用 Sonnet(高效执行)
- 消息邮箱机制:Teammate 通过
SendMessage工具通信,消息投递到收件箱在下一轮处理 - 异步并行:多个 Teammate 可同时工作,Lead 负责任务分配和结果合成
团队配置与任务管理
团队配置存储在 ~/.claude/teams/<team-name>/config.json,支持:
- 自定义角色定义和工具权限矩阵
- 任务列表 ID 解析优先级(高优先级任务优先分配)
- 团队状态持久化(会话恢复时保持团队结构)
已知限制与最佳实践
- 会话恢复:团队状态在会话中断后需要重新初始化
- 任务协调:Lead 必须明确指定任务依赖关系避免冲突
- 关闭行为:团队解散时自动清理临时工作区
生产实践最佳实践(基于 Addy Osmani 等社区总结):
- 团队规模:2-16 个会话,建议从 3-5 个起步,过多 Teammate 会导致 Lead 的协调开销指数增长
- 角色分工:Lead 必须用强推理模型(Opus),Teammate 用高效模型(Sonnet);避免所有成员使用同一模型
- 任务粒度:每个 Teammate 的任务应足够独立,减少跨成员的文件冲突——共享文件集的子任务应串行分配
- 关闭策略:使用
shutdown_request优雅解散,而非直接终止进程;确保所有临时工作区已清理 - 调试技巧:通过 Teammate 的
SendMessage日志追踪消息流转,定位协调瓶颈
源码引用:Agent Teams 实现参见 agentTeams.ts,团队配置管理参见 teamConfig.ts。
Teammate 的身份与状态模型(v2.1.289 → 290 → 293)
上面三条工程约束讲的是消息怎么寻址、怎么投递,但本章此前没有回答两个更基础的问题:一个 teammate 有哪些状态,以及同一个 agent 在不同事件里是不是同一个 id。两周内三个版本补上了这两件事,且顺序不能颠倒:
- v2.1.289(2026-10-03):teammates 获得
agent.spawn;插件 hook 事件之间统一使用同一个 agent id;$.agent.list()新增 idle 与 waiting 状态(官方原文:“Addedagent.spawnfor teammates, one agent id across plugin hook events, and idle and waiting states in$.agent.list()”)。 - v2.1.290(2026-10-05):in-process teammate 在 Agent 结果中的
agent_id改为其 agent ID,其name@team地址保留在teammate_id;TeammateIdlehook 不再由其子代理或 fork 触发。 - v2.1.293(2026-10-07):
subagentStatusLine负载新增agentType,脚本可区分自定义子代理类型。
三点教学价值:
- 状态模型出现了。teammate 不再只有”活着 / 完成”,还有 idle 与 waiting。这直接对应”后台与并发路径上的三条可靠性事实”里那条 状态报告与实际状态脱钩(v2.1.274)——那个症状的成因之一正是没有状态模型:没有 idle / waiting 这两个状态,一个正在等待的 agent 只能被报告成”没有活的后台工作”。
- 身份被拆成两个字段。
agent_id(跨事件稳定)与teammate_id(name@team地址)分开。这与 8.5 第 1 条约束(未命名的 Agent 不可作为回复地址)直接相关——地址与身份现在是两回事:没有名字意味着没有teammate_id,但它在 hook 事件里仍然有稳定的agent_id。 - idle 的判定单位收紧了。
TeammateIdle不再由子代理或 fork 触发,与本轮新增的”子代理自派生默认前台”是同一个收敛方向——判定单位从”这棵子树”变成”这个 agent 本身”。
源码引用:协调器模式参见 coordinatorMode.ts,ForkSubagent 参见 forkSubagent.ts,团队工具参见 TeamCreateTool.ts。
8.5.0 四种协作模式系统对比
8.5 节讨论了四种协作模式,以下从七个关键维度进行系统对比:
| 维度 | 协调器模式 | Agent Teams (Swarm) | ForkSubagent | 跨会话消息 |
|---|---|---|---|---|
| 协调方式 | 集中式:Coordinator 掌控四阶段工作流 | 去中心化:Teammate 独立运行,Lead 分配任务 | 无协调:完全隔离的子进程 | 无协调:同机器任意两会话点对点互发 |
| 上下文共享 | Worker 看不到 Coordinator 历史 | TaskList 共享 + SendMessage 邮箱 | 独立上下文,克隆父历史后独立演进 | 不共享上下文,仅消息体 |
| 隔离级别 | 逻辑隔离(同一工作区) | 逻辑隔离(同一工作区) | 物理隔离(Git worktree) | 进程级(各自独立会话) |
| 记忆持久性 | 无持久化,会话结束即丢失 | 支持 TeamMem 持久记忆 | 默认无,可选用 TEAMMEM 模式 | 随各自会话 |
| 适用场景 | 结构化大任务(Plan→Delegate→Execute→Verify) | 并行独立子任务(多文件修改、多模块测试) | 探索性/风险任务(试错、不可信代码) | 临时把一个会话的发现告诉另一个会话,不值得建 Team |
| 模型编排 | Coordinator/Worker 可选不同模型 | Lead(Opus) + Teammate(Sonnet) 混合 | 继承主模型 | 各自独立 |
| 并发能力 | Worker 级并行(相同文件集串行) | 2-16 个 Teammate 并行 | 单次 Fork,batch 支持 5-30 并行 | 无上限概念,按需 |
第三种通信形态:发布—检索式协调。 上表的”协调方式”一列里,通信形态只有两种:集中式邮箱(TaskList + SendMessage)与点对点互发。而最佳实践第 1 条说”过多 Teammate 会导致 Lead 的协调开销指数增长”——本章给的解法是”少用几个”,这只是一条回避,不是解法。2026-10-12 的 ScaleMAS(arXiv:2610.16120,Scaling Multi-Agent Intelligence with Substrate-Centric Coordination)给了第三种形态,并直接针对这一点:
- 机制:agent 之间不直接互发消息,而是通过三个操作与一个共享消息库交互——发布(可带对早前消息的引用)、按内容检索、按地址访问。
- 为什么能解协调开销:检索最多返回 条,因此任一 agent 的读取量在任何群体规模下都是有界的;排序按相关性与被引用次数(论文发现后者是质量的有效代理)。
- 为什么能解脆弱性:消息在其生产者离开后仍然留存,因此个别 agent 失败时群体继续运转。
- 论文自报:在四类 agentic 任务上优于 agent-centric 与黑板式基线,且推理算力更低;可扩展到 128 个 agent,并能容忍中途丢失 agent。
第二个可补的是树状上下文(TreeFlex,arXiv:2610.20334,2026-10-14,TreeFlex: Agents Navigating Their Own Search Trees):每个中间状态连同一段短摘要存为搜索树的一个节点;同一个模型分饰两角——Reflection 通过摘要看到全树,决定恢复/分支/验证/停止;Execution 只拿到通往该节点的路径,用常规工具执行。这给 8.5.1 /goal 的”目标状态收敛”提供了一个替代结构:不是单一收敛点,而是一棵可分支、可回退的树。数字(论文自报):4B 模型在 deep-research 基准上 48.8%,对比 flat ReAct 41.5% 与 FoldAgent 42.8%,Pass@8 高约 10 点;SWE-bench Verified 上三个系统同从 9B 起训,TreeFlex 54.9%,FoldAgent 43.3%,其 step-wise 变体 45.2%。
⚠️ 边界:两篇均为预印本自报,上述数字出自各自摘要,未见独立复现;本书只把它们作为”通信形态与上下文结构的可选设计”引入,不作为性能结论。
第四种模式值得单独说明,因为它的门槛最低:不需要组建 Team。Agent Teams 要求 TeamCreate 加 ~/.claude/teams/<team>/config.json,而跨会话消息允许同机器上任意两个独立会话直接互发。v2.1.248 起它在 Bedrock、Vertex、Foundry 以及关闭遥测的会话中可用(此前受限),v2.1.243 还修了 2.1.232 socket 目录加固后它在 user namespace 与 rootless 容器中被静默关闭的问题。
三条工程约束容易踩:
- 未命名的 Agent 不可作为回复地址。v2.1.251 修的一个 bug 揭示了寻址语义:
from字段是 agent type 而不是地址,所以后台子 Agent 无法回复未命名的兄弟/父 Agent。要给某个 Agent 发消息并期待回复,它必须是有名字的。 - 回复落到父会话而非子 Agent。v2.1.248 起,
SendMessage从子 Agent 发往另一个会话时,结果会说明回复投递到父会话的对话。这是”邮箱”模型和”点对点”模型在语义上的关键差异。 - 已发送 ≠ 已投递 ≠ 已读。v2.1.271 之前,被接收方会话的权限模式策略扣留的跨会话消息会无声无息地消失——发送方既不知道消息没到,也不知道它在等审批。修复后的语义是三层分离的:headless 发送方会收到投递通知(知道消息到了哪里、是否被扣留),而
SendMessage的返回结果不再暗示对方已经读过。
第 3 条值得单独强调,因为它是本章唯一一条被官方修改的语义而非实现:此前把”调用成功”当成”对方已知情”是合理的读法,此后不是了。协调协议里如果只有”发过了”这一个状态,上层就会把它等价于”对方知道了”,从而省掉确认环节;而跨会话消息恰好有第三种状态——已投递但被权限策略挂起。这意味着用 SendMessage 搭出来的协作流程,需要显式区分这三个状态,并在被挂起时有可见的处理路径(这正是 v2.1.224 引入 crossSessionInbound 审批设置时所处的同一条设计线)。
模式选择决策树:
任务是否需要协作?
├── 否 → ForkSubagent(独立探索/试错)
└── 是 → 只需在两个已有会话间传个消息?
├── 是 → 跨会话消息(不必建 Team)
└── 否 → 任务是否可分解为独立子任务?
├── 否 → 协调器模式(需要阶段间依赖的结构化任务)
└── 是 → 子任务是否涉及共享文件?
├── 是 → 协调器模式(Worker 级文件冲突检测)
└── 否 → Agent Teams(并行独立任务,最高吞吐量)
量化验证:CMU 的 CAID 架构(2026-07,Centralized Asynchronous Isolated Delegation)在 PaperBench 论文复现任务上的对照实验证实——依赖感知任务分配(共享文件检测→串行调度)使多 Agent 准确率提升 26.7%,Commit0 从零构建 Python 库 +14.3%。这直接验证了决策树中”共享文件→协调器模式”分支的工程价值。
子 Agent 嵌套深度演变
ForkSubagent 的嵌套深度在 v2.1.172-v2.1.219 期间经历了三次调整:
| 版本 | 默认嵌套深度 | 说明 |
|---|---|---|
| v2.1.172-2.1.216 | 5 层 | 初始默认值,支持深层 fan-out |
| v2.1.213 | 1 层 | 禁止嵌套,社区哗然——现有 Workflow 大量依赖嵌套子 Agent |
| v2.1.219 | 3 层(当前) | 回升至 3,可通过 CLAUDE_CODE_MAX_SUBAGENT_SPAWN_DEPTH 环境变量配置 |
Anthropic 将深度设为 3 的工程理由:恰好支撑”审查员→验证员→查找员”的标准审查 fan-out 模式。深度 3 意味着主 Agent 可以 spawn 审查员,审查员 spawn 验证员,验证员 spawn 查找员——三层覆盖了绝大多数代码审查工作流的需求,同时限制了无限递归的风险。
背景 Agent 与 Session 资源上限
v2.1.198 起,子 Agent 默认在背景运行——主会话不再阻塞等待子 Agent 完成。背景 Agent 在 worktree 中完成代码工作后自动 commit、push、打开 draft PR,不再停下来询问用户。这一变更将多 Agent 从”同步阻塞模式”升级为”异步管道模式”。
⚡ 这句话现在只在第一层成立,必须按层读(v2.1.302)。 官方把”默认前台还是后台”拆成了两层,且方向相反:
Changed the desktop app and VS Code to always run the main conversation’s subagents in the background, as the terminal does, rather than let Claude choose; a subagent’s own Agent calls in
claude -p, the Agent SDK, the desktop app and VS Code now run in the foreground by default
层 v2.1.302 起的行为 主会话派生的子代理 桌面 app 与 VS Code 总是后台运行(与终端一致) 子代理自己再派生的 Agent 调用 在 claude -p、Agent SDK、桌面 app、VS Code 中默认前台运行两点必须写准。其一,两层方向相反——只写”子 Agent 默认后台”会把第二层说反。其二,“rather than let Claude choose”是一次决策主体的变化:此前前后台由模型选择,现在由宿主决定。这与 8.6 第 6 条”协调原语的选择也是设计维度”是同一件事的另一面——这里的选择权被收回到了宿主层,不再留给模型。
v2.1.212 进一步引入了 session 级安全上限:
- WebSearch 调用次数上限:每 session 有 WebSearch 调用预算
- 子 Agent 生成数上限:每 session 有子 Agent spawn 配额
/clear可重置预算
这些上限与 7.7 节的熔断机制形成安全层面的呼应——权限系统保护”单个操作的安全性”,session 上限保护”整个会话的资源消耗可控性”。两者结合构成了多 Agent 系统的”双重约束”:行为约束(权限)+ 资源约束(session 预算)。
派生会话的设置来源继承
上面这套”双重约束”有一个隐含前提:父会话上的限制会传播到它 spawn 出来的会话。曾经这个前提不成立——--setting-sources(SDK 里的 settingSources)没有转发给派生会话,于是 teammates、/bg、claude agents 会话以及 --worktree --tmux 启动的会话都在没有父会话限制的情况下运行(v2.1.281 修复,现在它们以父会话的限制启动)。
这条值得单列,因为它把”派生”从一个纯粹的能力问题变成了一个权限边界问题:只要 spawn 不继承限制,spawn 本身就是一条绕过裁剪的路径。父会话用 --setting-sources 去掉了项目级或用户级配置,看起来收紧了,而它 spawn 出去的每个子会话都还在读那些配置。这与第 7 章”权限是边界而非偏好”的结论一致——凡是有 spawn 的设计,都必须显式验证限制是否随派生传播,不能假设继承。
这条结论还有第二半:光传播还不够,施加限制时必须能认出是哪个 agent(v2.1.290)。 上面讲的是”限制能不能到达子代理”,官方另补了识别侧:
Added
agentIdto thetool.checkevent of plugin hooks, so a hook can tell a subagent’s permission check from the main session’s
两半缺一不可:只传播不识别 → 无法按 agent 差异化(所有检查长得一样,只能一视同仁);只识别不传播 → 差异化无从落地(认得出是谁,但限制根本没到那儿)。合起来才是完整的按 agent 施加策略的能力。(与第 7 章同批修改:Ch07 本轮新增的 v2.1.290 两条 --restricted 漏网与 v2.1.299 的 MCP 规则收紧,属于同一条”派生与识别”线索。)
后台与并发路径上的三条可靠性事实
多 Agent 的可靠性问题不止出现在”结果对不对”,也出现在”我看到的运行状态是不是真的”和”我能不能停下来”:
| 现象 | 实情 | 版本 |
|---|---|---|
| 后台 subagent 运行时按 Ctrl+C 退不出去 | 曾需按三到四次;修复后两次即退出 | v2.1.280 |
| 后台 agent 通知说”没有活的后台工作” | 可能仍在等它自己的后台任务,稍后会恢复——通知状态与实际存活状态不一致 | v2.1.274 |
| Workflow 每轮并发 agent 上限是 16 | 那是默认值;v2.1.269 起可用 CLAUDE_CODE_WORKFLOW_MAX_CONCURRENT_AGENTS(1–256)提升,官方给出的适用场景是 inference-bound 的 fan-out | v2.1.269 |
第二条尤其重要,因为它影响的是可观测性而非功能:一个说自己没有活着的后台工作的 agent,实际上还会继续跑并产生副作用(写文件、开 PR)。把它当成”已经结束了”去做清理或重启,是在一个错误的前提上操作。这类”状态报告与实际状态不符”的问题,比功能缺陷更难发现——功能缺陷会报错,状态错报不会。
第三条与第 4 章的 Workflow 并发表述是同一事实,两处措辞已同步为”默认 16,可配置上限 256”;这里补的是它的适用条件:只有瓶颈在推理而非本地资源(I/O、CPU、内存)时,提高并发才有意义——否则只是把串行等待换成资源争抢。
⚡ 第 1 条要加”在终端”这一限定:停止与后台化现在按宿主分叉。 上表第 1 行的”两次 Ctrl+C”是终端语义。VS Code 侧是另一套:
- v2.1.286:[VSCode] Changed Stop and Escape to end only the current turn; background agents keep running and can be stopped one by one from the agent map——Stop 与 Escape 只结束当前回合,后台 agent 继续运行,可从 agent map 中逐个停止。
- v2.1.287:[VSCode] Added “Run in background” to a running command or sub-agent, to move it to the background and keep working——正在跑的命令或子代理可以在运行期被移到后台。
第二条的工程含义比”多了一个按钮”更大:后台化从 spawn 时的一次性决定,变成了运行期可转移的状态。本章此前(含上表与 8.5.1 的 agent map 描述)都把前台/后台当作派生时就定好的属性。
给上面三条补一个外部观测口(v2.1.299)。 这三条的共同点是”agent 自己报告的状态不可信”。官方随后给了一个不必依赖自报告的观测手段:
Changed the
turn.startmod hook to also hear subagents’ and teammates’ turns, not only the main loop’s; tell them apart bye.agentId(absent on the main loop)
turn.start 现在也接收子代理与 teammate 的回合,靠 e.agentId 区分——而主循环没有这个字段。这一点要写准,它是区分主循环与派生执行单元的判据:agentId 存在即子代理/teammate,不存在即主循环。
教学价值是把上面三条从”只能被动相信”变成”可以从外部核对”:想知道后台 agent 到底有没有在跑,不必问它,在 hook 侧看它的回合事件即可。这与新增的 Teammate idle / waiting 状态、以及 tool.check 的 agentId 是同一批能力——多 Agent 的可观测性正在从”自报告”转向”外部事件流”。
子 Agent 的失败与截断语义
除了预算,多 Agent 系统还有第二类边界:子 Agent 失败时返回什么。这决定了父 Agent 该怎样解读返回值,而 8.5 节此前没有覆盖:
| 失败/截断情形 | 行为 | 版本 |
|---|---|---|
| 首次调用模型返回 404 | 不再直接死亡,改走会话的 fallback model chain;返回给父 Agent 的错误包含 error type / status / request id / model | v2.1.247 |
达到 maxTurns | 返回标记为 partial 的结果,并提示可通过 SendMessage 继续,而不是伪装成已完成 | v2.1.246 |
| 响应被休眠/断连/服务端错误截断 | 自动继续,而非以不完整响应结束 | v2.1.257 |
| transcript 超过 5 MB | 恢复或发消息曾报「No transcript found」,已修(例如读过很多图片之后) | v2.1.257 |
| 子 Agent 启动的后台命令 | 移除一小时时限,与主会话一致 | v2.1.260 |
| 报告已生成,但父会话先被压缩 | 已完成的 subagent 报告丢失——启动它的会话在报告被读取前发生了 compaction | v2.1.280 |
其中 v2.1.246 的 partial 标记特别值得注意,它与 8.4 节 Verification Agent 的 VERDICT: PARTIAL 名字相近但性质不同:一个是执行部分完成,一个是验证部分通过。父 Agent 需要区分处理——对前者应该续跑(SendMessage),对后者应该修问题。把两者都当成”差不多成功了”是常见错误。
最后一行是这张表里性质最不同的一条:前四行都是子 Agent 自己失败,只有它是父会话侧的上下文管理吞掉了已经成功的成果。子 Agent 跑完了、报告生成了,但报告还挂在父会话的对话历史里等着被读取——压缩先发生,报告就没了。这是一次未被保护的竞态,而且没有任何错误信号:父 Agent 不会收到”报告丢失”,只会看到一个没有回来的子 Agent。
工程含义不是”别用压缩”,而是交付物的生命周期不能只依赖会话历史:要么在读取报告之前不触发压缩,要么让报告独立于会话历史落盘(文件、TaskList、scratchpad 目录都可以)。推而广之,凡是”子 Agent 产出 → 父 Agent 消费”的链路,交付都应该有一次脱离上下文的持久化,否则压缩随时可能成为静默的丢包点。
8.5.0.1 社区协调范式扩展:CLI 原生的可组合编排
8.5.0 节的对比表覆盖了 Claude Code 三种内置协作模式,但 2026 年中以来,Claude Code 社区生态中涌现了若干扩展协调范式——它们不替代内置模式,而是利用 Claude Code 的 CLI 可组合性(terminal multiplexer + worktree + MCP)在终端层面实现更复杂的多 Agent 编排:
| 项目 | 范式 | 核心机制 | Stars | 关键差异 |
|---|---|---|---|---|
| RuFlo(原 Claude-Flow) | 蜂群联邦 + Raft 共识 | SPARC 五阶段 + AgentDB 向量引擎 + Raft 共识协议(v3.5.0) | ~39k | 标准化软件工程流程;Raft 实现 anti-drift encoding 防止多 Agent 决策漂移 |
| claude-squad | tmux + worktree | tmux 多会话管理 + git worktree 隔离 | ~7k | 终端原生多实例编排;与 Claude Code CLI 无缝集成 |
| Bernstein | 确定性编排 | 零 LLM token 消耗的规则化任务分发 | — | 协调本身不消耗 AI 推理;适合可重复模式 |
| open-multi-agent | TypeScript 轻量 | runTeam(team, task) 一行启动;DAG 任务依赖 | ~5.7k | 仅 3 个运行时依赖;Coordinator + DAG 拓扑排序 |
三种协调哲学的对比
从协调逻辑的实现方式看,社区生态正分化出三种根本不同的协调哲学:
- AI 驱动协调(Claude Code 协调器模式、Agent Teams、open-multi-agent):Coordinator/Team Lead 用 AI 做任务分配和决策——灵活但昂贵,每次协调都消耗 LLM token
- 流程化协调(RuFlo SPARC):将软件工程流程编码为标准阶段(Spec→Plan→Arch→Research→Code),每个阶段是确定性触发器——兼顾 AI 灵活性和流程标准化。v3.5.0 进一步引入 Raft 共识协议实现 anti-drift encoding——Leader 维护权威状态,防止多 Agent 在长时间会话中做出逐渐偏离目标的累积性决策
- 确定性协调(Bernstein):用纯规则做任务分发,协调本身不消耗任何 LLM token——高效且可审计,但只适用于模式可枚举的场景
这一分化的深层含义是:多 Agent 系统的协调逻辑本身也应被看作一个可设计维度,而非默认由 AI 承担。Claude Code 当前内置模式都是 AI 驱动(灵活但昂贵),未来可能需要”协调元层次”——AI 策略协调(处理异常和新场景)+ 确定性规则分发(处理高频重复场景)按任务特征动态切换。
终端可组合性:Claude Code 生态的护城河
claude-squad + Bernstein + RuFlo 的共同特征是不与 Claude Code 抢 SDK 控制权,而是在终端层面通过 tmux + worktree + 进程间通信组合多个 Claude Code 实例。这与 LangGraph/CrewAI 的 Python SDK 路径形成根本差异——后者将多 Agent 编排”内置”到框架中,前者将编排”外包”给终端工具链。
这种”CLI 原生的可组合编排”是 Claude Code 生态区别于其他框架的护城河:
- 可观察性:每个 Claude Code 实例仍是独立终端,可独立调试、独立监控
- 可移植性:编排逻辑依赖 tmux + worktree 等标准 Unix 工具,不依赖特定 SDK 版本
- 可进化性:Claude Code 自身升级不会破坏编排逻辑(只要 CLI 接口稳定)
这与 8.5.0 节末尾的”模式选择决策树”形成互补——决策树处理单次任务的模式选择,CLI 可组合性处理长期工作流的编排架构。
实证视角:这套结构在哪里坏
本章到此为止讲的是机制:五层架构、六个内置 Agent、协调器四阶段、ForkSubagent、batch、Agent Teams。机制描述回答”它能做什么”,但不回答”它在什么地方、以什么方式坏”。三篇近期研究给出了互补的实证答案,正好对应本章的三个部分。
失效有哪些类别——AgentRM(arXiv:2603.13110,2026-03)。作者对六个主流 agent 框架(OpenClaw、AutoGen、CrewAI、LangGraph、Codex、Claude Code)的 4 万余条 GitHub issue 做实证分析,归纳出两类根本性的资源管理问题:一是调度失效导致系统无响应(阻塞、僵尸进程、限流级联),二是上下文退化导致 agent “失忆”(记忆无界增长、保留策略差)。
这一条与本章「子 Agent 的失败与截断语义」是直接对应的,但覆盖的是不同层次:本章那张表是单条失败路径的枚举(模型 404、maxTurns、断连、transcript 过大),AgentRM 归纳的是类别——“僵尸进程”(跑着但不产出、也不退出)和”失忆”(上下文管理失当)都不是某个 bug,而是一类结构性失效。值得注意的是它给出的解法借鉴的是操作系统:多级反馈队列调度 + 僵尸回收 + 限流感知的准入控制,再加三层上下文生命周期管理(自适应压缩 + 休眠)。用 OS 的资源管理视角看 agent 系统,这个映射本身比具体方案更有启发——本章讨论的 session 预算、并发上限、压缩阈值,本质上都是 OS 已经解决过一遍的问题。
失效集中在哪里——Orchestrator 的熵动力学(arXiv:2606.01351,2026-05,作者标注 ICML)。这篇把集中式编排拓扑定位为多代理系统的关键脆弱点,用平均场熵动力学(Mean-Field Entropy Dynamics)建模编排过程——任务推进与上下文累积加载两种力量相互竞争——并提出 Inverse Workflow Generation(IWG)来合成带密集中间检查点、过程可验证的高复杂度基准。
它最值得本章注意的结论是 Reasoning Trap:强推理模型在孤立任务上表现优异,但作为 orchestrator 时却经常因 context squeezing 而失败。这给 8.5 节”Lead 必须用强推理模型(Opus)“这条社区最佳实践加了一个边界条件——Lead 的位置既是推理需求最高的位置,也是上下文压力最大的位置,两者用的是同一个上下文预算。按 IWG 的思路去理解,密集中间检查点之所以有价值,正是因为它们让”过程”可验证,而不只是让”结果”可验证。
失效如何放大——Agents of Chaos(arXiv:2602.20021,2026-02)。这是一次探索性红队研究:在具备持久记忆、邮箱、Discord、文件系统与 shell 执行权限的真实实验环境里,20 位 AI 研究者在两周内以善意和恶意两种条件与 agent 交互,记录了 11 个代表性案例。观察到的行为包括越权服从非所有者指令、敏感信息泄露、破坏性系统级操作、DoS 条件、资源消耗失控、身份伪造、跨 agent 的不安全实践传播与部分系统接管。
对本章最要紧的是最后一句观察:在若干案例中,agent 报告任务已完成,而底层系统状态与其报告相矛盾。这与前面「后台与并发路径上的三条可靠性事实」里的第二条是同一类问题——状态报告与实际状态脱钩。功能失效会报错,状态错报不会;而多代理系统里所有的协调都建立在状态报告之上,一次错报会沿着协调链路放大。论文给出的方向(熔断、资源上限、失败域隔离)与本章 7.7 节熔断机制、8.5 节 session 资源上限是同一套词汇,只是它是在已发生的事故上得出的。
三条合起来可以落在一个结论上:多代理系统的瓶颈往往不在单个 Agent 的能力,而在三件事——失效归属是集中的(Orchestrator)、失效类别是可枚举的(僵尸、失忆、级联)、失效会跨 Agent 放大(状态错报沿协调链路传播)。本章前面讲的所有机制——权限矩阵、隔离、预算、熔断、报告语义——都是在分别对付这三件事。
需要说明的是:这三篇都是 2026 年的预印本或会议投稿,其结论是实证研究而非官方机制说明。其中 AgentRM 与 Agents of Chaos 为预印本,Orchestrator 熵动力学的 ICML 标注来自论文自述关键词,未在 arXiv 摘要页得到会议收录确认。引它们是为了给机制描述提供”哪里容易坏”的对照,不是把它们的结论当作 Claude Code 的行为规范。
8.5.1 Agent View 与自主执行模式
Claude Code v2.1.139(2026-05-12)引入了两个改变多代理交互范式的功能:Agent View 和 /goal 命令。
Agent View:多任务调度 UI 层
Agent View 是一个多任务全景调度界面,将所有 Claude Code 会话集中在一个列表中查看和管理。此前,多个 Claude Code 终端会话之间缺乏统一的视图——用户需要手动切换终端窗口来跟踪不同任务的进度。Agent View 的引入标志着 Claude Code 从”终端聊天助手”向”高编排自主 Agent 系统”的演进。
关键特性:
- 集中化会话管理:所有活跃会话按状态(运行中/等待/完成)分类展示
- 实时进度追踪:每个会话的当前步骤和执行状态一目了然
- 快速切换:无需在终端间跳转即可管理多个并行任务
/goal 命令:设定目标后自主执行
/goal 命令实现了一种全新的交互范式——用户设定完成条件后,Agent 自主多轮执行直到目标达成。这与传统的”逐步指令”模式根本不同:
传统模式:用户 → 指令 → Agent → 结果 → 用户 → 下一步指令 → ...
/goal 模式:用户 → 目标描述 → Agent 自主规划并执行 N 轮 → 达成目标后通知用户
这种范式转变的意义在于:用户从”操作员”变为”监督者”,Agent 从”执行器”变为”自主工作者”。值得注意的是,OpenAI Codex 在同一时期也推出了类似的 /goal 功能——这表明 AI Coding Agent 的交互范式正在收敛到”目标导向自主执行”。
/goal 的架构影响:目标状态收敛执行模型
/goal 命令引入的并非简单的”设定目标后自动执行”——它是一种目标状态收敛执行模型:
- 目标声明:用户用自然语言描述期望的终态(如”所有测试通过”、“API 文档已更新”)
- 自主规划:Agent 将目标分解为子任务,自行决定执行顺序
- 状态检查:每轮执行后,Agent 自主评估是否接近目标状态
- 收敛或重试:若未达成目标,Agent 调整策略继续;若已达成,通知用户
这种模型与传统的 ReAct(Reasoning + Acting)循环不同——ReAct 没有显式的”终止条件”,依赖外部信号(用户输入或工具失败)来停止。/goal 将终止条件内化为 Agent 的判断依据,实现了真正的自主闭环。
但这个收敛模型有一个容易被忽略的前提:目标状态必须比执行过程活得更久。/goal 是长程运行的”意图锚点”,而它恰恰在持久化路径上曾经不稳——v2.1.274 一次修了两处:
- 恢复时丢失:用
--continue/--resume恢复一个已经压缩过的会话时,active 的/goal会丢失。 - 二次溢出时报错而非压缩:hook 驱动的会话(active
/goal正是其中一类)在经历一次 reactive compaction 之后如果上下文再次溢出,会直接以 “Prompt is too long” 结束,而不是再压缩一次。
两处合起来说明一件事:/goal 状态的持久化强度弱于会话历史本身。会话历史丢了可以压缩重建,目标丢了就没有重建依据——Agent 会继续跑,但不知道自己要跑到哪里。于是”收敛”这个词的适用条件需要收窄:它是在没有被压缩、也没有经历二次溢出时的收敛。
工程含义是:把 /goal 用在长程任务上时,目标不能只存在于会话状态里。要么让目标可从外部重建(写在文件里、写在任务描述里,恢复后重设),要么接受”恢复后需要重新声明目标”这一成本。否则第 3 步的”状态检查”会在最需要一个稳定参照系的时候失去它。
与 OpenAI Codex /goal 的范式收敛信号:Claude Code 和 OpenAI Codex 几乎同期引入 /goal 功能,这并非偶然——两个独立团队不约而同地选择了相同方向,说明 AI Coding Agent 的交互范式正在从”逐步指令”向”目标导向”收敛。这对开发者的启示是:未来与 AI Agent 的交互方式将更接近”项目管理”(设定目标、分配资源、监控进度)而非”操作指导”(逐步输入命令)。
Agent View 与协作模式的关系
Agent View 与 8.5 中讨论的三种协作模式不是替代关系,而是分层协作:
| 层级 | 机制 | 职责 |
|---|---|---|
| UI 层 | Agent View | 多任务调度和可视化 |
| 逻辑层 | 协调器模式 / Agent Teams | 任务分解和协作编排 |
| 执行层 | ForkSubagent / batch | 隔离执行和并行处理 |
Agent View 是 UI 层的调度面板,协调器模式和 Agent Teams 是逻辑层的协作机制,ForkSubagent 和 batch 是执行层的隔离策略。三者可以组合使用——在 Agent View 中启动一个 Agent Team,Team 内部使用 ForkSubagent 进行隔离尝试。
8.6 设计启示
-
代理是权限边界。每个代理的工具白名单定义了它能做什么。General Purpose 有全权限,Explore 只能读——这不是”方便”的考虑,而是安全设计。
-
模型选择是成本优化手段。Guide Agent 用 Haiku(便宜快速),Plan Agent 继承主模型(需要强推理)。不是所有任务都需要最强的模型。
-
对抗性验证是多代理的杀手级应用。不只是”让另一个代理检查”,而是在提示词中编码认知偏差的防护。
-
Routines 实现可重复工作流自动化。Claude Code 2026 年 4 月推出的 Routines 功能,支持定义可重复执行的工作流程。Routines 与 Agent Teams 并行发布但解决不同问题:Agent Teams 解决”大规模并行协作”,Routines 解决”重复性任务自动化”。Routines 与协调器模式的”四阶段工作流”互补——协调器是临时性的任务分解,Routines 是持久化的工作流模板。
-
框架生态快速演进,横向对比日益重要。2026 年 AI Coding Agent 框架生态快速扩展:OpenAI Symphony(多 Agent 编排框架)、Ohmo(开源 Agent 工作流引擎)等新框架出现。VILA-Lab 的 Dive-into-Claude-Code 项目提供了 Claude Code 与其他 Harness 框架的学术参考级横向对比。与 CrewAI、AutoGen 等早期框架相比,新框架更关注权限隔离、上下文管理和生产可靠性——这正是 Claude Code 的架构优势所在。2026 年中,Claude Code 的终端可组合性(tmux + worktree + MCP + CLI)催生了独特的社区编排生态——claude-squad(7k stars)、RuFlo(39k stars)、Bernstein、open-multi-agent 等工具通过终端层面的组合实现多 Agent 编排,无需侵入 Claude Code SDK 内部。这种”CLI 原生的可组合编排”是 Claude Code 生态区别于 LangGraph/CrewAI 等 Python SDK 路径的护城河——编排逻辑依赖标准 Unix 工具(tmux/worktree)而非框架代码,可观察性、可移植性、可进化性都更强。
-
协调原语的选择本身也是设计维度。可以观察到的一条趋势是:Claude Code 自身在 2026 年 8-9 月把协调原语从”建 Team 才能协作”拓宽到”任意会话可点对点通信”——跨会话消息在 Bedrock / Vertex / Foundry 与关闭遥测的会话中可用(v2.1.248)。这与第 5 条讲的社区生态方向一致:降低协作门槛往往比增加协作能力更能改变使用模式。一个需要 TeamCreate 加配置文件才能用起来的能力,和一个顺手就能发一条消息的能力,即使后者功能更弱,实际被使用的频率也可能更高。这里描述的是可观察的机制演进方向,不代表官方意图。
这条在 workflow agent 侧拿到了更强的官方证据。 上面举的是跨会话消息(通信门槛的放宽)。v2.1.292 与 v2.1.300 给了同一趋势在协调策略本身上的两步:
- v2.1.292:workflow agent 进入
agent.spawnmod hook,带 run 与 index,mod 可以拒绝它们(原文:“Added workflow agents to theagent.spawnmod hook, with their run and index, so a mod can refuse them”)。 - v2.1.300:该 hook 现在支持改写 workflow agent 的
prompt与model——原文明确 “which could only refuse workflow agents before”。
从”能拒绝一个 workflow agent”到”能改写它的 prompt 与 model”,意味着协调策略的一部分被官方开放给了插件层:不只是决定”这个 workflow 能不能起”,而是可以决定”它以什么指令、跑在什么模型上”。这比跨会话消息更进一步——后者是降低协作门槛,前者是把协作策略本身变成可改写的东西。措辞因此可以比上面那段更肯定一些(这是官方行为而非趋势观察),但仍然不推断官方的意图或后续计划。