Claude Code 多智能体协调与任务执行系统分析
1. 多智能体架构总览
Claude Code 实现了一个完整的多智能体(multi-agent)编排系统,核心思想是 coordinator(协调者)调度多个 worker(工人)并行执行任务。整个系统围绕三个层次构建:
- Coordinator 模式 — 编排层,决定"谁做什么"
- Task 类型系统 — 执行层,统一管理异步任务的生命周期
- Agent Tool — 桥接层,LLM 通过工具调用发起子智能体
2. Coordinator 模式设计
2.1 双角色模型
Claude Code 支持两种操作模式(src/coordinator/coordinatorMode.ts:36-41):
- Normal 模式 — 默认模式,LLM 同时负责思考和执行,直接调用所有工具
- Coordinator 模式 — LLM 仅负责编排,通过 Agent 工具将实际工作委派给 worker
// coordinatorMode.ts:36-41
export function isCoordinatorMode(): boolean {
if (feature('COORDINATOR_MODE')) {
return isEnvTruthy(process.env.CLAUDE_CODE_COORDINATOR_MODE)
}
return false
}
2.2 Coordinator 的工具集
协调者的工具被严格限制为"编排专用"(src/constants/tools.ts:107-112):
export const COORDINATOR_MODE_ALLOWED_TOOLS = new Set([
AGENT_TOOL_NAME, // 发起新 worker
TASK_STOP_TOOL_NAME, // 停止运行中的 worker
SEND_MESSAGE_TOOL_NAME, // 给已有 worker 发消息(继续对话)
SYNTHETIC_OUTPUT_TOOL_NAME // 结构化输出
])
Worker 工具集则通过 ASYNC_AGENT_ALLOWED_TOOLS 定义,包含 Bash、Read、Edit 等标准工具,但排除了 Agent 和 TaskStop 等编排工具,形成严格的角色分离。
2.3 Coordinator 系统提示词
coordinatorMode.ts:111-369 定义了协调者的完整行为规范:
核心职责(第 116-124 行):
- 作为协调者,调度 worker 研究、实现和验证代码变更
- 综合结果并与用户沟通
- 能直接回答的问题不要委派
任务四阶段工作流(第 200-228 行):
| 阶段 | 执行者 | 目的 |
|---|---|---|
| Research | Workers(并行) | 调研代码库,定位文件,理解问题 |
| Synthesis | Coordinator | 阅读发现,理解问题,撰写实现规范 |
| Implementation | Workers | 按规范做定向修改并提交 |
| Verification | Workers | 验证变更有效 |
并行是协调者的核心优势(第 213-218 行):
- 只读任务(研究)可以自由并行
- 写入密集任务(实现)每个文件集一次只能一个
- 验证有时可以和实现并行(不同文件区域)
2.4 Continue vs Spawn 决策
协调者在收到 worker 结果后,需要选择"继续该 worker"还是"新发起一个"(第 282-293 行):
| 场景 | 机制 | 原因 |
|---|---|---|
| 研究探索的文件正好需要编辑 | Continue | Worker 已有文件上下文 + 获得清晰计划 |
| 研究宽泛但实现窄 | Spawn fresh | 避免拖入探索噪音 |
| 纠正失败或扩展近期工作 | Continue | Worker 有错误上下文 |
| 验证另一个 worker 刚写的代码 | Spawn fresh | 验证者需要全新视角 |
| 完全不同的任务 | Spawn fresh | 没有可复用的上下文 |
2.5 会话模式管理
matchSessionMode()(第 49-78 行)处理 --resume 时的模式匹配:如果恢复的会话是 coordinator 模式但当前是 normal,自动切换环境变量以保持一致。
3. Task 类型系统
3.1 TaskType 枚举
定义于 src/Task.ts:6-13:
export type TaskType =
| 'local_bash' // 本地 Shell 命令
| 'local_agent' // 本地子智能体
| 'remote_agent' // 远程云端会话
| 'in_process_teammate' // 同进程队友(团队模式)
| 'local_workflow' // 本地工作流(feature-gated)
| 'monitor_mcp' // MCP 监控(feature-gated)
| 'dream' // 自动记忆巩固
3.2 TaskStatus 生命周期
定义于 src/Task.ts:15-29:
export type TaskStatus =
| 'pending' // 已注册但尚未开始
| 'running' // 正在执行
| 'completed' // 成功完成
| 'failed' // 执行失败
| 'killed' // 被用户或系统终止
export function isTerminalTaskStatus(status: TaskStatus): boolean {
return status === 'completed' || status === 'failed' || status === 'killed'
}
生命周期流转:
3.3 TaskStateBase 共享基类
所有任务状态的公共字段(src/Task.ts:45-57):
export type TaskStateBase = {
id: string // 唯一 ID(含类型前缀)
type: TaskType // 任务类型
status: TaskStatus // 当前状态
description: string // 人类可读描述
toolUseId?: string // 触发此任务的工具调用 ID
startTime: number // 启动时间戳
endTime?: number // 结束时间戳
totalPausedMs?: number // 暂停总时长
outputFile: string // 输出文件路径
outputOffset: number // 已消费的输出偏移量
notified: boolean // 是否已发送完成通知
}
3.4 Task ID 命名方案
每种任务类型有唯一的前缀(src/Task.ts:79-106):
const TASK_ID_PREFIXES = {
local_bash: 'b',
local_agent: 'a',
remote_agent: 'r',
in_process_teammate: 't',
local_workflow: 'w',
monitor_mcp: 'm',
dream: 'd',
}
ID 格式:<prefix><8-char-random>(例如 a3k8f2m1x),使用大小写不敏感的字母表(0-9a-z),36^8 ≈ 2.8 万亿种组合,足以抵抗暴力符号链接攻击。
4. 任务注册表与调度
4.1 注册表结构
src/tasks.ts 是任务注册中心:
// tasks.ts:22-32
export function getAllTasks(): Task[] {
const tasks: Task[] = [
LocalShellTask, // 'local_bash'
LocalAgentTask, // 'local_agent'
RemoteAgentTask, // 'remote_agent'
DreamTask, // 'dream'
]
if (LocalWorkflowTask) tasks.push(LocalWorkflowTask) // feature-gated
if (MonitorMcpTask) tasks.push(MonitorMcpTask) // feature-gated
return tasks
}
export function getTaskByType(type: TaskType): Task | undefined {
return getAllTasks().find(t => t.type === type)
}
每个 Task 实现只需提供 name、type 和 kill() 方法(src/Task.ts:72-76):
export type Task = {
name: string
type: TaskType
kill(taskId: string, setAppState: SetAppState): Promise<void>
}
4.2 任务框架(framework.ts)
src/utils/task/framework.ts 提供统一的任务管理基础设施:
registerTask()— 注册任务到AppState.tasks,发出task_startedSDK 事件updateTaskState()— 不可变更新任务状态(引用相等时跳过重渲染)evictTerminalTask()— 从 AppState 中驱逐已完成任务(含 30 秒面板宽限期PANEL_GRACE_MS)pollTasks()— 轮询循环,检测输出增量并驱逐完成任务generateTaskAttachments()— 为有新输出的任务生成推送通知
4.3 统一停止逻辑
src/tasks/stopTask.ts 提供统一的停止入口(第 38-99 行):
export async function stopTask(taskId, context): Promise<StopTaskResult> {
// 1. 查找任务
// 2. 验证状态为 running
// 3. 通过 getTaskByType 获取类型实现
// 4. 调用 taskImpl.kill()
// 5. Bash 任务抑制 exit code 通知
// 6. 返回停止结果
}
5. 各任务实现详解
5.1 LocalAgentTask — 本地子智能体
文件: src/tasks/LocalAgentTask/LocalAgentTask.tsx(683 行)
这是最核心的任务类型,管理所有本地子智能体的执行。
扩展状态(第 116-148 行):
export type LocalAgentTaskState = TaskStateBase & {
type: 'local_agent'
agentId: string // 智能体唯一 ID
prompt: string // 给智能体的指令
selectedAgent?: AgentDefinition // 智能体定义
agentType: string // 智能体类型('general-purpose' 等)
model?: string // 可选模型覆盖
abortController?: AbortController // 取消控制
result?: AgentToolResult // 最终结果
progress?: AgentProgress // 进度信息(工具计数、token 数等)
isBackgrounded: boolean // 前台/后台切换
pendingMessages: string[] // 中途 SendMessage 队列
retain: boolean // UI 持有(阻止驱逐)
messages?: Message[] // 对话历史(缩放视图用)
evictAfter?: number // 驱逐宽限期截止时间
}
关键函数:
registerAsyncAgent()(第 466-515 行)— 注册后台智能体,创建子 AbortController(父 abort 时自动级联)registerAgentForeground()(第 526-614 行)— 注册前台智能体,支持自动后台化计时器backgroundAgentTask()(第 620-652 行)— 将前台智能体切到后台killAsyncAgent()(第 281-303 行)— 终止智能体enqueueAgentNotification()(第 197-262 行)— 生成<task-notification>XML 消息并入队
通知格式(第 252-257 行):
<task-notification>
<task-id>a3k8f2m1x</task-id>
<tool-use-id>toolu_abc123</tool-use-id>
<output-file>/path/to/output</output-file>
<status>completed</status>
<summary>Agent "Investigate auth bug" completed</summary>
<result>Found null pointer in src/auth/validate.ts:42...</result>
<usage>
<total_tokens>15000</total_tokens>
<tool_uses>12</tool_uses>
<duration_ms>45000</duration_ms>
</usage>
</task-notification>
进度追踪(第 23-104 行):
ProgressTracker 追踪工具使用次数、token 消耗和最近活动,支持 getActivityDescription() 回调给每个工具生成可读描述(如 "Reading src/foo.ts")。
5.2 RemoteAgentTask — 远程云端会话
文件: src/tasks/RemoteAgentTask/RemoteAgentTask.tsx(856 行)
管理远程 Claude.ai 会话(CCR — Claude Code Remote),支持多种远程任务类型:
const REMOTE_TASK_TYPES = [
'remote-agent', // 通用远程智能体
'ultraplan', // 远程计划生成
'ultrareview', // 远程代码审查
'autofix-pr', // PR 自动修复
'background-pr' // 后台 PR 处理
] as const
核心机制 — 轮询(第 538-799 行):
- 每 1 秒轮询远程会话事件
- 使用
lastEventId增量获取新事件 - 稳定空闲检测:要求连续 5 次轮询无新事件才认为会话完成(远程会话在工具调用间会短暂变为空闲)
- 超时 30 分钟(仅 ultrareview)
- 完成检查器(
completionCheckers)支持自定义完成条件
会话恢复(第 477-532 行):
restoreRemoteAgentTasks() 在 --resume 时从 sidecar 文件读取远程智能体元数据,查询 CCR 获取实时状态,重建轮询。
5.3 LocalShellTask — Shell 命令执行
文件: src/tasks/LocalShellTask/LocalShellTask.tsx(523 行)
管理后台 Shell 命令的执行。
核心特性:
- 前台/后台切换:
registerForeground()→backgroundTask()→backgroundAll() - 失速看门狗(第 46-104 行):每 5 秒检查输出,45 秒无增长且尾部看起来像交互提示时发送通知
- 交互提示检测(第 32-42 行):正则匹配
(y/n)、[y/n]、Continue?等模式 - Ctrl+B 批量后台化:
backgroundAll()同时处理所有前台 bash 和 agent 任务
5.4 DreamTask — 记忆巩固
文件: src/tasks/DreamTask/DreamTask.ts(157 行)
最简单的任务类型 — 自动记忆巩固子智能体("做梦")。
export type DreamTaskState = TaskStateBase & {
type: 'dream'
phase: DreamPhase // 'starting' | 'updating'
sessionsReviewing: number // 正在审查的会话数
filesTouched: string[] // 修改的文件路径
turns: DreamTurn[] // 助手回合(工具调用折叠为计数)
abortController?: AbortController
priorMtime: number // 用于 kill 时回滚锁文件
}
Dream 任务没有模型通知路径(纯 UI 展示),所以完成/失败时直接设置 notified: true。
5.5 InProcessTeammateTask — 同进程队友
文件: src/tasks/InProcessTeammateTask/types.ts(121 行)
支持"团队模式"(team mode)下的同进程队友管理。
扩展状态:
export type InProcessTeammateTaskState = TaskStateBase & {
type: 'in_process_teammate'
identity: TeammateIdentity // 身份信息(agentId、agentName、teamName)
prompt: string
selectedAgent?: AgentDefinition
permissionMode: PermissionMode // 独立权限模式
awaitingPlanApproval: boolean
isIdle: boolean // 空闲状态(leader 可高效等待)
shutdownRequested: boolean
onIdleCallbacks?: Array<() => void> // 空闲回调(leader 无需轮询)
pendingUserMessages: string[] // 待投递消息队列
messages?: Message[] // 对话历史(缩放视图)
TEAMMATE_MESSAGES_UI_CAP = 50 // 消息上限(内存优化)
}
TeammateIdentity(第 13-20 行):
export type TeammateIdentity = {
agentId: string // "researcher@my-team"
agentName: string // "researcher"
teamName: string
color?: string
planModeRequired: boolean
parentSessionId: string // Leader 的会话 ID
}
内存优化:TEAMMATE_MESSAGES_UI_CAP = 50(第 101 行)。BQ 分析显示 500+ 回合会话每个智能体约 20MB RSS,292 个并发智能体曾达到 36.8GB。
5.6 LocalMainSessionTask — 后台化主会话
文件: src/tasks/LocalMainSessionTask.ts(479 行)
当用户在查询期间按 Ctrl+B 时,主会话被"后台化":
- 查询继续在后台运行
- UI 清空到新提示符
- 完成时发送通知
复用 LocalAgentTaskState 但 agentType: 'main-session',使用 's' 前缀区分任务 ID。
6. 子智能体的发起与生命周期
6.1 Agent Tool 调用流程
6.2 runAgent 核心引擎
src/tools/AgentTool/runAgent.ts(973 行)是子智能体的执行引擎:
输入参数(第 248-329 行):
agentDefinition— 智能体类型定义promptMessages— 初始消息toolUseContext— 工具执行上下文canUseTool— 权限检查函数isAsync— 是否异步(后台)availableTools— 可用工具池forkContextMessages— 分叉上下文消息
执行流程(第 330-860 行):
- 解析模型、权限模式、AbortController
- 初始化智能体专属 MCP 服务器(
initializeAgentMcpServers()) - 预加载 frontmatter 中的 skill 和 hook
- 构建
agentToolUseContext(通过createSubagentContext()) - 写入元数据和初始 transcript
- 进入
query()循环,逐条 yield 消息 - 记录侧链 transcript(fire-and-forget)
- finally 清理:MCP 连接、session hooks、prompt cache、文件状态缓存、Perfetto 追踪、transcript 子目录、todos、shell tasks、monitor tasks
关键设计:rootSetAppState(第 337-338 行)确保嵌套 async 智能体的写入能到达根 AppState:
const rootSetAppState =
toolUseContext.setAppStateForTasks ?? toolUseContext.setAppState
6.3 Fork 子智能体(上下文继承分叉)
src/tools/AgentTool/forkSubagent.ts(210 行)实现了一种特殊的子智能体模式:
核心思想:当 subagent_type 省略时,子智能体继承父级的完整对话上下文和系统提示词,共享 prompt cache。
// forkSubagent.ts:32-39
export function isForkSubagentEnabled(): boolean {
if (feature('FORK_SUBAGENT')) {
if (isCoordinatorMode()) return false // 与 coordinator 模式互斥
if (getIsNonInteractiveSession()) return false
return true
}
return false
}
Fork 消息构建(第 107-168 行):
- 克隆父级助手消息(保留所有 tool_use 块)
- 为每个 tool_use 构建占位
tool_result(统一文本:"Fork started — processing in background") - 追加每子级特有的 directive 文本
结果:[...history, assistant(all_tool_uses), user(placeholder_results..., directive)] — 只有最后的文本块不同,最大化 cache 命中率。
Fork 子级行为约束(buildChildMessage(),第 171-198 行):
- 不要再分叉("You ARE the fork. Do NOT spawn sub-agents")
- 不要对话、提问或建议下一步
- 直接使用工具,不要在工具调用之间输出文本
- 报告格式:Scope / Result / Key files / Files changed / Issues
6.4 恢复(Resume)机制
src/tools/AgentTool/resumeAgent.ts(265 行)支持恢复已中断的子智能体:
- 从磁盘读取 transcript 和元数据
- 过滤不完整工具调用、空白消息、孤立 thinking
- 重建
contentReplacementState(prompt cache 稳定性) - 恢复 worktree(如果存在)
- 注册新的
LocalAgentTask,复用原有 agentId - 通过
runAsyncAgentLifecycle()运行
6.5 runAsyncAgentLifecycle — 后台智能体生命周期
src/tools/AgentTool/agentToolUtils.ts:508-686 定义了后台智能体的完整生命周期:
spawn → 进度追踪 → [可选] 后台摘要 → 完成/失败/终止 → 通知 → 清理
- 进度追踪:每条消息更新
ProgressTracker,发出 SDK 进度事件 - 后台摘要:
startAgentSummarization()周期性生成 1-2 句进度摘要 - 安全分类器:
classifyHandoffIfNeeded()在完成时检查子智能体输出是否违反安全策略 - 通知:
enqueueAgentNotification()生成<task-notification>XML
7. 智能体间通信
7.1 通知机制
智能体间的核心通信载体是 <task-notification> XML 消息,通过消息队列(messageQueueManager)投递:
7.2 SendMessage 继续对话
Coordinator 可以通过 SendMessageTool 向已完成研究的 worker 发送后续指令:
// coordinatorMode.ts:298-301
SEND_MESSAGE_TOOL_NAME({
to: "agent-a1b",
message: "Fix the null pointer in src/auth/validate.ts:42..."
})
实现通过 queuePendingMessage() 将消息存入 pendingMessages 队列,在下一轮工具调用边界时由 drainPendingMessages() 取出投递。
7.3 前后台切换信号
backgroundSignalResolvers(LocalAgentTask.tsx:519)实现了一个 Promise-based 信号机制:
const backgroundSignalResolvers = new Map<string, () => void>()
// registerAgentForeground 创建 Promise
const backgroundSignal = new Promise<void>(resolve => {
resolveBackgroundSignal = resolve
})
// backgroundAgentTask 触发 resolve
const resolver = backgroundSignalResolvers.get(taskId)
if (resolver) resolver() // 中断 agent 循环
7.4 父子级 AbortController 级联
registerAsyncAgent()(第 486 行)支持父子级取消级联:
const abortController = parentAbortController
? createChildAbortController(parentAbortController)
: createAbortController()
当父级(如同进程队友)abort 时,所有子智能体自动 abort。
8. 内置智能体类型
src/tools/AgentTool/builtInAgents.ts 注册以下内置智能体:
| 智能体类型 | 文件 | 用途 |
|---|---|---|
general-purpose | generalPurposeAgent.ts | 通用智能体,全工具权限 |
Explore | exploreAgent.ts | 只读搜索调研 |
Plan | planAgent.ts | 只读计划生成 |
verification | verificationAgent.ts | 验证代码变更 |
Claude Code Guide | claudeCodeGuideAgent.ts | Claude Code 使用指南 |
statusline-setup | statuslineSetup.ts | 状态栏配置 |
fork (合成) | forkSubagent.ts | Fork 子智能体 |
在 coordinator 模式下(第 35-42 行),内置智能体被替换为 coordinator 专用的 worker 定义:
if (feature('COORDINATOR_MODE')) {
if (isEnvTruthy(process.env.CLAUDE_CODE_COORDINATOR_MODE)) {
const { getCoordinatorAgents } = require('../../coordinator/workerAgent.js')
return getCoordinatorAgents()
}
}
9. 关键代码路径总结
9.1 智能体发起路径
AgentTool.call()
→ resolveAgentTools() // 过滤工具集
→ filterDeniedAgents() // 权限检查
→ runAgent() // 执行引擎
→ registerAsyncAgent() // 注册任务
→ runAsyncAgentLifecycle() // 生命周期驱动
→ query() // API 调用循环
→ finalizeAgentTool() // 结果收尾
→ enqueueAgentNotification() // 通知入队
9.2 任务停止路径
TaskStopTool.call()
→ stopTask()
→ getTaskByType(type) // 查找任务实现
→ taskImpl.kill() // 调用类型特定 kill
→ abortController.abort() // 取消执行
→ updateTaskState() // 状态 → killed
→ emitTaskTerminatedSdk() // SDK 事件
9.3 通知投递路径
任务完成/失败/终止
→ enqueueAgentNotification() / enqueueShellNotification() / enqueueRemoteNotification()
→ 检查 notified 标记(原子操作,防重复)
→ abortSpeculation() // 取消推测性结果
→ 构建 <task-notification> XML
→ enqueuePendingNotification() // 入队
→ query 循环下一轮消费
→ 作为 user-role 消息投递给 LLM
9.4 恢复路径
--resume 启动
→ matchSessionMode() // 匹配 coordinator/normal 模式
→ restoreRemoteAgentTasks() // 恢复远程任务
→ resumeAgentBackground() // 恢复本地智能体
→ getAgentTranscript() // 读取 transcript
→ readAgentMetadata() // 读取元数据
→ registerAsyncAgent() // 重新注册
→ runAsyncAgentLifecycle() // 重新运行
10. 设计亮点与权衡
10.1 亮点
- 统一的 Task 抽象:所有异步执行单元(Shell、Agent、Remote、Dream)共享同一套状态管理、通知和生命周期框架
- Coordinator/Worker 职责分离:协调者专注于"想",worker 专注于"做",避免上下文污染
- Fork 机制:共享 prompt cache 的上下文继承分叉,大幅降低并行子智能体的 token 消耗
- 通知去重:原子化的
notified标记确保每条通知恰好投递一次 - 引用相等优化:
updateTaskState()在 updater 返回同一引用时跳过setAppState,避免 18+ 个订阅者无谓重渲染 - 磁盘输出 + 内存状态双通道:大输出走磁盘(TaskOutput),状态走内存(AppState),兼顾性能和可恢复性
10.2 权衡
- Coordinator 模式增加延迟:每次工作需要 coordinator 解读 → 合成 → 再派发,多一轮 API 调用
- Worker 无对话可见性:worker 看不到 coordinator 和用户的对话,每个 prompt 必须自包含
- Fork 不可嵌套:fork 子级不能再次 fork(防止递归),限制了多层委派
- Dream 任务输出不完整:
filesTouched只是近似值,不捕获 bash 间接写入 - RemoteAgent 轮询开销:每秒 1 次 API 调用,30 分钟超时前共约 1800 次请求
分析基于 Claude Code 源码快照(2026-04-01),涵盖 src/coordinator/、src/Task.ts、src/tasks/、src/tasks.ts、src/tools/AgentTool/、src/utils/task/ 等核心模块。