为什么没有 Agent 间 P2P 通信——树状拓扑 vs 网状拓扑

2026-10-05·编排与协作·多 Agent 委派

Claude Code Agent Teams 支持任意 Teammate 向任意 Teammate 发消息。我们选了树状拓扑——只有 parent→child 和 child→parent。这篇文章讲这个设计争议——P2P 的四个被低估的代价,树状拓扑在什么场景下是正确的、什么场景下不够用。

两种截然不同的通信模型

树状拓扑(我们的选择)

              Parent Agent
             ╱      │       ╲
       Child A   Child B   Child C
  • 下行:Parent 委派任务给 Child
  • 上行:Child 返回结果给 Parent
  • 无横向:Child A 不能直接和 Child B 通信

需要 A 和 B "对话"时,让 Parent 协调:

Parent → delegate(A) → 得到结果 A
Parent → delegate(B, context=结果A) → 得到结果 B
Parent → 汇总

网状拓扑(Claude Code Agent Teams 的选择)

        Lead
       ╱    ╲
  Teammate A ←→ Teammate B
       ╲    ╱
   Teammate C
  • 任意 Teammate 向任意 Teammate 发消息
  • Lead 是协调者但不是信息的唯一中转
  • 广播(to: "*")向所有 Teammates 发消息

Claude Code 的 Agent Teams 使用 SendMessage 工具实现 P2P:

SendMessage({
  to: "teammate-b",     // 或 "*" 广播
  summary: "5-10 词摘要",
  message: "详细消息内容"
})

tmux 模式下消息通过 Mailbox 文件(JSON,带文件锁)传递;in-process 模式下通过内存队列 + 文件双写。

两种拓扑不是"简单 vs 复杂"的关系——它们回答的是同一个问题的两种答案:"Agent 之间的信息流应该怎么走?"


树状拓扑 vs 网状 P2P——审计复杂度的差异

P2P 的四个被低估的代价

代价一:可追踪性从 O(N) 变成 O(N²)

树状拓扑下,所有信息流经 Parent——形成一条清晰的追踪链。N 个 Agent 的系统中,信息路径最多 2N 条(每个 Agent 有一条上行和一条下行)。

P2P 网络中,N 个 Agent 之间理论上有 N(N-1)/2 条通信路径。3 个 Agent → 3 条;5 个 Agent → 10 条;10 个 Agent → 45 条。

在调试和审计中,这意味着:

  • 你需要追踪的信息流从"一条树"变成"一张图"
  • 一个 Bug 可能是 A 发给 B 的消息被 C 的消息覆盖——需要检查所有消息的时序
  • 审计时"谁把什么信息告诉了谁"变成一个复杂的图遍历问题

Claude Code 在 Agent Teams 的遥测中记录了 from、to、summary、timestamp——但在实际调试中,时间线上交叉的 P2P 消息仍然比树状追踪难读得多。

代价二:死锁的结构性风险

树状拓扑在结构上消除了循环等待——因为信息只能向上(child→parent)或向下(parent→child)流动。不可能出现 A 等 B、B 等 A 的情况。

P2P 通信引入了循环等待的可能:

Teammate A: SendMessage(to: "B", "请帮我检查 X")
    → A 进入 idle,等待 B 的回复
Teammate B: SendMessage(to: "A", "我需要你先告诉我 Y")
    → B 进入 idle,等待 A 的回复

A 等 B,B 等 A——经典死锁。

Claude Code 的 Agent Teams 通过异步消息模型部分缓解了这个问题——SendMessage 是非阻塞的(写入消息后立即返回),不会真的"等待回复"。但模型可能认知上进入"我发了消息,应该等回复再继续"的模式——如果 prompt 引导不够明确,模型可能在收到回复前不做任何有用的工作,实际效果等同于阻塞。

对比 $47,000 事故:那不是技术层面的死锁——是认知层面的死锁。Analyzer 和 Verifier 各自在"正常工作",但它们之间的消息循环没有任何一方能打破。

代价三:prompt cache 被 P2P 消息打断

Agent 的每一轮 LLM 调用都依赖消息序列的稳定性——相同的消息前缀可以复用 prompt cache。

P2P 消息的到达是不可预测的——Teammate A 在执行第 15 轮工具调用时,可能突然收到 Teammate C 的消息。这条消息作为新的输入注入到 A 的上下文中——打断了 A 的已有消息序列。

每次 P2P 消息注入都可能导致:

  • 从注入点开始的 prompt cache 失效
  • 模型需要"消化"一条上下文之外的信息
  • 模型的推理链被外部消息打断

在长对话场景中(100+ 轮),频繁的 P2P 消息可能让 prompt cache 命中率降到很低——意味着每次 LLM 调用都需要处理完整上下文,token 成本大幅上升。

Claude Code 的 in-process Teammate 有 50 条消息的上限——部分是因为 P2P 消息会迅速填满上下文窗口。超过上限就触发独立的压缩。

代价四:治理链断裂

树状拓扑中,GovernMode(治理模式——"这个 Agent 可以做什么"的安全策略)沿委派链向下继承。父 Agent 的安全策略自然传递给子 Agent——如果父被限制为"只读",子也只能是"只读"或更严格。

P2P 网络中,治理继承关系不清晰。如果 Teammate A(只读模式)发消息给 Teammate B(可写模式),B 收到消息后执行了一个写操作——这算 A 发起的还是 B 发起的? 在审计中如何归责?

Claude Code 的 Agent Teams 在这方面的处理是——Teammate 默认拥有所有工具权限(tools: ["*"]),不做权限收紧。这在 CLI 开发者工具场景中是可接受的(开发者自己承担风险),但在企业合规场景中是不可接受的。


P2P 确实有价值的场景

cache safety

尽管有以上四个代价,P2P 通信在特定场景中是正确的选择。

场景一:竞争假设

两个 Agent 各自探索一条技术路线(比如"用策略 A 重构"和"用策略 B 重构")。在探索过程中,A 可能发现一个细节对 B 的策略有影响——比如"数据库 schema 有一个隐藏的约束,策略 B 的假设不成立"。

如果通过 Parent 中转——A 报告给 Parent,Parent 转告 B——信息传递有两轮 LLM 调用的延迟,且 Parent 可能压缩掉关键细节。

P2P 通信让 A 直接告诉 B——信息传递更快、更完整。

Claude Code 的 Agent Teams 正是为这个场景设计的。它的官方文档建议在需要"research, exploration, and competitive implementation"时使用 Teams。

场景二:流水线式数据传递

Agent A 在持续产出中间结果(比如逐页翻译文档),Agent B 需要实时消费这些结果(比如实时做术语一致性检查)。

等 A 全部完成再传摘要给 B 会引入不必要的延迟。A 直接向 B 流式传递中间结果更高效。

场景三:共享工作区

多个 Agent 同时编辑同一个代码仓库的不同文件。它们需要实时知道对方的修改以避免冲突——比如"我正在改 auth.go 的接口,你先别动依赖它的 handler.go"。

Claude Code Agent Teams 的 Task 系统(共享的 TaskCreate/TaskUpdate)部分解决了这个问题——Teammates 通过 Task 列表协调工作,而不是直接告知对方正在做什么。这是一种间接通信——通过共享状态而非直接消息。


我们选择树状拓扑的理由

代码知识图谱

我们的场景覆盖了从个人编程助手到企业多部门工作流。在这些场景中:

Web SSE 流的消息顺序

我们的产品面向 Web 浏览器——消息通过 SSE(Server-Sent Events)实时推送。多 Agent 并行输出意味着用户在浏览器中看到交叉混合的文字——A 的一段话、B 的一段话、A 的另一段话。阅读体验极差。

串行触发链(Orchestrator → A → 汇总 → B → 汇总)提供可预测的阅读顺序。这是产品层面的约束,不只是技术选择。

企业合规的可审计性

在金融、法律、医疗等合规场景中,"谁做了什么决策"必须清晰可追溯。树状拓扑的追踪链是天然的审计日志——"Coordinator 委派了法律审查 → 法律 Agent 分析了合同 → 结果返回 Coordinator → Coordinator 决定..."。

P2P 网络的审计需要重建完整的消息图——时间线上交叉的消息、多方同时修改的共享状态——这在合规审查中是噩梦。

Coordinator 不是 Agent——是基础设施

我们的 Coordinator(协调多个 Agent 响应同一条消息时的调度逻辑)不是一个 Agent——它不持有 SessionState,不消耗上下文窗口,不出现在对话历史中。它使用 Query 原语(单轮无工具调用的轻量 LLM 调用)做路由决策。

这和 Claude Code 的 Team Lead 形成对比——Lead 是完整的 Claude 会话,有自己的上下文窗口、系统提示词、工具集。Lead 的每一次协调决策都消耗上下文容量。

对于大多数协调场景("这条消息让谁回复?""需不需要下一个 Agent 跟进?"),一次轻量的 Query 调用就够了——不需要一个完整的 Agent 会话。


两种拓扑的适用场景对比

场景树状拓扑(我们的选择)P2P 网状(Agent Teams)
Web 聊天 / SSE 流✅ 消息顺序可预测❌ 交叉混合
企业合规审计✅ 树状追踪链清晰❌ 图遍历审计困难
CLI 并行探索⚠️ 需通过 Parent 中转✅ 直接通信更高效
竞争假设⚠️ 信息传递有延迟✅ 实时共享发现
长对话 prompt cache✅ 消息序列稳定❌ P2P 消息打断 cache
安全/治理继承✅ 沿委派链向下❌ 横向权限边界不清
简单委派(搜索/分析)✅ 足够过度设计

两种拓扑不是"好坏"之分——是"适合什么场景"之分。

行业趋势

截至本文写作时,Claude Code 的 Agent Teams 仍标为"实验性"——官方文档明确警告"known limitations around session resumption, task coordination, and shutdown behavior"。

而 Anthropic 在同一份文档中的建议是先考虑更轻量的选项:"Before you set up a team, check whether a lighter option does the job. Subagents work within a single session, and with cross-session messaging Claude can pass findings between the sessions you run yourself."

这个建议和我们的判断框架一致——默认用最简单的模式(单 Agent → Subagent → 树状委派),只有在确定需要并行探索/竞争假设/实时协作时才考虑 P2P。

FrankX 在 2026 年的编排模式综述中也给出了类似的建议:"Many production systems combine them: a durable state machine launches a dynamic research graph, whose workers execute small loops, then a deterministic DAG publishes the verified artifacts." 实际系统是分层的——不是"选一种模式用到底",是不同层次用不同模式。


需要 P2P 时的正确做法

如果你的场景确实需要 Agent 之间的直接通信(比如 CLI 开发场景的并行探索),以下是从 Claude Code Agent Teams 实现中提炼的工程建议:

1. 消息必须带结构化元数据

{
  "from": "teammate-a",
  "to": "teammate-b",
  "summary": "5-10 词摘要",
  "timestamp": "2026-10-05T14:30:00Z",
  "message": "详细内容"
}

摘要字段让接收方(和审计系统)能快速判断消息的重要性,不需要读完整内容。

2. 广播要极度克制

Claude Code 的 SendMessage 支持 to: "*" 广播——但只允许纯文本消息,不允许结构化消息(如 shutdown_request)。这是一个有意的限制——广播不应该携带"需要所有人响应"的语义,否则每条广播都触发 N 个 Agent 各自回复,产生 O(N) 条回复消息。

3. 共享状态通过 Task 系统而非 P2P 消息

Claude Code Agent Teams 有独立的 Task 系统——TaskCreate/TaskGet/TaskList/TaskUpdate——通过共享的 JSON 文件实现。这是一种间接通信:

  • 直接通信:"A 告诉 B 他在做什么" → 消息
  • 间接通信:"A 更新共享看板,B 自己去看" → 共享状态

间接通信更安全(修改是原子的、有冲突检测)、更可追踪(所有修改都在一个地方)、更抗延迟(不依赖实时消息投递)。

4. 死锁检测是必须的

如果允许 P2P 消息,必须有死锁检测——当两个 Agent 互相等待对方回复超过 N 秒时,至少发出警告。Claude Code Agent Teams 的实验性标记部分就是因为这类边界条件还没有完全处理好。


一个更大的视角

这篇文章讨论的是"Agent 之间怎么通信"。但退一步看,这个问题是"多 Agent 系统的拓扑设计"的一部分——更大的问题包括:

  • 发现:一个 Agent 怎么知道有哪些其他 Agent 可以协作?
  • 身份:消息发送者是谁?接收者怎么验证?
  • 协议:消息格式、传递保证、错误处理
  • 生命周期:谁启动 Agent、谁负责清理、超时怎么处理

树状拓扑把所有这些问题简化为Parent 全知全管——Parent 知道有哪些 Child、负责启动和清理、通信格式由委派接口定义。

P2P 网络需要独立的解决方案——发现服务、认证机制、消息协议、心跳/清理机制。这些基础设施加在一起的复杂度远超 P2P 通信本身。

选择通信拓扑不只是选择消息怎么流——是选择整个系统的复杂度水位。


你现在能做什么

1. 默认用树状拓扑——只有在确定需要并行探索时才考虑 P2P。 树状拓扑的审计和调试成本是 O(N),P2P 是 O(N²)。除非你的场景明确需要"两个 Agent 互相交换实时发现"——用树状。

2. 需要 Agent 间协作时让父 Agent 中转。 A 做完 → 结果传给父 → 父把结果作为 context 传给 B → B 做完。这比 A 直接给 B 发消息更可追踪、更安全、不会破坏 B 的 prompt cache。

3. 如果用 P2P——消息必须带结构化元数据。 至少包含 from、to、timestamp、summary(5-10 词摘要)。没有 summary 的 P2P 消息让审计和调试变成噩梦。

4. 广播要极度克制。 不要对 N 个 Agent 广播一条需要回复的消息——那会产生 N 条回复,每条回复又可能触发新的消息。广播只用于"通知型"信息("任务已完成"),不用于"请求型"信息("帮我检查 X")。


引用来源

  • Claude Code 官方文档, "Orchestrate teams of Claude Code sessions" — https://code.claude.com/docs/en/agent-teams
  • Inside Claude Code, "Agent Teams v2.1.88 深度分析" (y-agent.github.io) — SendMessage 实现、Mailbox 文件系统、in-process 队列
  • Anthropic, "Building effective agents" — Multi-agent token cost warning
  • FrankX, "AI Agent Orchestration: Loops, DAGs and Durable Graphs" (2026)
  • vectara/awesome-agent-failures, "$47K infinite loop" — 认知层面的死锁
  • NomadX, "Multi-Agent Orchestration: Patterns and Frameworks (2026)"
Logo

更多推荐