多智能体系统并不天然优于单个 Agent,它只是另一组权衡。当你把一个任务拆给多个 Agent 时,你买到的是隔离、并行和独立归属,付出的代价是更高的 Token 成本、协调开销、更大的失败面,以及更难调试的 Trace。本文谈的正是如何刻意地做这笔交易:这个模式在什么条件下值得、该如何组织、以及哪些失败模式决定了它能否扛住真实负载。内容最后一次技术核验时间为 2026 年 7 月 16 日。

核心结论

  • 从单个 Agent 起步。只有当隔离、并行或归属能带来可度量的价值时,才增加 Agent。
  • 任务有多个步骤,本身并不是采用多 Agent 的理由。固定顺序的流程通常更适合做成确定性工作流。
  • 架构选型——层级式、对等式还是混合式——应基于工作必须如何被分解和控制,而不是哪种看起来更高级。
  • 给每个 Agent 独立的工具集和权限边界。角色提示塑造行为,但并不约束能力。
  • 把每条 Agent 间消息和工具返回值都当作不可信输入,在边界处校验。
  • 为成本做预算。相互协调的 Agent 可能消耗比单次对话高约一个数量级的 Token。
  • 评估执行轨迹和真实业务结果,而不只是最终那份报告。

多智能体系统在什么条件下才真正值得

第一个设计问题不是"我该如何构建多智能体系统",而是"我到底需不需要"。

Anthropic 关于构建高效 Agent 的建议很明确:从最简单的方案开始,只有当收益能覆盖代价时才增加自主性。很多"多 Agent"设计其实是一条固定流水线——先研究、再分析、后写作——被包装成了一支团队。如果这些步骤总是按同样的顺序执行,没有分支、没有协商、也没有真正的并行,那么确定性工作流或一个配了合适工具的单 Agent 会更便宜、更快,也远更容易调试。

一个多智能体系统只有在满足以下至少一条时,才对得起它的复杂度:

  • 不同的权限边界。 某个专家确实需要别人不能拥有的访问权——例如一个可以触及生产环境的部署 Agent,与一个始终只读的审查 Agent。
  • 上下文隔离。 一个领域的上下文会拖累另一个领域的表现,把它们分开能改善各自的决策。
  • 真正的并行。 相互独立的子任务能同时运行,且节省的墙钟时间确实有意义。
  • 归属分离。 不同团队在稳定接口之后各自构建、拥有并评测不同的能力。

如果这些都不成立,增加 Agent 大多只是增加了模型调用、延迟和出错的方式。

系统 谁决定下一步 适用场景 主要代价
单次 LLM 调用 应用代码 分类、抽取、改写 能力最有限
确定性工作流 应用代码 稳定、有序的业务流程 缺乏适应性
单 Agent 循环中的一个模型 单一权限范围内的开放式任务 局限于一份上下文
多智能体系统 多个模型协调运行 隔离、并行或归属分离 协调开销与成本

多Agent架构模式

一旦多智能体系统是合理的,它的结构就取决于工作必须如何被分解和控制。三种模式覆盖了大部分设计。

1. 层级式(管理者-执行者)

管理者 Agent 分解目标并派发子任务,执行 Agent 完成后回报。这正是 Anthropic 所说的编排者-工作者模式,在分解清晰时是最稳妥的默认选择。

graph TD M["管理者Agent 任务规划与分配"] --> W1["执行Agent 1 数据收集"] M --> W2["执行Agent 2 数据分析"] M --> W3["执行Agent 3 报告生成"] W1 --> M W2 --> M W3 --> M style M fill:#e1f5fe style W1 fill:#fff3e0 style W2 fill:#fff3e0 style W3 fill:#fff3e0
  • 适用:分解结构清晰、需要集中控制、执行流程相对固定的任务。
  • 优点:控制流清晰、便于监督、责任明确。
  • 缺点:管理者会成为瓶颈和单点故障,适应性较弱。

2. 对等式

所有 Agent 地位平等,通过协商、投票或共享工作空间得出结果。适合不该由单个 Agent 独揽决策的场景。

graph LR A1["Agent 1 研究员"] <--> A2["Agent 2 分析师"] A2 <--> A3["Agent 3 撰稿人"] A3 <--> A1 style A1 fill:#e8f5e9 style A2 fill:#e8f5e9 style A3 fill:#e8f5e9
  • 适用:多方协商、能力相近或互补的 Agent、边界模糊的任务。
  • 优点:灵活、没有单一协调者会失效、适应性强。
  • 缺点:协调开销大、可能陷入循环或悬而未决的冲突、更难推理。

3. 混合式

把两者结合:顶层是协调层,下面是层级式团队,团队之间有有限的对等连接。大多数大型系统最终都落在这里。

graph TB subgraph "决策层" C[协调者Agent] end subgraph "执行层 - 团队A" A1[Leader A] --> A2[Worker A1] A1 --> A3[Worker A2] end subgraph "执行层 - 团队B" B1[Leader B] --> B2[Worker B1] B1 --> B3[Worker B2] end C --> A1 C --> B1 A1 <-.-> B1 style C fill:#f3e5f5 style A1 fill:#e1f5fe style B1 fill:#e1f5fe
  • 适用:需要在集中控制与局部灵活之间取得平衡的多团队大型系统。

通信与协调

多智能体系统真正的工程挑战不在 Agent 本身,而在它们之间的空隙。

通信模式

模式 描述 适用场景
直接通信 两个 Agent 之间点对点消息 简单、定义明确的交互
广播通信 一对多通知 状态同步、全局信号
黑板系统 一个供 Agent 读写的共享工作空间 异步协作、知识共享
消息队列 通过中间件解耦投递 高并发、松耦合系统

无论用哪种传输方式,消息都应结构化、带版本,并在边界处校验。一个原样信任另一个 Agent 输出的 Agent,会继承对方所有的错误。

协调机制

合同网协议——发布任务、收集投标、择优授标——是能力各异时分配工作的一种成熟做法:

python
from enum import Enum
from dataclasses import dataclass
from typing import List, Dict, Optional

class CoordinationType(Enum):
    CONTRACT_NET = "contract_net"
    VOTING = "voting"
    AUCTION = "auction"
    NEGOTIATION = "negotiation"

@dataclass
class Task:
    id: str
    description: str
    requirements: List[str]
    priority: int

@dataclass
class Bid:
    agent_id: str
    task_id: str
    capability_score: float
    estimated_time: float

class ContractNetProtocol:
    def __init__(self, manager_agent):
        self.manager = manager_agent
        self.bids: Dict[str, List[Bid]] = {}

    def announce_task(self, task: Task) -> None:
        self.bids[task.id] = []
        for agent in self.get_available_agents():
            agent.receive_announcement(task)

    def collect_bid(self, bid: Bid) -> None:
        if bid.task_id in self.bids:
            self.bids[bid.task_id].append(bid)

    def award_contract(self, task_id: str) -> Optional[str]:
        bids = self.bids.get(task_id, [])
        if not bids:
            return None
        best_bid = max(bids, key=lambda b: b.capability_score / b.estimated_time)
        return best_bid.agent_id

    def get_available_agents(self):
        raise NotImplementedError

冲突解决

  • 资源冲突 —— 多个 Agent 竞争同一资源。用优先级队列、资源预留或时间片轮转解决。
  • 目标冲突 —— Agent 追求相互矛盾的目标。用仲裁 Agent、显式优先级或协商协议解决。
  • 信息冲突 —— Agent 持有不一致的状态。指定一个权威系统并据此对齐,而不是让每个 Agent 各执一份"真相"。

框架选型

先定义流程、失败策略和运维要求。框架的流行度不是架构需求,而且这个生态变化很快——把任何具体版本、模型名或跑分都当作需要向厂商核验的带日期数据点。

框架 特点 典型架构 学习曲线 适用场景
CrewAI 基于角色、上手快 层级式 / 顺序式 团队模拟、工作流自动化
AutoGen 对话驱动;注意其架构在大版本之间有过较大变动 对等式对话 多轮对话、代码协作
LangGraph 带检查点和中断的状态图 混合式、可恢复 较高 复杂、有状态、需人工介入的流程
MetaGPT 模拟一家软件公司的角色 层级式 代码生成、项目模拟
OpenAI Agents SDK 少量核心原语:Agent、工具、Handoff、Session、Trace Handoff / 管理者 轻量多 Agent 交接(取代实验性的 Swarm)

OpenAI 早期的 Swarm 项目明确定位为教学实验,其思路已被吸收进面向生产的 Agents SDK,因此新项目应以 SDK 为目标,而非 Swarm。

可运行示例

下面的示例刻意保持最小化。模型标识符经常变动,因此每个示例都从环境变量读取模型,而不是写死一个会过期的名字。

用 CrewAI 构建顺序式研究团队

python
import os
from crewai import Agent, Task, Crew, Process
from langchain_openai import ChatOpenAI

# 模型标识符是易腐信息,请通过环境变量设置当前值。
llm = ChatOpenAI(model=os.environ.get("OPENAI_MODEL", "gpt-4o"))

researcher = Agent(
    role="高级研究员",
    goal="就指定主题收集全面、准确的信息",
    backstory="你会跨多个来源核实论断并记录出处。",
    verbose=True,
    allow_delegation=False,
    llm=llm,
)

analyst = Agent(
    role="数据分析师",
    goal="把研究转化为具体、经得起推敲的洞察",
    backstory="你能从噪声中分离信号,并标记证据薄弱之处。",
    verbose=True,
    allow_delegation=False,
    llm=llm,
)

writer = Agent(
    role="内容撰稿人",
    goal="基于分析产出清晰的报告",
    backstory="你行文平实,绝不编造分析未支持的事实。",
    verbose=True,
    allow_delegation=False,
    llm=llm,
)

research_task = Task(
    description="研究当前多 Agent 协调的主流做法。",
    expected_output="一份带来源和出处的研究报告,含关键发现",
    agent=researcher,
)
analysis_task = Task(
    description="识别研究中最强和最弱的论断。",
    expected_output="一份简短分析,区分证据充分与推测性的观点",
    agent=analyst,
)
writing_task = Task(
    description="仅根据分析撰写最终报告。",
    expected_output="一份结构化、不含无据论断的报告",
    agent=writer,
)

crew = Crew(
    agents=[researcher, analyst, writer],
    tasks=[research_task, analysis_task, writing_task],
    process=Process.sequential,
    verbose=True,
)

result = crew.kickoff()
print(result)

这是最经典的"团队"示例,也值得对它坦诚:一条严格顺序的研究 → 分析 → 写作流水线,恰恰是多 Agent 相比"用同样三段提示词的单个 Agent"几乎没有额外收益的情形,甚至常常不如一条确定性工作流。它是学习框架的好方式,但只有当步骤出现分支、当某个 Agent 需要别人不能有的权限、或当独立工作能真正并行时,它才成为一个真正的多 Agent 案例。

用 AutoGen 构建对话式小组

python
import os
import autogen

config_list = [{
    "model": os.environ.get("OPENAI_MODEL", "gpt-4o"),
    "api_key": os.environ["OPENAI_API_KEY"],
}]

user_proxy = autogen.UserProxyAgent(
    name="user_proxy",
    human_input_mode="TERMINATE",
    max_consecutive_auto_reply=10,
    code_execution_config={"work_dir": "workspace", "use_docker": True},
)

architect = autogen.AssistantAgent(
    name="architect",
    system_message="你负责设计整体结构,并为每个选择给出理由。",
    llm_config={"config_list": config_list},
)

developer = autogen.AssistantAgent(
    name="developer",
    system_message="你实现架构师的设计,并说明你的假设。",
    llm_config={"config_list": config_list},
)

reviewer = autogen.AssistantAgent(
    name="reviewer",
    system_message="你审查正确性与安全性,并引用具体行号。",
    llm_config={"config_list": config_list},
)

groupchat = autogen.GroupChat(
    agents=[user_proxy, architect, developer, reviewer],
    messages=[],
    max_round=20,
)
manager = autogen.GroupChatManager(
    groupchat=groupchat,
    llm_config={"config_list": config_list},
)

user_proxy.initiate_chat(
    manager,
    message="设计并实现一个小型的 Agent 任务调度器。",
)

注意 code_execution_config 会运行生成的代码。请把它沙箱化(use_docker=True 或等效的隔离环境);一个能在你主机上执行任意代码的 Agent 小组是负债,而不是特性。AutoGen 的 API 在大版本之间变化很大,依赖上面这种写法前请先在其文档中确认当前接口。

用 LangGraph 构建有状态工作流

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

class MultiAgentState(TypedDict):
    messages: Annotated[List[str], operator.add]
    current_agent: str
    task_status: dict
    final_result: str

def research_node(state: MultiAgentState) -> dict:
    return {
        "messages": ["researcher: 信息已收集"],
        "current_agent": "analyst",
        "task_status": {**state["task_status"], "research": "done"},
    }

def analysis_node(state: MultiAgentState) -> dict:
    return {
        "messages": ["analyst: 分析已完成"],
        "current_agent": "writer",
        "task_status": {**state["task_status"], "analysis": "done"},
    }

def writing_node(state: MultiAgentState) -> dict:
    return {
        "messages": ["writer: 初稿已完成"],
        "current_agent": "reviewer",
        "task_status": {**state["task_status"], "writing": "done"},
    }

def review_node(state: MultiAgentState) -> dict:
    if needs_revision(state):
        return {"messages": ["reviewer: 需要修改"], "current_agent": "writer"}
    return {
        "messages": ["reviewer: 已通过"],
        "final_result": "任务完成",
        "current_agent": "end",
    }

def route_after_review(state: MultiAgentState) -> str:
    return END if state["current_agent"] == "end" else state["current_agent"]

def needs_revision(state) -> bool:
    return False

workflow = StateGraph(MultiAgentState)
workflow.add_node("researcher", research_node)
workflow.add_node("analyst", analysis_node)
workflow.add_node("writer", writing_node)
workflow.add_node("reviewer", review_node)

workflow.set_entry_point("researcher")
workflow.add_edge("researcher", "analyst")
workflow.add_edge("analyst", "writer")
workflow.add_edge("writer", "reviewer")
workflow.add_conditional_edges("reviewer", route_after_review)

app = workflow.compile()

result = app.invoke({
    "messages": [],
    "current_agent": "researcher",
    "task_status": {},
    "final_result": "",
})

审查节点通向撰写节点的条件边,正是 LangGraph 价值所在:这个修订循环是真正的分支,而不是固定流水线;LangGraph 的检查点让你能跨故障持久化并恢复这个循环。

失败模式与生产考量

多智能体系统会以单 Agent 不会有的方式失败。请从一开始就为它们做设计。

  • 成本会翻倍。 每一条协调消息都是会被反复读取的上下文。Anthropic 报告过:一个多 Agent 研究架构消耗的 Token 可能比单 Agent 对话高约一个数量级,因此只有当任务价值和并行收益足以覆盖开销时才划算。为每个 Agent 和整个系统设定预算并强制执行。
  • 错误会级联。 一个返回了"自信但错误"结果的执行者,会毒害每一个信任它的下游 Agent。请校验观察结果,并优先选择那种在坏结果扩散前,由审查者或权威系统能拦下它的设计。
  • 循环与死锁。 对等式协商可能无限循环或卡住。为轮次、工具调用、墙钟时间和成本设上限;要求每一轮都有可衡量的进展;进展停滞时升级人工。
  • 共享状态被破坏。 黑板是一个共享的可变资源。没有指定的权威系统和对齐机制,Agent 就会相互覆写。绝不要让向量库或草稿区成为余额、权限或状态的真相来源。
  • 每个 Agent 各自的权限边界。 "你只审查、绝不修改"这样的角色提示塑造行为,但并不约束能力。要用每个 Agent 的工具集来强制它:一个只读的审查者就该只有只读工具。认证不是授权——对象级访问控制属于你的服务端,且要在每一次请求上校验。
  • 不可信输入会穿过每一条边。 把 Agent 间消息、工具返回值,以及任何经 MCP 拉取的内容都当作数据,而不是带授权的指令。这是多 Agent 版的提示词注入,而且爆炸半径更大,因为一个被攻陷的 Agent 能驱动其他 Agent。

评测与可观测性

记录足够多的信息以便重建任何一次运行:行动的是哪个 Agent、调用了什么工具及校验后的参数、结果及其耗时、状态迁移、以及最终结果及其验证结论。导出前脱敏密钥和客户数据,并为 Trace 和业务记录分别设定保留周期。

层级 核心问题 示例指标
结果 用户目标是否达成 正确解决率
轨迹 Agent 是否走了合理路径 非法调用、循环、冗余步骤
运营 是否高效可靠 p95 延迟、Token 成本、人工升级率

用真实、匿名化的任务构建评测集——包含工具故障、越权、提示词注入和 Agent 之间相互矛盾的输出——并在每次修改 Prompt、模型、工具 Schema 或协调图时运行它。一份精美的最终报告可能掩盖一条坏掉的轨迹;业务结果验证才是发布门禁。

最佳实践

  • 每个 Agent 单一职责。 一个清晰的领域,与其他 Agent 互补。
  • 稳定的接口。 定义好消息 Schema,让某个 Agent 能被替换或升级而不破坏邻居。
  • 最小权限。 每个 Agent 只拿到它角色所需的工具。
  • 一切有界。 轮次、重试、时间和成本都有硬上限。
  • 默认可观测。 每个决策、工具调用和结果都可追溯。

常见问题

多Agent系统和单Agent有什么区别?

单 Agent 运行一个循环,只有一套工具和一份上下文。多 Agent 系统把工作拆给多个拥有独立上下文和权限的 Agent。这种拆分以更高的 Token 开销、协调成本和更难的调试为代价,换来隔离、并行和独立归属。应从单 Agent 起步,收益可度量时再增加 Agent。

如何选择框架?

让框架匹配工作负载:基于角色的工作流选 CrewAI,对话驱动的协作选 AutoGen,有状态、可恢复、需人工介入的图选 LangGraph。请在定义好流程、失败策略和运维要求之后再决定,而不是在此之前。

主要挑战是什么?

成本、错误级联、协调开销、跨 Agent 的状态一致性,以及调试困难。它们都是架构问题,因此要在设计中解决——预算、校验、权威系统、每个 Agent 的权限、以及 Trace——而不是靠换一个更大的模型。

如何优化性能?

削减不必要的 Agent 间消息、缓存稳定结果、在子任务独立时用异步通信、避免拆分成过多小 Agent,并让模型选型匹配每个 Agent 的实际难度,而不是处处都用最大的模型。

总结

多智能体系统是一件强大的工具,也是一件容易被滥用的工具。它的纪律与单个 AI Agent 相同:构建能解决问题的最小方案,让每个动作可观察、可验证,只给每个组件它所需的访问权,只有当收益真实且经过度量时才增加自主性。一个多步骤任务并不需要一支 Agent 团队。需要它的,是隔离、并行和归属。

延伸阅读

一手资料