多Agent系统在实际工程中常常因为通信方式随意而陷入混乱。不同的智能体由不同团队开发,有的用JSON明文,有的用二进制流,还有的把控制指令和业务数据混在同一个字段里,导致接收方不得不写大量兼容逻辑。更麻烦的是,当系统中Agent数量超过十个之后,谁该接收哪条消息往往靠硬编码或者全局广播,结果既浪费带宽又容易引发竞态。要从根本上解决这类问题,必须建立一套明确的消息协议,并配套合理的路由机制,让消息从产生、投递到消费都有章可循。

消息协议的结构化设计
消息协议的核心目标是让任意Agent在收到一条消息时,不需要事先约定就能理解它的来源、去向、类型和紧急程度。一个实用的协议通常包含信封与载荷两部分。信封是元数据,描述sender_id、receiver_id、msg_type、priority和timestamp等字段;载荷才是真正的业务数据。把元数据与业务解耦,中间件就能在不解析业务的前提下完成路由与限流。
下面给出一个简单的协议定义示例,使用JSON描述信封,业务数据放在payload中。注意所有字段都使用下划线命名,避免不同语言解析时的歧义。
{
"envelope": {
"sender_id": "agent_order_01",
"receiver_id": "agent_payment_02",
"msg_type": "command.pay",
"priority": 5,
"timestamp": 1710000000000,
"trace_id": "trace_abc123"
},
"payload": {
"order_id": "O10086",
"amount": 99.9,
"currency": "CNY"
}
}
采用这种结构后,接收方先用通用解析器读取envelope,就能决定是丢弃、转发还是本地处理。如果以后新增一种消息类型,只要扩展msg_type的取值并在路由表中登记即可,不必改动底层通信框架。相比把类型藏在业务字段里的做法,结构化信封显著降低了耦合度。
另一个容易被忽视的点是协议版本号。建议在信封中增加proto_version字段,当协议升级时旧Agent仍可识别并走兼容分支。否则一次协议调整就可能让整个系统集体失效。版本字段配合灰度发布,可以把通信混乱的风险控制在最小范围。
中心化网关与去中心化路由的对比
路由机制决定了消息如何从发送者到达正确的接收者。最常见的两种形态是中心化网关和去中心化订阅。中心化网关由一个独立服务持有全量路由表,所有消息先发往网关,再由网关根据receiver_id或msg_type转发。它的好处是权限、审计、限流都集中在一点,出问题容易排查;缺点是网关成为瓶颈,一旦宕机全系统失联。
去中心化路由通常基于发布订阅模型,Agent按照主题订阅自己关心的消息。发送者只管往主题里发,中间件负责拷贝给所有订阅者。这种结构扩展性很好,新增Agent只需注册订阅,不影响他人。但如果没有约束,一个热门主题可能被上百个Agent订阅,产生消息风暴,甚至压垮下游。
# 中心化网关转发伪代码
def route_message(msg):
receiver = msg['envelope']['receiver_id']
if receiver in agent_registry:
agent_registry[receiver].send(msg)
else:
dead_letter_queue.put(msg)
# 去中心化订阅伪代码
def publish(topic, msg):
for subscriber in topic_subscribers.get(topic, []):
subscriber.queue.put(msg)
从实践看,中小规模系统用中心化网关更省心,因为通信路径清晰,也方便做统一监控。当Agent数量突破五十且跨机房部署时,纯中心化难以支撑,可改为分层路由:机房内用网关,机房间用订阅同步路由表。这样兼顾可控与弹性。
无论哪种机制,都必须考虑消息幂等。由于网络重试,同一个trace_id的消息可能到达两次。接收方应维护已处理ID集合,或者在业务层用唯一键防重。忽略幂等设计,多Agent协作就会出现重复扣款、重复下单等难以复现的故障。
基于主题与标签的路由表实现
当系统规模变大,仅靠receiver_id点对点发送不够灵活。引入主题和标签可以让一类Agent批量接收相关消息。路由表本质上是一张映射:主题对应订阅列表,标签用于精细化过滤。例如主题order.created下挂接库存、积分、通知三个Agent,它们各自通过标签表明只处理特定渠道的订单。
下面给出一个路由表配置的简单结构,以及匹配逻辑。标签以键值对形式附加在信封中,路由引擎在转发前做匹配。
{
"topics": {
"order.created": ["agent_stock", "agent_point", "agent_notify"],
"payment.done": ["agent_order", "agent_ledger"]
},
"tag_filters": {
"agent_notify": {"channel": "sms"}
}
}
匹配时,引擎先查主题得到候选Agent,再按tag_filters剔除不满足条件的。比如一条带channel:email的订单创建消息,就不会发给只订阅短信通知的Agent。这种机制让路由规则可读、可配置,运营人员也能参与调整,而不必改代码。
最后要提死信队列。当消息多次投递失败或无人订阅时,不应直接丢弃,而进入死信队列供人工或补偿Agent处理。结合前面说的协议版本与幂等,死信队列是防止通信混乱演变为业务损失的最后一道防线。把以上协议、路由、幂等、死信四点组合起来,多Agent系统的消息流才能从无序走向可控。
multi_agentmessage_protocolrouting_mechanism修改时间:2026-08-16 11:06:35