Multi-Agent 的两种解法:拆解 Claude Code 与 Codex
引言:什么时候单 agent 不够用了
你给 Claude Code 一个任务:”帮我把这个 React 项目从 Webpack 迁到 Vite,所有相关配置都改一下,跑通测试再提个 PR。”
它接活、读文件、改代码、跑测试、再改、再跑,半小时后回你一句”搞定,PR 已提”。这是单 agent 模式 —— 一个 AI 进程从头干到尾。
但你换个任务:”帮我调研 5 个开源 vector DB(Qdrant / Milvus / Weaviate / pgvector / Chroma),各做一个 100 万向量的 benchmark,最后出一份对比报告。”
单 agent 立刻就崩了:
- Context 装不下 5 个项目的源码 + 5 份 benchmark log + 1 份报告,加起来轻松 50 万 token,超过任何模型的 context window
- 没法并行 5 个 benchmark 串行跑要 5 倍时间
- 角色混乱 同一个 AI 既要做调研、又要写代码、又要分析数据、又要写报告,在不同思维模式之间频繁切换,质量普遍下降
这种任务的解法是 Multi-Agent —— 把任务拆成多个子任务,每个交给一个独立的 AI 子进程跑,主 agent 负责协调。
业界两个最有影响力的开源 / 半开源 AI CLI 工具 —— Anthropic 的 Claude Code 和 OpenAI 的 Codex —— 都做了 multi-agent 能力。但思路完全不同:
- Claude Code 走 “委派 (delegation)“ 路线:主 agent 像项目经理,把任务派给小弟(subagent),小弟干完返回结果。轻量、同进程、一次性。
- Codex 走 “图 (graph)“ 路线:每个 agent 是图中的节点,spawn 关系是边,父 agent 可以多次和子 agent 来回交互、暂停、恢复。重量级、有持久化、有签名鉴权。
这篇文章把两种做法都拆开看。读完你能:
- 理解什么时候真需要 multi-agent(很多人没必要的也搞)
- 看懂这两种 CLI 工具的源码 / 工具描述里关于 agent 的部分
- 在自己做 AI agent 项目时知道该选哪种模型
1. 先说清楚:什么是 Multi-Agent?
把这个词拆开很简单:Multi(多个)+ Agent(自主的 AI 进程)。多个 AI 进程协作完成一个任务。
但魔鬼在细节里。”协作”分很多档:

| 协作档位 | 例子 | 是不是 multi-agent |
|---|---|---|
| 同一个 agent 串行做几件事 | 主 agent 先读文件、再改代码、再跑测试 | ❌ 单 agent,只是 multi-step |
| 同一个 agent 在不同模式间切换 | Codex 的 Plan / Execute / Pair Programming 模式 | ❌ 还是单 agent,只是换了 system prompt |
| 主 agent 派一次性任务给 subagent | “帮我去搜 X” → subagent 搜完返回 | ✅ Multi-agent · 委派模式 |
| 多个 agent 并发跑独立任务 | 5 个 agent 同时调研 5 个数据库 | ✅ Multi-agent · 并行 |
| 多个 agent 长期协作有共享状态 | PM agent / Dev agent / Test agent 流水线 | ✅ Multi-agent · 长程协作 |
后面三种是真正的 multi-agent。它们都解决同一类单 agent 解不了的问题:
| 单 agent 的天花板 | 解释 | Multi-agent 怎么破 |
|---|---|---|
| Context 溢出 | 一个 agent 的对话历史 + 工具输出超过 200K token,模型记不住 | 每个 sub-agent 有独立 context,主 agent 只看 sub-agent 的最终结果(高度压缩) |
| 没法并行 | 一个 agent 同一时刻只能干一件事 | 多个 sub-agent 并发跑,墙钟时间砍到 1/N |
| 角色专精弱 | 一个通用 agent 既写代码又做 review,不专 | 不同 sub-agent 用不同 system prompt + 不同工具集,各司其职 |
理解了这三个核心动机,你就能判断”我这个任务真的需要 multi-agent 吗” —— 如果你的任务 context 装得下、不需要并行、单一角色就够,不要上 multi-agent。它会让你的系统复杂十倍而收益接近零。
2. Claude Code:Subagent + Team 的委派模式
Anthropic 的 Claude Code 把 multi-agent 做得特别轻量。一个工具就是一切的入口:Agent。

2.1 Agent 工具:一次性 Subagent
你只需要调用一个工具:
1 | // Claude Code 的 Agent 工具调用(伪代码) |
主 agent 调一次这个工具,Claude Code 在背后做这些事:
- fork 一个新的 AI 进程 —— 独立的 conversation、独立的 context window、独立的 token 预算
- 按
subagent_type限定工具集 —— Explore 只有读和搜索的能力,不能写文件;general-purpose 有全部工具;自定义的 subagent 按其.claude/agents/文件定义 - 把
prompt作为初始消息 —— subagent 看不到主 agent 的对话历史,只看到这条 brief - subagent 自己跑 —— 调它能用的工具,最后产出一条最终消息
- 结果返回主 agent —— 主 agent 看到的是一段文本(subagent 的最终消息),整个 subagent 的中间过程不污染主 context
这就是”委派”的精髓:一个一次性的小弟,干完活把结果丢回来就消失。
2.2 Subagent 类型:工具集隔离
Claude Code 的 subagent_type 是一个非常聪明的设计点。它不是简单的”角色 prompt”,而是绑定了工具集合:
| Subagent 类型 | 能用的工具 | 用途 |
|---|---|---|
| Explore | Read / Grep / Glob / Bash 等只读工具 | 代码搜索、定位、调研 |
| Plan | 同上 + 不能 Edit/Write | 设计实现方案 |
| general-purpose | 全部工具 | 复杂多步任务 |
| claude-code-guide | Bash / Read / WebFetch / WebSearch | 回答 Claude Code 自身的使用问题 |
| code-reviewer | 全部工具 | 已完成代码的 review |
.claude/agents/*.md 自定义 |
用户自定义 | 任意 |
工具集隔离的好处:主 agent 不需要”提醒”subagent “你不能写文件”,根本就给不了它写文件的工具。这是从架构层面执行的最小权限原则。
2.3 Team:持久化 Teammate + 共享 TaskList
Agent 工具适合一次性任务。如果你需要多个 agent 长期共存、互相通信,Claude Code 还有 Team 模式:
1 | // 1. 创建 team(同时创建一个共享的 TaskList) |
Team 模式的关键设计:
- Team = TaskList:1:1 对应。team 内所有 teammate 共享同一份任务列表,谁都能 claim、update、create
- Named teammate:通过
name寻址(不是 UUID),适合跨 turn 持续协作 - idle 状态:teammate 完成一个 turn 后自动 idle,发消息会 wake-up
- Peer-to-peer 消息:任何 teammate 给任何 teammate 发 SendMessage,不必经过主 agent
2.4 同步 vs 后台
run_in_background: true 让 subagent 后台跑,主 agent 不阻塞,可以继续干别的。后台 subagent 完成时主 agent 收到通知,用 TaskOutput 拿结果。
这一组合(Agent + run_in_background + Team)足够支撑大部分 multi-agent 场景:
- “并行调研 5 个东西” → 5 个 background Agent 并行
- “PM/Dev/Test 流水线” → Team + 角色化 teammate
- “深度搜索某个问题” → Agent 单次派出 Explore subagent
整个 multi-agent 系统没有持久化:进程结束 team 就没了。也没有跨 session 状态:下次 Claude Code 启动 team 不存在。这是它”轻”的代价 —— 也是它能保持简单的关键。
3. Codex:Thread + Graph 的图模式
OpenAI 的 Codex 走的是另一条路。理解 Codex 的 multi-agent 要先理解一个核心抽象:Thread。

3.1 Thread:基本单元
在 Codex 里,Thread = 一个 AI 会话。它有:
- 独立的
thread_id - 独立的 model(可以不同)
- 独立的 reasoning_effort(推理深度)
- 独立的 cwd / permissions / sandbox
- 独立的 conversation history(
history) - 独立的 ed25519 keypair(身份,下面细说)
Thread 由 ThreadManager 管理:
1 | // codex-rs/thread-manager-sample/src/main.rs(简化) |
ThreadManager 的配置里有 4 个跟 multi-agent 直接相关的参数(codex-rs/core/src/config.rs):
1 | agent_max_threads: Some(6), // 同时存活的 agent thread 上限 |
这就是 Codex 的”团队规模 + 层级深度”硬上限。默认最多 6 个 agent、最大 1 层(即主 agent 可以 spawn 子 agent,子 agent 不能再 spawn 孙 agent)。
3.2 AgentControl 工具:spawn / interact / wait / close / resume
主 agent 通过一个内置的 AgentControl 工具控制子 agent。背后有 5 类事件(codex-rs/protocol/src/protocol.rs):
| 事件对 | 含义 |
|---|---|
CollabAgentSpawnBegin/End |
创建一个新子 agent thread,传入初始 prompt + model + reasoning_effort |
CollabAgentInteractionBegin/End |
父 agent 给子 agent 发新消息(注意:是多次对话,不是一次性派任务) |
CollabWaitingBegin/End |
父 agent 等待子 agent 完成当前 turn |
CollabCloseBegin/End |
关闭一个子 agent(结束 thread) |
CollabResumeBegin/End |
恢复一个已 close 的子 agent(继续之前的 conversation) |
注意 Interaction 这一层:父子 agent 不是”派一次任务”的关系,是”持续多轮对话”的关系。父 agent 可以给同一个子 agent 多次 prompt:
1 | spawn(role="researcher", prompt="调研 vector DB 选型") |
这种”多轮对话”模式对应到 sub-agent 端是这样的事件序列:

3.3 父子上下文怎么传:消息 + 文件系统
看完上面的事件序列,下一个自然的问题是:父子 agent 各自有独立 thread、独立 history,**”上下文”到底怎么传**?子 agent 怎么知道父在说什么?父怎么拿到子的中间结果?
核心结论先放:没有”共享 context window”这种东西。两边各管各的 history,靠两条窄通道交换信息。
通道一:显式消息(Interaction 的 prompt / response 文本)
父 agent 调用 AgentControl.interact 时,在它自己的 history 里就是一次普通的工具调用——发出 tool_call,拿回 tool_result,那段 tool_result 就是子 agent 这一轮的最终回复文本。
1 | 父 agent.history: |
两个关键点:
- 子 agent 那一堆 WebSearch、读文档的中间步骤,完全不进父的 context——这就是 §1 表里”Context 溢出”那行说的”主 agent 只看 sub-agent 的高度压缩结果”。
- 父第二次问”重点对比写入吞吐”时,子 agent 还记得自己上一轮做了什么(同一个 thread,history 累积)。这就是”持续多轮对话”的来源——父不用每次重讲”我们在聊什么”。
通道二:隐式文件系统(共享 cwd)
子 agent 默认继承父的 cwd 和 sandbox,所以它写出的文件父能直接读。这是一条”宽通道”——一份 5000 字的调研报告塞进 message 文本会污染父 context,写到 ./reports/qdrant.md 然后只回”已写到 xxx,核心结论是 yyy”则不会。
两条通道的分工
| 通道 | 带宽 | 是否进 history | 适合 |
|---|---|---|---|
| Interaction message | 窄 | ✅ 双方都进 | 摘要、决策、下一步指令 |
| 文件系统 / 工作目录 | 宽 | ❌ 不进 | 详细报告、生成的代码、长数据 |
到底”共享”了什么
| 类型 | 是否共享 | 说明 |
|---|---|---|
history(对话历史) |
❌ | 各自独立 thread |
cwd(工作目录) |
✅ 默认继承 | 看得到同一份代码 |
sandbox / permissions |
✅ 继承(可收紧) | 子可以更受限,不能突破父 |
| 文件系统状态 | ✅ 隐式 | 子改了文件,父再读才能看到(无自动通知) |
model / reasoning_effort |
❌ | spawn 时各自指定 |
agent_identity(ed25519) |
❌ | 每个 thread 一把私钥(§3.5) |
实战教训
子 agent 的 final message 不要是”全文报告”,应该是”摘要 + 文件路径”。把宽内容走文件系统、窄内容走 message——multi-agent 节省 context 的优势才能真正兑现。否则 5 个 sub-agent 各回 5000 字,父 context 立刻爆炸,multi-agent 的核心收益就没了。
记忆口诀:Codex 的 multi-agent 不靠”共享内存”通信,而是靠”显式消息 + 隐式文件系统”。
3.4 AgentGraphStore:spawn 关系持久化
每次 spawn 一个子 thread,Codex 在 AgentGraphStore 里记录一条父子边:
1 | // codex-rs/agent-graph-store/src/store.rs |
这意味着 Codex 知道整个 agent 拓扑图:哪个 agent spawn 了哪些子 agent,哪些边是 Open(活跃)的,哪些是 Closed。这个图是持久化的(落 SQLite),重启 Codex 之后还能恢复出来 —— 你能 resume 一个昨天 close 掉的 agent,继续上次的对话。
接口提供 BFS 遍历:
1 | async fn list_thread_spawn_descendants( |
这是 Codex multi-agent 区别于 Claude Code 的最大特征:整个 agent 关系图是一等公民、有持久化、可遍历。
3.5 AgentIdentity:每个 agent 一把 ed25519 私钥
Codex 把每个 agent 当成一个独立的认证主体对待。每个 agent 有:
1 | // codex-rs/agent-identity/src/lib.rs |
调用 ChatGPT 后端 API 时,agent 用自己的私钥签一段 AgentAssertion:
1 | // 签名内容: "{agent_runtime_id}:{task_id}:{timestamp}" |
服务端通过 JWKS 验证签名 + JWT 鉴权(AGENT_IDENTITY_JWT_AUDIENCE = "codex-app-server",AGENT_IDENTITY_JWT_ISSUER = "https://chatgpt.com/codex-backend/agent-identity")。每个 agent 调用 LLM 时都带着自己的身份,后端能精确知道是哪个 agent 在调用。
为什么要这么重?因为 Codex 设计为可以跑在云上 / 跨进程 / 跨机器的 agent 系统。当你的 multi-agent 跑在企业 K8s 集群里时,每个 agent 一把私钥就是必需的安全机制 —— 一个 agent 被攻破不能伪装成另一个 agent。
这也是 Claude Code 不需要的:Claude Code 的所有 subagent 都在同一个本地进程里,互信,不需要互相鉴权。
3.6 4 种 Collaboration Mode(不是 multi-agent,但相关)
Codex 还有一个容易和 multi-agent 混淆的概念:Collaboration Mode。
1 | codex-rs/collaboration-mode-templates/templates/ |
这 4 个不是 multi-agent —— 它们是同一个 agent 的 4 种工作风格,由 system prompt 切换。但在 multi-agent 场景下你可以混用:spawn 一个 sub-agent 时给它 Plan mode 的 prompt 让它专心规划,spawn 另一个给 Execute mode 让它专心干活。
4. 11 维度对比
把上面两种模式放在一张表里:

| 维度 | Claude Code (委派) | Codex (图) |
|---|---|---|
| 基本单元 | Subagent(一次性) + Teammate(持久) | Thread(DAG 节点) |
| 创建方式 | Agent 工具调用 |
AgentControl 工具的 spawn 事件 |
| 角色定义 | subagent_type(绑定工具集) |
agent_roles 配置(按 role 分发 system prompt) |
| 父子通信 | Subagent 一次性返回;Team 用 SendMessage 任意 peer | 父子多轮 Interaction 事件 |
| 共享状态 | Team 共享 TaskList | 父子共享 cwd / sandbox / 部分 context(按需) |
| 生命周期 | Subagent: spawn → run → 结果返回 → 销毁 | Thread: spawn → interact × N → wait → close → (可 resume) |
| 隔离机制 | 独立 conversation + 工具集白名单 | 独立 thread_id / model / reasoning_effort / sandbox |
| 可观测性 | 主 agent 看消息流;team 有 idle notification | CollabAgent* 事件流,每个事件带 timestamp + thread_id |
| 持久化 | 无(除 TaskList 在 session 内) | AgentGraphStore 持久化 spawn 图(重启可恢复) |
| 认证 | 无(同进程互信) | 每个 agent 一把 ed25519 私钥 + JWT 签名 |
| 典型规模 | 2-10 个 subagent | 默认 agent_max_threads: 6, agent_max_depth: 1 |
| 后台执行 | run_in_background: true 显式开 |
默认就是异步 / 事件驱动 |
| 跨 session | 不支持 | 支持(持久化 + resume) |
| 架构定位 | CLI 内的 in-process delegation | 可云化 / 可跨节点的 agent runtime |
4.1 一句话哲学差异
- Claude Code: “Project manager + interns” —— 主 agent 是 PM,subagent 是临时实习生,干完活就走,不留痕
- Codex: “DAG of agents” —— 每个 agent 是图中长寿的节点,关系持久、可观测、可恢复
4.2 哪种更”对”?
都对。两种模式对应两种使用场景:
| 你的场景 | 选哪个 |
|---|---|
| 一次性研究任务(”调研 X / 搜索 Y”) | Claude Code Agent (委派) |
| 一次性长任务(”重构整个模块”) | Claude Code Agent + Team |
| 多个工程师 / 多个任务长期共享一个 AI 团队 | Codex (持久 + 鉴权 + 跨 session) |
| 跑在 K8s 集群里给 300 工程师服务 | Codex (天然适合分布式) |
| 想内嵌进 CI/CD 流水线、每次启动新 agent | Claude Code Agent run_in_background |
| 想让用户能”resume 上次没干完的活” | Codex (有 thread_id 持久化) |
| 想审计”哪个 agent 在哪一步干了什么” | Codex (CollabAgent 事件流) |
5. 几个不直观的设计取舍
5.1 委派模式为什么默认是同步的
Claude Code 的 Agent 工具默认是同步的(主 agent 阻塞等结果),后台是 opt-in。这反直觉 —— 直觉上 multi-agent 应该并发啊。
但仔细想:大部分单次 subagent 任务(”搜代码”、”写一个组件”)几秒到几十秒结束,主 agent 等一下没什么。真正需要并发的场景(5 个 benchmark / 多个 PR review)才显式开 run_in_background。
这种”默认同步、并发是 opt-in”的设计减少了用户犯错的机会 —— 不开背景任务,就不会有”多个 subagent 互相竞争资源 / 主 agent 忘了取结果”这类 bug。默认走最安全的路径是优秀 API 设计的标志。
5.2 图模式为什么需要 ed25519 鉴权
直觉上同进程的 agent 没必要互相鉴权 —— 都在一个 binary 里跑,互信就行。
但 Codex 的 multi-agent 设计目标是云化:agent 可能跑在不同进程、不同机器、甚至不同 K8s pod 里。这种场景下,”agent A 给 backend 发请求” 和 “攻击者伪装成 agent A 给 backend 发请求” 必须能区分。每个 agent 一把私钥就是这个区分的来源。
这是 Codex 把”同进程 multi-agent”和”分布式 multi-agent”用同一套抽象实现的代价 —— 即使你的 agent 都在同一个进程里,也得走签名流程。复杂度提升换来的是规模化的可能性。
5.3 Token 经济的隐性成本
无论哪种模式,每个 sub-agent 都在烧 token。看起来 multi-agent 让你”并行做 5 件事”,但 token 花费也是 5 倍 —— 而且每个 sub-agent 的 system prompt + 工具描述都是独立的开销,单算下来比单 agent 跑同样工作量贵 30-50%。
实战教训:Multi-agent 的真正价值不是省时间(虽然墙钟时间砍了),是做单 agent 做不了的事(context 装不下 / 角色冲突 / 长程任务)。把它当 “AI 加速器” 用一定亏。
6. 你应该选哪个:决策树

简化版:
1 | 你的任务 / 系统是 …… |
7. 总结:两种工具对应两种产品形态
回过头看 Claude Code 和 Codex 在 multi-agent 上的不同选择,本质反映了两家公司对”AI agent 是什么”的不同定位:
**Anthropic 把 Claude Code 定位为”程序员的本地 CLI 助手”**。所以 multi-agent 是轻量的、同进程的、一次性的、用完即弃的。它的 sweet spot 是”你坐在终端前指挥 AI”。
**OpenAI 把 Codex 定位为”可云化的 AI agent runtime”**(看 codex-rs 那 90+ crates 的体量就知道),multi-agent 是重量的、有持久化、有签名鉴权、可分布式的。它的 sweet spot 是”AI agent 团队跑在你公司的 K8s 集群里给所有工程师服务”。
这两个定位都对,没有谁优于谁。理解定位差异,你才能在做自己的 AI 产品时做出对的选择:
- 想做”开发者本地工具”?学 Claude Code 的轻量委派模式
- 想做”企业级 AI 平台”?学 Codex 的图 + 鉴权 + 持久化模式
- 千万别在轻量 CLI 里搞重量级图模型(用户体验会崩)
- 也别在企业级平台里搞轻量委派(持久化 / 审计 / 鉴权全没了)
下一篇我们换个角度,聊聊 multi-agent 系统真正落地时最容易踩的几个坑:token 经济失控、消息总线选型、人工 approval 的边界、级联错误的可观测性。这些是”知道 API 怎么用”之后真正会咬你的问题。
参考资料
- Claude Code 官方文档 —— Agent 工具 / Team 工具的官方说明
- Codex 源码:thread-store —— Thread 抽象的具体实现
- Codex 源码:agent-graph-store —— spawn 图的持久化层
- Codex 源码:agent-identity —— ed25519 + JWT 鉴权
- Codex 源码:collaboration-mode-templates —— 4 种工作风格的 system prompt
- 本系列 23 篇 · 多 Agent 并发场景
