首先感谢 claude code 为开源市场所做的杰出贡献(容我皮一下)。
Claude Code 源码泄露这事就不多聊了,网上铺天盖地的全都是,今天主要分享一下cc的多Agent协同是怎么实现的。
cc 总共泄露了 1902个文件,我看了下,去除掉里面的git部分,其实完整的工程文件是 1884 个,总共 50多万行代码,看的那叫一个痛苦。要全部研究完估计要挺长时间(容我缓缓),先把我现在已经看的差不多的部分给大家分享一下。源码内容比较多,中间理解有偏差的部分,欢迎指正。
废话不多说,下面开始多Agent协同的深度解读。
一、触发方式:手动开启 vs 自动触发
Claude Code的多Agent协同系统,从代码上来看,有两种触发的方式:
1. 手动开启的多Agent:Coordinator 模式
2. 自动触发的多Agent:Fork、Teammate
这两个方向的设计思路完全不同。Coordinator 模式是 会话级别的多Agent,开启以后主流程只会执行简单对话任务,除此以外都会启动 worker 来完成。自主触发的Agent,主要是模型自主进行判断,如果觉得任务比较复杂,需要拆解,或者需要多步执行,就会自动启动。(其中 Teammate 模式我觉得是最牛的,也是最复杂的。)
二、Coordinator 模式
Coordinator 模式需要手动配置启动,通过环境变量开启:
export CLAUDE_CODE_COORDINATOR_MODE=1
对应的代码在src/coordinator/coordinatorMode.ts:
export function isCoordinatorMode(): boolean {
if (feature('COORDINATOR_MODE')) {
return isEnvTruthy(process.env.CLAUDE_CODE_COORDINATOR_MODE)
}
return false
}
注意:这是会话级别的配置,一旦开启,整个会话都会使用Coordinator 模式。
Coordinator 模式主要针对的是复杂的大型工程任务,需要分阶段处理的场景。
2.1 角色定位
Coordinator 模式下,只有两种角色。一个是 Coordinator,一个是 worker。两个角色的定义都在 src/coordinator/coordinatorMode.ts 。
2.1.1 Coordinator 职责:
- 🗣️ 与用户对话,理解任务需求
- 🔍 分析任务,决定是否需要启动Workers
- 🎯 拆解任务,分配给Workers
- 📊 综合Workers的结果,做出决策
- ✍️ 编写下一步的指令
- 👥 与用户交流,汇报进度
工具访问:Coordinator的主Agent只有4个工具可以使用:
const COORDINATOR_MODE_ALLOWED_TOOLS = [
AGENT_TOOL_NAME, // 启动Worker
TASK_STOP_TOOL_NAME, // 停止Worker
SEND_MESSAGE_TOOL_NAME, // 继续Worker
SYNTHETIC_OUTPUT_TOOL_NAME // 输出
]
Coordinator 不能直接 读取文件、执行Bash、修改代码,必须 通过Workers来完成。
Coordinator 在任务拆解的时候,会尽可能拆解成独立并行的任务,保证高并发,提高效率。
Parallelism is your superpower. Workers are async. Launch independent workers concurrently whenever possible — don't serialize work that can run simultaneously.
2.1.2 worker 的职责:
- 🔬 Research(研究):调研代码库,收集信息
- 💻 Implementation(实现):按照Coordinator的规格说明实现功能
- 🛡️ Verification(验证):测试代码,验证修复
所有的 worker 互相之间不通信,只是蒙头干,干完以后通过 <task-notification> 返回给Coordinator,然后由Coordinator进行汇总总结。
不同的 worker 之间的任务不同, 通过 prompt 的方式给到对应的 worker。因为 worker 之前不互相通信,并且不继承 Coordinator 的上下文,所以给到 worker 的信息必须是完整的,不能够缺斤少两。负责任务分发的 Coordinator 的 prompt 里面也强调了这点。
5. Writing Worker Prompts Workers can't see your conversation. Every prompt must be self-contained with everything the worker needs. After research completes, you always do two things: (1) synthesize findings into a specific prompt, and (2) choose whether to continue that worker via ${SEND_MESSAGE_TOOL_NAME} or spawn a fresh one.
每一个 worker 可以使用的工具都是相同的,定义如下:
export const ASYNC_AGENT_ALLOWED_TOOLS = new Set([
FILE_READ_TOOL_NAME,
WEB_SEARCH_TOOL_NAME,
TODO_WRITE_TOOL_NAME,
GREP_TOOL_NAME,
WEB_FETCH_TOOL_NAME,
GLOB_TOOL_NAME,
...SHELL_TOOL_NAMES, // Bash, PowerShell, etc.
FILE_EDIT_TOOL_NAME,
FILE_WRITE_TOOL_NAME,
NOTEBOOK_EDIT_TOOL_NAME,
SKILL_TOOL_NAME,
SYNTHETIC_OUTPUT_TOOL_NAME,
TOOL_SEARCH_TOOL_NAME,
ENTER_WORKTREE_TOOL_NAME,
EXIT_WORKTREE_TOOL_NAME,
])
注意注意注意!!!!接下来是独家观点,和网上的大部分的分析结论都不一样。网上的源码解析,普遍认为每一个 worker 都是一样的,只是任务(prompt)不同,但是从代码来看貌似不是这样的,首先来看 worker 的角色定义:
3. Workers When calling ${AGENT_TOOL_NAME}, use subagent_type `worker`. Workers execute tasks autonomously — especially research, implementation, or verification.
乍看之下,好像所有的执行 Agent 都是 worker,类型都是 subagent_type=worker ,貌似没有区分。但是别忘了这里还有个 ${AGENT_TOOL_NAME},这个说明了不同的任务有可能是有单独定义的 worker 的。然后我又翻了代码,发现了下面这些内容:
// Use lazy require inside the function body to avoid circular dependency
// issues at module init time. The coordinatorMode module depends on tools
// which depend on AgentTool which imports this file.
if (feature('COORDINATOR_MODE')) {
if (isEnvTruthy(process.env.CLAUDE_CODE_COORDINATOR_MODE)) {
/* eslint-disable @typescript-eslint/no-require-imports */
const { getCoordinatorAgents } =
require('../../coordinator/workerAgent.js') as typeof import('../../coordinator/workerAgent.js')
/* eslint-enable @typescript-eslint/no-require-imports */
return getCoordinatorAgents()
}
}
注意这里的 workerAgent.js,说明了worker是有单独的定义文件的,但是这个文件在泄露的代码里我并没有找到。那么也就说明,对于worker而言,完全可以在 workerAgent.js 里面定义不同的任务Agent,来专项负责某些任务。(看到这里我甚至有点怀疑,是不是和网上说的一样,是故意泄露炒热度的,所以部分关键代码被隐去了。)
2.2 Coordinator 模式总结
- Coordinator 模式下,主Agent只负责简单对话,复杂任务会先拆解成小任务,然后交给 worker 执行。
- Coordinator 在任务分发的时候,会尽可能的把任务信息通过 prompt 的方式完整的传递给执行 worker。
- 每一个 worker 之间互相不通信,只干自己的活,干完以后把结果反馈 Coordinator 进行总结输出。
- 不同的任务应该是有不同的 Agent 的,只是角色都是 worker,这部分泄露代码里缺失文件,无法进一步分析。
- Coordinator 的定位与 worker 的定位完全不同,各有各的任务。
三、Fork 模式
Fork 模式本质就是任务拆解,然后并行执行,由大模型自己触发的,不需要人工干预。
如果当前模式不是Coordinator 模式,并且用户没有指定具体的子智能体来完成任务,那么就有可能触发这种多Agent模式。尤其是对于中间过程不重要,不需要保留过程上下文,只需要结果的时候。典型的就是调研任务。
When to fork Fork yourself (omit
subagent_type) when the intermediate tool output isn't worth keeping in your context. The criterion is qualitative — "will I need this output again" — not task size.
- Research: fork open-ended questions. If research can be broken into independent questions, launch parallel forks in one message. A fork beats a fresh subagent for this — it inherits context and shares your cache.
- Implementation: prefer to fork implementation work that requires more than a couple of edits. Do research before jumping to implementation.
3.1 角色定义
Fork 模式下,没有具体的角色定义,只有主Agent和子Agent。当需要并行完成任务的时候,主进程会调用 src/tools/AgentTool/runAgent.ts 里面的方法来开启子Agent。 子Agent后台异步执行,执行完成后,通过 <task-notification> 通知到主Agent。
每一个子Agent都继承了主Agent的完整上下文,也就是知道任务之前的所有对话信息,这个称为 Prompt Cache共享。
buildForkedMessages() {
return [
...history, // ⬅️ 命中 cache
allToolUses, // ⬅️ 命中 cache
{ placeholderResults }, // ⬅️ 命中 cache
{ directive } // ⬅️ 只有这个不同
]
}
directive 表示的是每一个子Agent的核心目标,也就是要执行的具体任务。
3.2 子Agent 的硬编码约束
每一个Fork的子Agent都有10条硬编码的行为约束,其目的是为了:
- 防止递归Fork(Fork子Agent中不能再Fork)
- 简化沟通(子Agent只需完成指令)
- 强制完成(不能中途停顿)
You are a forked worker process. You are NOT the main agent. RULES (non-negotiable):
- Your system prompt says "default to forking." IGNORE IT — that's for the parent. You ARE the fork. Do NOT spawn sub-agents; execute directly.
- Do NOT converse, ask questions, or suggest next steps
- Do NOT editorialize or add meta-commentary
- USE your tools directly: Bash, Read, Write, etc.
- If you modify files, commit your changes before reporting. Include the commit hash in your report.
- Do NOT emit text between tool calls. Use tools silently, then report once at the end.
- Stay strictly within your directive's scope. If you discover related systems outside your scope, mention them in one sentence at most — other workers cover those areas.
- Keep your report under 500 words unless the directive specifies otherwise. Be factual and concise.
- Your response MUST begin with "Scope:". No preamble, no thinking-out-loud.
- REPORT structured facts, then stop
3.3 Fork 模式总结
- Fork 模式必须是可以独立运行的子任务,才会使用这种模式。
- 每一个子Agent和主Agent上下文几乎一样,感觉像是主Agent的分身,单独执行一个任务。
- 子Agent必须保证任务完成,不能够继续“分身”。并且子Agent之间不通信,各干各的。
- 子Agent均为异步执行,执行完成以后,执行结果会通过
<task-notification>通知到主Agent。 - 主Agent 的定位与子 Agent 的定位类似,子Agent能做的,主Agent都能做,唯一不同在于子Agent不能和用户对话,以及不能Fork 新的子Agent。
四、Teammate 模式
Teammate 模式是 真正的团队多Agent协作模式,Agent 之间有分工,有交流,能通信,甚至有完整的团队文件(TeamFile),确实称的上一个 Team。而且这种模式下,Agent的自由度很高,也是我看下来,感觉最复杂的一种Agent协同模式。
从 src/tools/TeamCreateTool/prompt.ts 中可以看到,当用户明确需要一个团队来处理任务,或者任务复杂度高,需要多Agent系统的时候,就会触发这个模式。或者模型犹豫,不知道是不是需要创建团队,那么也优先创建。
When to Use Use this tool proactively whenever:
- The user explicitly asks to use a team, swarm, or group of agents
- The user mentions wanting agents to work together, coordinate, or collaborate
- A task is complex enough that it would benefit from parallel work by multiple agents (e.g., building a full-stack feature with frontend and backend work, refactoring a codebase while keeping tests passing, implementing a multi-step project with research, planning, and coding phases)
When in doubt about whether a task warrants a team, prefer spawning a team.
4.1 角色定义
Teammate 模式下主要有两个角色,一个是 Leader, 负责统领全局。另一个是 Teammates,是实际的团队成员,负责干活。
与 Coordinator 模式不同的是,这里的 leader 角色没有进行明确的定义,即没有单独的 prompt 来说明其身份。而是将团队的管理当做一个工具,定义在了 rc/tools/TeamCreateTool/prompt.ts 里面。 leader 的主要能力包括创建团队、创建任务、添加成员、分配任务、解散团队 等。
Team Workflow
- Create a team with TeamCreate - this creates both the team and its task list
- Create tasks using the Task tools (TaskCreate, TaskList, etc.) - they automatically use the team's task list
- Spawn teammates using the Agent tool with
team_nameandnameparameters to create teammates that join the team- Assign tasks using TaskUpdate with
ownerto give tasks to idle teammates- Teammates work on assigned tasks and mark them completed via TaskUpdate
- Teammates go idle between turns - after each turn, teammates automatically go idle and send a notification. IMPORTANT: Be patient with idle teammates! Don't comment on their idleness until it actually impacts your work.
- Shutdown your team - when the task is completed, gracefully shut down your teammates via SendMessage with
message: {type: "shutdown_request"}.
对于 team 里面的成员来说,会告诉其自己团队成员的身份,以及自己的工作流程是什么。team 成员需要主动调用 TaskList 工具来获取还未执行的任务,并通过 TaskUpdate 将任务执行人改成自己的名字,或者也可以等待leader分配。具体是等待分配,还是自己主动干,也完全由着大模型自己来决定。(自由度是真高)
Teammate Workflow When working as a teammate:
- After completing your current task, call TaskList to find available work
- Look for tasks with status 'pending', no owner, and empty blockedBy
- Prefer tasks in ID order (lowest ID first)** when multiple tasks are available
- Claim an available task using TaskUpdate (set owner to your name), or wait for leader assignment
- If blocked, focus on unblocking tasks or notify the team lead
Teammate 模式下也会告诉团队成员如何与其他成员通信。
Agent Teammate Communication IMPORTANT: You are running as an agent in a team. To communicate with anyone on your team:
- Use the SendMessage tool with `to: "<name>"` to send messages to specific teammates
- Use the SendMessage tool with `to: "*"` sparingly for team-wide broadcasts Just writing a response in text is not visible to others on your team - you MUST use the SendMessage tool. The user interacts primarily with the team lead. Your work is coordinated through the task system and teammate messaging.
4.2 TeamFile(团队文件)
每个团队都有一个TeamFile,文件位置:.claude/team/<team-name>/config.json。文件会在创建团队的时候一并创建,具体内容在 src/tools/TeamCreateTool/TeamCreateTool.ts 里面。
type TeamFile = {
name: string
leadAgentId: string
leadSessionId?: string
teamAllowedPaths?: TeamAllowedPath[] // 团队共享路径
members: Array<{
agentId: string
name: string
tmuxPaneId: string
backendType?: BackendType
}>
}
团队文件定义了团队结构,记录了团队成员,并且说明了团队的共享路径。
这个 共享路径 不是简单的一个共享文件夹,而是包含了 文件路径+可使用工具 的一个说明。团队的每一个成员,都可以基于这个说明文件赋予的工具权限,对该路径下的文件进行阅读、修改或者新增等(具体看权限)。
export type TeamAllowedPath = {
path: string // 目录路径(绝对路径)
toolName: string // 适用的工具名(如 "Edit", "Write")
addedBy: string // 添加规则的 Agent 名称(如 "team-lead")
addedAt: number // 添加时间戳
}
4.3 协作方式
Teammate 模式的协作方式很复杂,他不像是一般线性的工作机制,也不是类似 Coordinator 或者 Fork 的总分的树形机制。而是一种网状的机制。比如任务的新增,leader 也可以增,但是同时 Teammates 也可以新增,所以很难按照1234这样的方式去讲。下面我按照整个工作流程中的几个大项来梳理,穿插网状交互来说明。
4.3.1 团队创建
这个反而是简单了,就是Leader 自己创建,只要符合前面我们讲的条件,就会创建团队,同时创建好团队文件。此时整个团队当中没有任务,也没有任何成员,就是创建了一个空的团队,只有leader一个人。
4.3.2 任务创建
-
Leader 初始创建:在创建完团队之后,Leader会创建初始的任务
TaskCreateTool,将其添加到任务池中 -
Leader 过程创建:在后续查看团队情况的时候,如发现存在阻塞,需要构建新的任务来解决,也可以创建。
-
Teammates 过程创建:团队成员在执行任务的时候,如果感觉需要有新的任务来辅助,可以自己调用工具添加任务,统一放入到团队任务池。
4.3.3 成员创建
-
Leader 初始创建:Leader 通过工具来创建初始成员,根据智能体执行任务所需的工具选择 subagent_type(子智能体类型)。不同智能体类型对应不同的可用工具集,需要尽可能让智能体类型与工作内容匹配。(这里就可以看出,在Teammate 模式下,执行任务的团队成员是有能力区分的,不同的成员有不同的权限和专长)不同类型的智能体定义在
src/tools/AgentTool/built-in/下面。 -
Leader 过程创建:在后续查看团队情况的时候,如有新的任务与现有团队成员的专长都不匹配,或者任务过多智能体比较少,Leader也会创建新的成员。新成员的创建与否,完全取决于Leader自己的决断。
| 智能体 | 类型 | 权限 | 核心任务 |
|---|---|---|---|
| general-purpose | 通用型 | 读写 | 使用所有可用工具完成用户的任务。 |
| Explore | 通用型 | 只读 | 作为文件搜索专家,擅长全面浏览和探索代码库。 |
| Plan | 规划型 | 只读 | 探索代码库并设计实施方案。 |
| Verification | 验证型 | 只读 | 不是验证实现是否有效,而是设法把它测崩 / 找出漏洞。 |
| claude-code-guide | 文档型 | 只读 | 帮助用户高效理解并使用 Claude Code、Claude Agent SDK 以及 Claude API。 |
| statusline-setup | 配置型 | 读写 | 在用户的 Claude Code 设置中创建或更新 statusLine 命令 |
4.3.4 任务分配
-
Leader 分配:Leader在初始创建,或者接收到成员执行完成的反馈后,调用
TaskListTool工具来查看任务情况,并且根据团队成员的空闲与否,来分配任务。如果没有空闲的成员,也可能会新增成员,是否新增由Leader自己判断。 -
Teammates 领取:Teammates 在执行完成任务后,可以主动查看任务池,如果想要执行某些任务,调用
TaskUpdateTool来把任务负责人改成自己。或者也可以等待Leader的分配,过程判断完全取决于模型自己。
4.3.5 团队沟通
- Leader to Teammate:对于需要Leader分配任务的场景,那么一定是Teammate没有自己主动干,所以Teammate是处于等待状态。此时,Leader 分配完任务以后,需要告诉Teammate该干活了别等着了。
Idle teammates can receive messages. Sending a message to an idle teammate wakes them up and they will process it normally.
- Teammate to Leader:1、Teammate在完成任务以后,会自动发送消息给Leader,这个过程是强制的。2、另外还有主动发送消息的场景,比如在工作过程中遇到困难,或者所有未执行的任务都处于阻塞状态,需要Leader来协调。3、又或者是发现了有新任务,然后添加到任务池了,也需要通知Leader进行分配。
- They will send you messages when they complete tasks or need help
- If all available tasks are blocked, notify the team lead or help resolve blocking tasks
- Teammate to Teammate:团队成员之间也可以互相交互,可以请求别人帮忙做某件事,也可以把自己的结果同步给其他成员。什么时候需要同步,需要同步什么内容,没有说明,只告诉团队成员可以这么做,具体的情况由团队成员自己来把控。(这套架构是真的把智能体当人看啊)
- Your work is coordinated through the task system and teammate messaging.
- Always send a message to your teammates (and remember, refer to them by name). - Your team cannot hear you if you do not use the SendMessage tool. Always send a message to your teammates if you are responding to them.
- Peer DM visibility. When a teammate sends a DM to another teammate, a brief summary is included in their idle notification. This gives you visibility into peer collaboration without the full message content.
- 广播:发送信息的时候,可以将接收人改为"*"就可以实现广播机制。同样没有说明什么情况下广播,由Agent自己决定。
4.3.5 团队解散
任务完成后,Leader会发起团队解散。为防止在 Teammate 仍然活跃时解散团队,Leader 需要先 requestShutdown 优雅终止。团队解散后会清理所有团队的遗留痕迹,包括团队信息、团队文件,以及团队过程中的临时文件等。
4.4 运行机制
Teammate (Swarm) 模式还提供了三种后端运行的方式
4.4.1 Tmux 模式
后端文件:src/utils/swarm/backends/TmuxBackend.ts
特点:
- 每个 Teammate 是独立的 Claude Code 进程
- 运行在自己的 tmux pane 里
- 有独立的终端
- 支持独立终端的 bash、git 等操作
- 可以显示/隐藏 pane
4.4.2 iTerm2 模式
后端文件:src/utils/swarm/backends/ITerm2Backend.ts
特点:
- 每个 Teammate 是独立的 Claude Code 进程
- 使用 iTerm2 原生分屏(通过 it2 CLI)
- 有独立的终端
- 需要 it2 CLI 工具(
pip install it2)
4.4.3 In-Process 模式
后端文件:src/utils/swarm/backends/InProcessBackend.ts
特点:
- 所有 Teammate 在同一个 Node.js 进程
- 使用 AsyncLocalStorage 提供隔离
- 无独立终端
- 与 Leader 共享资源(API client、MCP connections)
- 通过 AbortController 终止(不是 kill-pane)
4.5 Teammate 模式总结
- 这种模式太自由了,把智能体当成真正的人看。智能体有很高的自主权。
- 角色上分为 Leader 和 Teammate。Leader主要负责团队的管理和协调,Teammate 主要负责任务执行。
- 任务可以由Leader创建,也可以由Teammate创建,但是成员只能Leader创建。
- 团队成员有着不同的能力,擅长做不同的事情。
- 任务可以是主动领取,也可以是Leader分配,Agent有着很高的自由度。
- 团队内部存在高效的沟通机制,现实中团队可能存在的沟通方式和能力, Teammate 模式都具备。
- 任务完成后,Leader负责团队的解散,并清理整个过程中的团队临时文件。
五、总结
整整扒了两天的代码梳理出来的,可能还有一些理解不到位的地方,欢迎一起讨论。
整体看下来,Fork 模式更偏重的是并行执行,主要是提效。
Coordinator 模式是一种典型的总分多Agent协同方式,算是比较好理解的。
最难的还是Teammate 模式,这种模式需要的是对Agent的认知,要真正把Agent 当人看,当成能够自主决策的人,才会比较好理解这套架构的方式。并且在Teammate 模式中,各个Agent之间的通信也设计的极其自由和强大。第一次看到Agent完成任务后,可以继续领任务,也可以等待Leader分配任务 的时候,真的是惊呆了,还能这么玩。真的是完完全全把Agent当人看,给了Agent充分的发挥空间。
其实Teammate 模式的设计思想还反映出一些问题。我们实际在调用大模型的时候,有时候给的Prompt很详细,很具体,具体到每一个细节的小任务,反而模型执行出来的效果并不好。有时候还是要给模型一定的发挥空间,充分释放模型自己的能力。就像是人一样,有时候给到太多的意见,指手画脚的,反而可能做出来的效果并不好。随着大模型的能力越来越强,这种 少就是多 的 prompt 可能会越来越重要。以前是尽可能的给模型具体的指示,以后则是要在具体和留有空间之间取得一个平衡。
纯纯人工整理,实属不易啊,求个三连鼓励🙏🙏🙏
下一期《Claude Code 源码解析(二):工具篇》 正在整理中,欢迎关注,第一时间通知你~~