多 Agent 协作通信怎么设计?
把"一个大上下文"拆成多个"小上下文 + 通信协议 + 共享状态"——分工必然带来信息损失,所以通信设计是 Multi-Agent 系统的命门。本文专讲:Agent 之间到底传什么、消息长什么样、拓扑怎么选、协议怎么定、错误怎么兜底,并给出一份可直接照抄的设计蓝图。
1. 一句话讲清:通信设计的本质
多 Agent 协作的难点从来不是"让两个模型对话",而是如何在分工后,把信息无损、可控、可恢复地从一个 Agent 传到另一个。
通信要解决 3 件事
传什么(消息结构)、怎么传(拓扑与通道)、传坏了怎么办(协议与可靠性)。缺任何一环,系统就会"各说各话"或"踢皮球"。
核心矛盾:分工 vs 信息损失
拆分上下文能解决单 Agent 的窗口溢出,但每个 Agent 只拿到"别人传给它的那点信息"。设计通信,本质是在带宽有限下最小化信息损失。
multi-agent-explained.html 讲"Multi-Agent 是什么、怎么协作、选什么框架";本文件是配套实操篇,专门钻进"通信"这一关——消息、拓扑、协议、可靠性,配一份可落地的设计蓝图。
2. 通信到底在传什么?
Agent 之间传递的不是"一句话",而是一组结构化信封。一个最小可用通信单元至少包含 5 个字段:
身份字段
sender / receiver / message_id / reply_to:让消息可寻址、可关联、可做请求-响应配对。
类型字段
type 决定接收方怎么处理:task(派活)、result(交差)、query(问)、error(报错)、signal(控制)。
载荷字段
payload 是业务内容,结构化(JSON)优于自然语言,便于程序解析、校验、重试。
3. 消息格式设计:自然语言 vs 结构化
消息内容的"编码方式"直接决定系统能不能规模化。三种主流做法,从弱到强:
| 编码方式 | 样子 | 优点 | 缺点 | 适用 |
|---|---|---|---|---|
| 纯自然语言 | "帮我查下竞品A的销量" | 灵活、零成本 | 难解析、易歧义、不可校验、易丢字段 | 原型、人参与的调试 |
| 半结构化 | "Action: search[竞品A]" | 能解析、好控制 | 格式约束弱、易格式漂移 | 单 Agent ReAct |
| 强结构化(JSON) | {"type":"task","payload":{...}} | 可校验、可重试、可类型安全 | 需定义 Schema、啰嗦 | 生产推荐 |
生产级消息 Schema 样例
// 一个强结构化消息的完整骨架
{
"message_id": "msg_8f3a", // 全局唯一,用于去重/追踪
"sender": "orchestrator", // 发送方 Agent 标识
"receiver": "researcher_1", // 接收方;"broadcast" 表示广播
"type": "task", // task | result | query | error | signal
"trace_id": "trace_2026", // 串联一次用户请求的全链路
"reply_to": "msg_7c1b", // 若这是对某消息的回复
"payload": {
"task": "collect_competitor_sales",
"args": { "company": "A", "month": "2026-07" },
"timeout_sec": 60,
"expected_schema": { "sales": "number" } // 对结果的格式契约
},
"deadline": "2026-08-24T15:00:00Z" // 超时边界
}
message_id 和 trace_id,否则无法去重、追踪、排查;② 用 expected_schema 把"结果长什么样"写在任务里,接收方交差时才能被校验;③ 自然语言尽量只出现在 payload 的"不可结构化"部分(如分析结论)。
4. 拓扑结构怎么选
"谁可以跟谁说话"是通信设计的第一道架构决定。四种常见拓扑:
| 拓扑 | 通信路径 | 优点 | 缺点 | 选型 |
|---|---|---|---|---|
| 中心辐射 Hub | 只经 Orchestrator | 可控、易排查、无环路 | Hub 成瓶颈、单点 | 生产首选 |
| 流水线 Pipeline | A→B→C 单向 | 简单、背压清晰 | 无法回退、难并行 | 固定工序 |
| 层级 Hierarchical | 经理↔组员 | 可扩展到大量 Agent | 层级深了延迟高 | 大团队分组 |
| 全互联 Mesh | 任意两点直连 | 最灵活、鲁棒 | 复杂度指数级、难调试 | 探索/研究 |
5. 共享状态 vs 消息传递
Agent 间同步信息有两条根本路径,理解它们的权衡是通信设计的核心决策:
📨 消息传递(Message Passing)
信息只通过"发送消息"流动。每个 Agent 私有上下文,互不直接读内存。
- 优点:低耦合、易并联、可重放、天然审计。
- 缺点:带宽有限,只传增量,容易丢上下文;要显式设计"传什么"。
- 典型:AutoGen 的 GroupChat、CrewAI 的 Crew 轮转。
🗂️ 共享状态 / 黑板(Shared State)
所有 Agent 读写同一块"黑板"(blackboard / state object)。
- 优点:信息全集可见,不用反复传;新 Agent 随时接入都能看到全局。
- 缺点:要处理并发写冲突、版本、一致性;状态错了全局崩。
- 典型:LangGraph 的
State、黑板模式。
6. 通信协议与握手
光有消息格式还不够,要有"规矩"约束通信时序。三类协议,复杂度递增:
请求-响应(RPC 风格)
发 task,等 result,靠 reply_to 配对。最简单,适合点对点调用。timeout 必带。
发布-订阅(Pub/Sub)
Orchestrator 广播事件,关心它的 Agent 订阅处理。解耦好,适合一对多通知。
协商 / 握手
两 Agent 先"报价-确认"再干活(如能力协商、任务认领)。最稳,适合去中心化。
握手时序:任务派发到交付
7. 交互演示:看一次消息总线里发生了什么
点"跑一轮",观察一条用户请求如何在 Orchestrator 与多个 Worker 之间通过消息总线流转(带 reply_to、trace_id、超时与错误分支)。
再点"注入一次失败",看错误怎么被协议兜住
8. 错误处理与可靠性
多 Agent 链路长、参与方多,错误是常态而非例外。通信层必须内置四类兜底:
超时与重试
每条 task 带 timeout;超时未回 result 则重试或转派。重试要幂等(同任务跑多次结果一致)。
失败转移(Failover)
Worker 崩了,Orchestrator 把任务转给备份 Worker,或从共享状态恢复半成品。
幂等与去重
靠 message_id 去重,避免重试导致重复执行;写共享状态用版本号防并发覆盖。
死循环防护
设全局最大轮次 / 最大消息数;两 Agent 互相等待或互踢皮球时强制终止并告警。
expected_schema → 校验失败即报错并请求重发;③ 状态撕裂——并发写共享状态互相覆盖 → 用乐观锁/版本号。
9. 一个可落地的通信设计蓝图
把前面所有要点收口成一份"照着抄"的设计清单。一个稳健的 Multi-Agent 通信系统应当包含:
消息信封(Envelope)
统一必含:message_id、sender、receiver、type、trace_id、payload、deadline。所有 Agent 收发都走同一套。
通道与拓扑
默认中心辐射:所有消息经消息总线(或 Orchestrator)。总线负责路由、去重、持久化、超时检测。
共享状态(Blackboard)
存稳定全局事实与各方产出,带版本号;消息只传动作与增量。新 Agent 接入即可读全局。
协议与握手
请求-响应为主(带 reply_to);长任务用状态机(pending→doing→done/error);跨框架互通看 A2A。
可靠性底座
ack 确认、超时重试(幂等)、failover、最大轮次防护、完整 trace 日志(谁调谁、输入输出、耗时、错误)。
10. 主流框架里通信是怎么实现的
| 框架 | 通信机制 | 消息/状态模型 | 通信设计启示 |
|---|---|---|---|
| CrewAI | 顺序/层级 Process 轮转 | Agent 依次发言,上下文拼接 | 消息≈"上一个人说的话",轻量但难精细控制 |
| LangGraph | 状态图节点流转 | State 共享对象 + Conditional Edge | 通信≈"状态更新 + 条件路由",最适合精细通信设计 |
| AutoGen / AG2 | GroupChat 群聊 | 消息列表广播,Speaker 选择 | 消息传递范式,天然审计、可重放 |
| 自研总线 | 消息队列(如 Redis Stream) | Envelope + 主题订阅 + 持久化 | 完全自控,可上 A2A、跨服务部署 |
11. 常见坑与设计 Checklist
坑:自然语言当消息
用纯文本传指令,下游解析靠"猜",字段一多就丢。→ 改用强结构化 JSON Envelope。
坑:无超时无限等
Worker 卡死,Orchestrator 永远阻塞。→ 每条消息必带 deadline。
坑:上下文全靠传
私有上下文导致下游 Agent 缺少上游关键背景。→ 稳定全局事实放黑板。
坑:无 trace 难排查
出错了不知道谁发的、卡在哪。→ trace_id + 全链路日志。
✅ 通信设计 Checklist
- ☐ 消息是否统一了 Envelope(id / sender / receiver / type / trace_id / payload / deadline)?
- ☐ 拓扑是否明确(中心辐射 / 流水线 / 层级 / mesh),且默认走可控的中心辐射?
- ☐ 稳定全局事实是否进了共享状态,动作与增量是否走消息?
- ☐ 是否有请求-响应配对(
reply_to)、ack 确认、超时与幂等重试? - ☐ 是否有最大轮次 / 最大消息数防死循环、死锁防护?
- ☐ 结果是否用
expected_schema校验,格式漂移能否被发现并重发? - ☐ 并发写共享状态是否有版本号/乐观锁防撕裂?
- ☐ 是否每条消息都可被 trace、重放、审计?