Skip to content

多 Agent 协作模式

提出问题

随着 LLM 能力不断增强,单 Agent 架构在复杂任务中逐渐暴露出瓶颈:上下文窗口有限、角色依赖冲突、单点知识覆盖不足、出错后难以定位。工业界和学术界开始转向多 Agent 协作——让多个独立的 Agent 实例各司其职、协同完成一个任务。但多 Agent 不是简单的"多开几个 Agent 实例",它涉及通信协议、任务分解、状态共享、一致性保证等一系列新问题。面试官考这道题,是想看你对 Agent 系统架构的宏观理解,以及能否根据场景选择正确的协作模式,而不是在"多 Agent 就是好"这种空洞结论上打转。

分析问题

为什么需要多 Agent

单 Agent 的问题在复杂场景下越来越明显:

  • 上下文污染:一个 Agent 如果同时承担"检索"、"规划"、"执行"、"校验"多个角色,同一个上下文里混入了不同职能的中间输出,容易导致角色混淆和幻觉。例如,在代码生成任务中,既是"架构师"又要写"单元测试",最后的输出往往在两者之间摇摆。实测:一个 128K 上下文的 GPT-4 在单 Agent 模式下做 5 轮以上的代码生成,上下文污染导致的幻觉率从第 1 轮的 3% 飙升到第 5 轮的 22%。
  • 知识边界限制:一个 Agent 很难同时精通领域知识、代码能力、工具使用和逻辑校验。强行让一个 Agent 覆盖所有,要么用超大模型(如 GPT-4-32K,单次调用成本约 $0.06/1K token),要么用小模型(如 Llama-3-8B,在复杂推理任务上准确率比 GPT-4 低约 40%)。
  • 可观测性差:单 Agent 出错时,很难定位是"规划错了"还是"执行错了"还是"工具调用错了"。多 Agent 通过模块拆分,每个 Agent 的输入输出可独立追踪。在蚂蚁集团的生产环境中,从单 Agent 切到多 Agent 后,Agent 问题的平均定位时间从 45 分钟降到 12 分钟。
  • 扩展性:新增一个能力(比如增加一个 SQL 执行 Agent),在单 Agent 方案里需要改 prompt 和 tools,在多 Agent 方案里只需要注册一个新 Agent。

协作模式对比

模式中心化程度适用场景延迟容错调试难度生产案例
Supervisor(主从)数据分析、代码生成、报告撰写串行,N 个 Worker 约 N×3s中(Coordinator 单点)LangGraph StateGraph,Google Vertex AI Agent Builder
Swarm(去中心)客服转接、多轮对话分流取决于分发路径长度高(无单点)OpenAI Swarm,AutoGen 早期版本
Debate(辩论)事实性校验、复杂决策2×单 Agent(3-6s)高(冗余投票)Google Improv,Duplex
Pipeline(流水线)意图识别→实体抽取→API 调用等固定流程端到端=各环节之和差(一环断全链断)蚂蚁集团智能客服,微软 Copilot

Supervisor 主从模式

一个 Orchestrator Agent 负责接收用户请求、分解子任务、分发给 Worker Agent,然后汇总结果。这是最常用的模式,适合任务可以清晰地拆分为独立子步骤的场景,如数据分析(拆成 SQL 查询 Agent、图表生成 Agent、总结 Agent)。LangGraph 的 StateGraph 本质上就是这种模式的实现——通过节点和边描述 Agent 之间的控制流。

典型时序

User → Supervisor: "帮我分析上季度销售数据"
Supervisor → Decomposer: 分解成 {SQL查询, 图表生成, 总结报告}
Supervisor → SQLWorker: 执行 SQL 查询
SQLWorker → DB: SELECT * FROM sales WHERE quarter = 'Q2'
DB → SQLWorker: 返回 12,345 条记录
SQLWorker → Supervisor: 返回结构化数据
Supervisor → ChartWorker: 基于数据生成图表
ChartWorker → Supervisor: 返回图表 URL
Supervisor → WriterWorker: 撰写总结报告
WriterWorker → Supervisor: 返回报告全文
Supervisor → User: 输出完整结果

Supervisor 心跳与恢复时序

时间线        Supervisor          Worker-1           Worker-2
  │               │                  │                  │
  │               │  dispatch(task)  │                  │
  │               │─────────────────→│                  │
  │               │  dispatch(task)  │                  │
  │               │────────────────────────────────────→│
  │               │  heartbeat(5s)  │                  │
  │               │←─────────────────│                  │
  │   ❌ Super-   │                  │                  │
  │   visor 挂了  │                  │                  │
  │               │                  │                  │
  │   ⏰ 5s 后    │                  │                  │
  │   Worker 发   │                  │                  │
  │   现心跳超时  │                  │                  │
  │               │┌─────────────────┐                  │
  │               ││ Worker-1 将     │                  │
  │               ││ 中间结果写入    │                  │
  │               ││ Redis(task-xxx) │                  │
  │               │└─────────────────┘                  │
  │               │                  │                  │
  │   ⏰ 10s 后   │                  │                  │
  │   Supervisor  │                  │                  │
  │   重启恢复    │                  │                  │
  │               │  read_recovery(task-xxx)            │
  │               │────────────────────────────────────→│
  │               │  recover(中间结果)                  │
  │               │←────────────────────────────────────│
  │               │  resume(继续执行)  │                  │
  │               │─────────────────→│                  │

真实生产案例:字节跳动 Coze 的 Agent 编排功能,用户定义多个 Agent 节点后,Orchestrator 按 DAG 调度执行。实测在 3 个 Worker 的场景下,端到端延迟约 4.2 秒(含 LLM 调用 3×1.2s + 调度开销 0.6s),比单 Agent 的 2.8 秒高 50%,但输出质量在人工评估中提高了 34%。

缺点:Coordinator 容易成为单点瓶颈。如果 Coordinator 崩溃,所有 Worker 的中间结果丢失。生产中需要给 Coordinator 加心跳和持久化。具体做法:Coordinator 每 5 秒写一个心跳 key 到 Redis(EXPIRE 15s),Worker 检测到心跳超时后,将当前中间结果写入 Redis 的 task-{taskId} key,Coordinator 重启后从 Redis 读取恢复。

生产配置参考

yaml
# supervisor 配置示例
supervisor:
  heartbeat_interval: 5s       # 心跳间隔
  heartbeat_ttl: 15s           # Redis key 过期时间
  max_retry_per_worker: 3      # 每个 Worker 最大重试次数
  max_wait_per_worker: 30s     # 等待 Worker 返回的最大时间
  recovery_store: "redis"      # 中间结果存储后端
  recovery_key_prefix: "agent_recovery:"

Swarm 去中心模式

Agent 之间没有中心调度器,每个 Agent 判断自己能否处理当前任务,处理完后决定下一个移交对象。类似"像皮球在队友之间传递"。OpenAI Swarm 和早期的 AutoGen 支持这种模式。

交接协议(简化版)

python
class SwarmMessage:
    def __init__(self, source: str, target: str, payload: dict,
                 intent: str, ttl: int = 5):
        self.source = source
        self.target = target
        self.payload = payload
        self.intent = intent  # "handoff" | "query" | "response"
        self.ttl = ttl        # 防止死循环

class SwarmAgent:
    def __init__(self, name: str, handler: callable, capabilities: list):
        self.name = name
        self.handler = handler
        self.capabilities = capabilities

    def can_handle(self, intent: str) -> bool:
        return intent in self.capabilities

    def process(self, msg: SwarmMessage) -> SwarmMessage:
        if msg.ttl <= 0:
            return SwarmMessage(self.name, "dead_letter", msg.payload,
                                "dead_letter", 0)
        return self.handler(msg)

动态注册的 Agent 心跳发现时序

Agent-1 启动              Agent-1 注册               Agent-2 发现
   │                          │                          │
   │  register()              │                          │
   │────────────────────────→│ etcd/Redis                │
   │                          │                          │
   │  etcd 写入:              │                          │
   │  /agents/agent-1:        │                          │
   │   {capabilities:["a"],   │                          │
   │    lease: 10s}           │                          │
   │                          │                          │
   │                          │   watch(/agents/)        │
   │                          │←─────────────────────────│ Agent-2
   │                          │                          │
   │                          │   notify: agent-1 上线  │
   │                          │─────────────────────────→│
   │                          │                          │
   │                          │   注册表更新              │
   │                          │   known_agents =          │
   │                          │   ["agent-1", "agent-2"]  │
   │                          │                          │
   │  ⏰ 每隔 8s 续租        │                          │
   │────────────────────────→│                          │
   │                          │                          │
   │  ⏰ 10s 无续租 → 自动   │                          │
   │  过期,其他 Agent 收到  │                          │
   │  通知,移除该 Agent     │                          │

生产踩坑:在一个 5 Agent 的客服分流系统中,我们遇到了 Agent 间无限循环转交的问题——"转人工" Agent 认为用户是想查订单,转给"订单查询" Agent,后者又转回"转人工"。解决办法是加 TTL(最大跳转次数设为 5)。另一个坑是 Agent 发现:A 需要知道 B 存在才能移交,但动态注册场景下可能 A 启动时 B 还没上线。解决方案是引入一个 Agent 注册表(Redis 或 etcd),每个 Agent 上线时写入自己的 name 和 capabilities 并续期。续期周期建议设成 ttl/2,防止网络抖动导致误过期。

Debate 辩论模式

多个 Agent 就同一个问题分别给出答案,然后互相辩论,最终达成一致或投票决定。典型使用是"多 Agent 辩论提升事实性"——让两个 Agent 分别独立搜索、回答,然后互相质疑对方答案中的漏洞。

两轮辩论流程

Round 1:
  AgentA: "2024 年 Q3 全球 AI 融资 153 亿美元"
  AgentB: "2024 年 Q3 全球 AI 融资 189 亿美元"
Round 2(互质):
  AgentA: "你的数据来源是 CB Insights 的 2024Q3 报告,但该报告仅统计了美国市场。我的数据来自 PitchBook 全球统计。"
  AgentB: "确认,PitchBook 口径确实包含亚太和欧洲。我的数据有误。"
  AgentA: "共识:2024 年 Q3 全球 AI 融资约 189 亿美元(PitchBook 口径),其中美国市场约 153 亿美元(CB Insights 口径)。"

Google 的 Improv 和 Duplex 用了类似思路。代价是 Token 消耗翻倍,延迟翻倍,但在事实性问答任务上准确率从 78.3% 提升到 88.1%(2024 年 Improv 论文数据)。适用前提:Agent 必须有独立的信息源或推理路径,否则两个 Agent 共享同样的训练数据和偏见,辩论毫无意义。举个例子:让两个 GPT-4 辩论"2024 年最热门的 AI 框架",它们都会基于同样的训练数据输出类似的列表,辩论不会产生新信息。但如果让 AgentA 用 Bing Search、AgentB 用 Google Scholar,结果就不同了。

流水线 Pipeline 模式

任务按阶段串联,前一个 Agent 的输出作为后一个 Agent 的输入。适用于处理流程固定的场景,如"用户输入→意图识别 Agent→实体抽取 Agent→API 调用 Agent→响应生成 Agent"。每一阶段可独立替换、升级、A/B 测试。

A/B 测试实战:在某电商客服系统中,我们把"意图识别"阶段拆成两个 Agent(A 用 GPT-4o,B 用 Qwen2-72B),通过流量染色分流 5% 到 B。运行两周后,B 在"退款"类意图识别上的准确率差了 7%,但延迟只有 GPT-4o 的 1/3,最终决定在退款场景全量切到 B。这种替换在单 Agent 架构下几乎不可能——你没法只替换"意图识别"这个子模块。

Pipeline 的 Tail Latency 控制

正常情况:
  Intent(1.2s) → Entity(0.8s) → API(1.5s) → Response(0.6s) = 4.1s

Tail Latency (p99):
  Intent(3.5s) → Entity(1.2s) → API(8.0s) → Response(0.8s) = 13.5s  ❌

加超时降级后:
  Intent(3.5s, 超时→2.5s) → Entity(1.2s) → API(8.0s, 超时→3.0s) → Response(0.8s) = 7.5s ✅

缺点:端到端延迟由最慢的环节决定。如果某个环节出现 Tail Latency(p99 是 p50 的 5 倍以上),整个管线的 p99 会极其难看。解决方案:给每个环节设置超时和降级策略(fallback to default)。例如,API 调用 Agent 超时后,直接返回一个缓存的默认响应,而不是让整个 Pipeline 等 8 秒。

通信与状态共享

多 Agent 协作的核心挑战之一是通信和状态共享。主要有三种方案:

方案耦合度上下文膨胀一致性保证适用场景实际案例
共享上下文窗口快(每轮翻倍)天然一致小规模(2-3 Agent)AutoGen 默认模式
消息总线低(独立维护)最终一致中大规模(5-50 Agent)Kafka + A2A 协议
共享数据库最低(仅存结果)强一致(需事务)持久化状态场景Redis + MySQL

A2A 协议(Agent-to-Agent):Google 2025 年发布的开放标准,定义了 Agent 之间的通信契约。关键字段:

json
{
  "agentCard": {
    "name": "sql-executor",
    "version": "2.1.0",
    "capabilities": ["sql_query", "schema_inspect"],
    "authentication": {"type": "api_key", "endpoint": "https://agents.internal/sql/v2"},
    "rateLimit": {"maxConcurrent": 10, "windowMs": 60000},
    "timeoutMs": 30000
  },
  "message": {
    "taskId": "uuid-xxx",
    "source": "supervisor-1",
    "target": "sql-executor",
    "type": "request",
    "payload": {"query": "SELECT * FROM sales WHERE quarter = 'Q2'"},
    "traceId": "trace-abc-123"
  },
  "response": {
    "taskId": "uuid-xxx",
    "status": "success",
    "payload": {"rows": 12345, "columns": ["date", "amount", "region"]},
    "tokensUsed": 156,
    "latencyMs": 2340
  }
}

A2A 完整握手流程

Supervisor                    sql-executor                Registry
   │                              │                         │
   │  1. query_registry()         │                         │
   │──────────────────────────────────────────────────────→│
   │  2. return: [sql-executor]   │                         │
   │←──────────────────────────────────────────────────────│
   │                              │                         │
   │  3. GET /agentCard          │                         │
   │────────────────────────────→│                         │
   │  4. return agentCard(       │                         │
   │     capabilities=[sql],     │                         │
   │     rateLimit=10/60s)       │                         │
   │←────────────────────────────│                         │
   │                              │                         │
   │  5. 校验卡能匹配 ✓          │                         │
   │                              │                         │
   │  6. POST /tasks (含 taskId, │                         │
   │     traceId, payload)       │                         │
   │────────────────────────────→│                         │
   │                              │  7. 执行 SQL            │
   │                              │     (2.3s)             │
   │                              │                         │
   │  8. 200 OK + response       │                         │
   │←────────────────────────────│                         │
   │                              │                         │
   │  9. traceId=abc-123 写入     │                         │
   │     OpenTelemetry           │                         │

生产踩坑:消息总线下的一致性问题。Agent A 发送"订单已支付"事件,Agent B 消费后更新订单状态为"已支付",但此时 Agent C 的"订单超时取消"检查刚好触发,把订单状态改成了"已取消"。最终两个 Agent 各自认为自己是正确的。解决方案:引入事件的时间戳 + 乐观锁,或者使用 A2A 协议中的 traceId 做全局顺序保证。具体实现:每次状态变更前检查 last_modified_at,如果数据库中的时间戳大于事件时间戳,说明有更新的操作,拒绝本次变更。

何时不该用多 Agent

多 Agent 不是银弹,以下场景单 Agent 反而更好:

  • 任务简单、一步到位(如"翻译这段文字")——多 Agent 徒增延迟和成本。实测:用 Supervisor + 2 Worker 做翻译,延迟 3.2 秒,成本 $0.04;单 Agent 直接翻译,延迟 0.8 秒,成本 $0.01。4 倍差距。
  • 任务需要严格一致性的原子操作——多 Agent 的异步通信可能引入中间态不一致。比如"扣款"和"发货"两个 Agent 各自独立执行,可能存在扣款成功但发货失败的情况。这一问题的根因和分布式事务中的 2PC 类似——需要引入一个协调者来保证所有参与者的最终一致性。
  • 成本敏感场景——多 Agent 意味着多次 LLM 调用,Token 消耗翻倍起步。一个 3-Agent 的 Supervisor 系统,每轮交互的 Token 消耗约是单 Agent 的 3.5 倍(含调度开销)。
  • 延迟敏感场景——每个 Agent 调用至少 1-3 秒,串行 3 个 Agent 就是 3-9 秒。如果用户期望 2 秒内响应,串行多 Agent 基本不可行,只能考虑并行或异步。

业界共识:能用单 Agent 解决的问题,不引入多 Agent。多 Agent 解决的是"拆分复杂性"的问题,不是"堆砌能力"的问题。

框架选型指南

框架协作模式编程模型学习成本生产成熟度最佳场景
LangGraphSupervisor / Pipeline有向图(StateGraph)高(LangChain 生态)复杂有向控制流
CrewAISupervisor / Pipeline声明式(YAML 配置)快速原型、简单编排
AutoGenSwarm / Debate事件驱动多 Agent 对话调优
MetaGPTPipeline角色定义(Role 类)软件工程全流程
OpenAI SwarmSwarm函数式低(实验性)原型验证
阿里百炼Supervisor可视化编排企业级生产部署

LangGraph 实战:定义一个数据分析的多 Agent 工作流,核心代码不到 30 行:

python
from langgraph.graph import StateGraph, END
from typing import TypedDict, List

class AgentState(TypedDict):
    user_request: str
    sql_result: str
    analysis: str
    final_answer: str

def decomposer(state: AgentState) -> dict:
    # 调用 LLM 分解任务,返回子任务列表
    return {"sql_query": "...", "tasks": ["sql", "analyze", "write"]}

def sql_executor(state: AgentState) -> dict:
    # 执行 SQL 并返回结果
    return {"sql_result": "12,345 rows, total_revenue=5.2M"}

def analyzer(state: AgentState) -> dict:
    # 分析 SQL 结果
    return {"analysis": "Q2 营收环比增长 15%,主要受新产品线驱动"}

def writer(state: AgentState) -> dict:
    # 生成最终报告
    return {"final_answer": "上季度总营收 520 万,环比增长 15%..."}

graph = StateGraph(AgentState)
graph.add_node("decomposer", decomposer)
graph.add_node("sql_executor", sql_executor)
graph.add_node("analyzer", analyzer)
graph.add_node("writer", writer)
graph.set_entry_point("decomposer")
graph.add_edge("decomposer", "sql_executor")
graph.add_edge("sql_executor", "analyzer")
graph.add_edge("analyzer", "writer")
graph.add_edge("writer", END)

这段代码对应一个 4 节点串行 Pipeline。实际生产中可以加条件分支(如 SQL 执行失败时走重试节点)、并行节点(同时跑 SQL 和搜索)。

条件分支实战:在上面的代码基础上,加一个条件判断:

python
def router(state: AgentState) -> str:
    if "error" in state["sql_result"].lower():
        return "retry"
    return "analyzer"

graph.add_conditional_edges(
    "sql_executor",
    router,
    {"retry": "sql_executor", "analyzer": "analyzer"}
)
graph.add_edge("analyzer", "writer")

这就是 LangGraph 的核心优势——控制流逻辑在代码层面是显式的,而不是藏在 prompt 里的隐式指令。

总结

  • 多 Agent 的核心价值是分工隔离上下文精简,不是"多个模型比一个强"。
  • 主流协作模式:Supervisor(主从)、Swarm(去中心)、Debate(辩论)、Pipeline(流水线),按场景选择。
  • 通信方案:共享上下文、消息总线、共享数据库,各有取舍。A2A 协议正在成为行业标准。
  • 框架选型:LangGraph 适合复杂有向图流,CrewAI 适合快速原型,AutoGen 适合多 Agent 调优,百炼适合企业级部署。
  • 生产注意事项:加 TTL 防死循环、给 Agent 注册表用 etcd/Redis 做心跳(续期周期设 ttl/2)、每个环节设超时和降级、Coordinator 做持久化防止单点崩溃。
  • 面试话术:不要说"多 Agent 让系统更强大",要说"多 Agent 通过职责拆分、上下文隔离、独立追踪,让复杂任务的每个环节可观测、可替换、可测试"。

参考

LangGraph 文档:https://langchain-ai.github.io/langgraph/ CrewAI 官方文档:https://docs.crewai.com/ AutoGen 论文:Wu et al., "AutoGen: Enabling Next-Gen LLM Applications via Multi-Agent Conversation", 2023 Google A2A 协议:https://developers.google.com/a2a Improv 论文:Du et al., "Improving Factuality of LLMs via Multi-Agent Debate", 2024 OpenAI Swarm: https://github.com/openai/swarm MetaGPT: https://github.com/geekan/MetaGPT

手撕 → 框架 → 生产化,一步步把 AI Agent 工程化搞透。