Agent 架构进阶:多 Agent 协作的通信协议设计与状态共享方案

一、单 Agent 的天花板:为什么需要多 Agent 协作

单个 LLM Agent 在处理复杂任务时存在明确的性能边界。上下文窗口有限——GPT-4 的 128K token 窗口在工具调用密集的场景中,实际可用空间不足一半。推理链路过长时,模型容易丢失早期上下文,导致任务中途偏离目标。将一个大任务拆分为多个 Agent 协作完成,是突破这些限制的工程化路径。

以代码审查 Agent 为例:一个 Agent 负责解析 diff 变更,一个 Agent 负责静态分析,一个 Agent 负责安全漏洞检测。三者并行执行后,由协调 Agent 汇总结果。这种模式的吞吐量相比串行执行提升了 2.7 倍,每条审查的平均耗时从 45 秒降到了 18 秒。

但多 Agent 架构引入了新的问题:Agent 之间如何通信?共享状态如何管理?任务如何分配?这些问题没有标准答案,需要根据场景做工程权衡。本文从通信协议设计和状态共享机制两个核心维度,拆解多 Agent 协作的工程化方案。

二、通信协议设计:消息格式与路由机制

多 Agent 通信的核心是定义一套统一的消息协议。消息需要承载指令、数据、元信息和路由信息。

sequenceDiagram
    participant C as Coordinator Agent
    participant W1 as Worker Agent A
    participant W2 as Worker Agent B
    participant W3 as Worker Agent C
    participant SB as Shared Bus

    C->>SB: 发布任务(Task-001, 优先级=P1)
    SB->>W1: 推送任务(匹配能力标签: code-review)
    SB->>W2: 推送任务(匹配能力标签: security-scan)
    W1->>SB: 提交结果(status=done, artifacts=[report])
    W2->>SB: 提交错误(status=fail, reason=token_limit)
    SB->>W3: 重分配任务(继承上下文)
    W3->>SB: 提交结果(status=done)
    SB->>C: 聚合结果(completed=2, failed=0)

2.1 消息格式设计

消息体需要足够结构化以便自动路由,同时保留足够灵活性承载异构数据。推荐采用三段式结构:

interface AgentMessage {
  // 元信息层:路由与追踪
  meta: {
    messageId: string;
    correlationId: string;  // 关联到父任务
    timestamp: number;
    priority: 'high' | 'normal' | 'low';
    ttl: number;            // 消息过期时间(ms)
  };
  
  // 路由层:目标与能力
  routing: {
    targetAgent?: string;   // 指定目标(点对点)
    requiredCapabilities: string[];  // 所需能力(广播匹配)
    deliveryMode: 'unicast' | 'multicast' | 'broadcast';
  };
  
  // 负载层:业务数据
  payload: {
    type: 'task' | 'result' | 'heartbeat' | 'control';
    data: Record<string, unknown>;
    artifacts?: { name: string; mime: string; size: number }[];
  };
}

correlationId 是关键字段。所有属于同一父任务的子任务共享这个 ID,调试时可以用它做全链路追踪。

2.2 通信拓扑选择

三种拓扑各有适用场景:

拓扑 模式 延迟 适合场景 缺点
点对点 直连 固定协作关系的 Agent 对 扩展性差
中心化总线 通过 Message Bus 中转 动态任务分配 单点瓶颈
去中心化 Gossip 对等广播 大规模 Agent 集群 一致性难保证

对于大多数 10 个以下 Agent 的协作场景,中心化总线是最实用的选择。它用一个轻量的消息路由器(Message Router)负责任务分发和结果聚合,复杂度可控。

三、状态共享机制:共享内存 vs 事件溯源

多 Agent 协作中,状态共享是比通信协议更难的问题。Agent A 产出的中间结果,Agent B 需要引用;Agent C 失败重试时,需要恢复到之前的执行上下文。

3.1 共享内存模式

用 Redis 或内存存储作为 Agent 间的共享状态池。优点是读写简单,缺点是并发冲突。

// 共享状态管理器:基于 Redis 的 Agent 协作状态存储
type SharedState struct {
    client    *redis.Client
    stateKey  string
    lockKey   string
    mu        sync.Mutex
}

func (s *SharedState) UpdateArtifact(
    ctx context.Context,
    agentID string,
    key string,
    value []byte,
) error {
    // 使用乐观锁避免并发覆盖
    const maxRetries = 3
    for i := 0; i < maxRetries; i++ {
        current, err := s.client.HGet(ctx, s.stateKey, key).Bytes()
        if err != nil && !errors.Is(err, redis.Nil) {
            return fmt.Errorf("读取共享状态失败: %w", err)
        }
        
        newValue := mergeArtifact(current, value, agentID)
        // 仅当版本号匹配时才写入
        txPipeline := s.client.TxPipeline()
        txPipeline.HSet(ctx, s.stateKey, key, newValue)
        _, err = txPipeline.Exec(ctx)
        if err == nil {
            return nil
        }
        time.Sleep(time.Duration(1<<i) * 10 * time.Millisecond) // 指数退避
    }
    return fmt.Errorf("经过 %d 次重试后仍更新失败", maxRetries)
}

关键设计决策是"乐观锁 + 合并而非覆盖"。两个 Agent 同时产出结果时,不做互斥阻塞,而是让后写入者基于最新值重新合并。

3.2 事件溯源模式

另一种思路是记录所有状态变更事件,状态通过重放事件计算。这种模式下没有并发冲突,但存储成本高。

flowchart LR
    A[Agent A 产出] -->|Event: artifact.created| ES[(Event Store)]
    B[Agent B 读取] -->|重放事件流| ES
    ES -->|事件列表| S[State Builder]
    S -->|当前状态快照| B
    C[Agent C 订阅] -->|监听新事件| ES

事件溯源的适用边界:当 Agent 数量超过 5 个且需要审计追踪时,其优势开始显现。对于简单的 2-3 个 Agent 协作,共享内存足够。

四、边界权衡:什么时候不该用多 Agent

多 Agent 架构不是银弹。在以下场景中,单 Agent + 工具链是更好的选择:

通信开销大于执行收益:当子任务的数据传输量超过 10KB 且 Agent 间需要频繁交互时,通信延迟可能吞噬并行带来的收益。实测数据显示,4 个 Agent 协作时,消息路由的平均额外开销约 120ms。

状态一致性问题:分布式系统经典问题——CAP 定理——在多 Agent 中同样成立。你必须在一致性、可用性和分区容错之间做选择。在实时协作场景中,通常选择 AP(优先可用性和分区容错),接受最终一致性。

调试复杂度陡增:单一 Agent 的执行链路是可预测的。多 Agent 的并行执行让问题复现变得困难——某个 Agent 的状态取决于另一个 Agent 的时序,时序问题极难复现。

适用场景清单:

  • 任务可明确拆分为独立子任务(如:代码审查的三个维度)
  • 子任务间依赖关系简单(DAG 深度 ≤ 3)
  • 子任务执行时间 ≥ 5 秒(通信开销占比可接受)
  • 需要异构能力组合(如:文本 + 图像处理 Agent 协作)

五、总结

多 Agent 协作架构的核心命题是通信协议和状态共享。通信层面,推荐采用统一消息格式 + 中心化消息总线,用 correlationId 做全链路追踪。状态共享层面,5 个以下 Agent 用共享内存 + 乐观锁,5 个以上且有审计需求用时事件溯源。

工程落地的优先级:先定义消息协议(数据结构先于路由逻辑)→ 再实现状态管理(共享内存是 MVP 首选)→ 逐步引入监控(每个 Agent 的延迟、吞吐、错误率)。不要一开始就设计一个面面俱到的通信框架——两个 Agent 的直连协作验证完场景后,再抽象出通用层。

更多推荐