2026年多智能体系统正经历一场深层架构迁移:从LangGraph代表的DAG/图状态机范式,经AWS Strands引领的事件驱动响应式架构,到Akka/Erlang思想在Agent领域的Actor模型复兴。三大范式各自解决了编排中的核心痛点——确定性、弹性与吞吐——但也各有致命盲区。本篇从编排引擎内部架构出发,深入拆解三种范式的Agent Loop实现、状态管理策略、容错机制与生产适配性,给出面向不同场景的范式选型决策树。
多Agent编排的本质问题只有一个:谁来决定下一个执行的Agent是谁,以及何时执行。三种范式给出了截然不同的答案。
| 维度 | DAG/图状态机 | 事件驱动/响应式 | Actor模型 |
|---|---|---|---|
| 代表框架 | LangGraph、AWS Step Functions | AWS Strands、Temporal | AutoGen Core、Akka-agents |
| 决策权 | 编译期确定(图拓扑) | 运行时涌现(事件匹配) | Agent自治(消息邮箱) |
| 状态管理 | 集中式状态图 | Event Sourcing + CQRS | Actor内部私有状态 |
| 并发模型 | 图节点并行 | Pub/Sub扇出 | 异步消息传递 |
| 容错策略 | 检查点回滚 | 重放 + DLQ | Supervisor树 |
| 延迟特征 | 中等(节点调度开销) | 低(事件直推) | 极低(内存邮箱) |
| 可观测性 | 图可视化 | 事件溯源审计 | 邮箱/调度追踪 |
| 上手难度 | 中等 | 高 | 高 |
| 适合场景 | 工作流确定的多步任务 | 高并发实时协作 | 高吞吐流式处理 |
graph TB
subgraph "DAG/图状态机范式"
A1[用户请求] --> B1[Planner Node]
B1 --> C1[Router Edge]
C1 --> D1[Agent A Node]
C1 --> E1[Agent B Node]
D1 --> F1[Merge Node]
E1 --> F1
F1 --> G1[Output]
end
subgraph "事件驱动范式"
A2[Event Bus] --> B2[Event: task.created]
B2 --> C2[Agent A 订阅]
B2 --> D2[Agent B 订阅]
C2 --> E2[Event: result.ready]
D2 --> E2
E2 --> F2[Aggregator]
end
subgraph "Actor范式"
A3[Supervisor Actor] --> B3[Agent Actor A]
A3 --> C3[Agent Actor B]
B3 -->|消息| C3
C3 -->|消息| B3
B3 --> D3[结果汇聚]
C3 --> D3
end
DAG范式的核心思想是将多Agent协作建模为有向图:节点是Agent或处理函数,边是条件路由。LangGraph是这一范式的标杆实现——它用Python函数定义节点,用条件lambda定义边,整个编排逻辑在启动前就被"编译"为一个确定的状态转移图。
图状态机的关键创新在于共享状态的不可变快照。LangGraph在每个节点执行完毕后,对全局状态对象(一个TypedDict)做一次快照,存入checkpointer(SQLite/Postgres/Redis)。任何节点失败时,系统回滚到上一个检查点重试。这保证了执行的精确一次语义(exactly-once semantics),在金融交易、医疗诊断等不能容忍重复执行的场景中至关重要。
from langgraph.graph import StateGraph, END
from typing import TypedDict, Annotated
import operator
class AgentState(TypedDict):
messages: Annotated[list, operator.add]
current_task: str
results: dict
def researcher(state: AgentState) -> dict:
"""研究Agent节点"""
query = state["current_task"]
findings = search_and_analyze(query)
return {"messages": [f"Research: {findings}"], "results": {"research": findings}}
def coder(state: AgentState) -> dict:
"""编码Agent节点"""
spec = state["results"].get("research", "")
code = generate_code(spec)
return {"messages": [f"Code: {code}"], "results": {"code": code}}
def reviewer(state: AgentState) -> dict:
"""审查Agent节点"""
code = state["results"].get("code", "")
review = review_code(code)
return {"messages": [f"Review: {review}"]}
def should_review(state: AgentState) -> str:
"""条件路由边"""
return "reviewer" if state["results"].get("code") else END
# 构建图
graph = StateGraph(AgentState)
graph.add_node("researcher", researcher)
graph.add_node("coder", coder)
graph.add_node("reviewer", reviewer)
graph.add_edge("researcher", "coder")
graph.add_conditional_edges("coder", should_review)
graph.set_entry_point("researcher")
# 编译并执行
app = graph.compile(checkpointer=SqliteSaver("agent.db"))
result = app.invoke({"current_task": "Build REST API", "messages": [], "results": {}})
DAG范式的确定性是一把双刃剑。一旦任务结构在运行时需要动态变化——例如一个Agent的输出决定是否需要新增两个之前未定义的Agent——DAG要么无法表达,要么被迫用"万能图"(所有可能路径都预先画好,用条件边选择)来模拟,导致图复杂度爆炸。实测表明,当Agent数量超过8个、条件分支超过15条时,LangGraph的可维护性急剧下降。
另一个被低估的问题是节点粒度的锁竞争。LangGraph的checkpointer在并发场景下会对状态对象加锁。当多个图实例共享同一个Postgres checkpointer时,锁等待时间可占总执行时间的12%-18%。
DAG范式最适合包装为"AI工作流自动化训练营"。企业客户对确定性有强烈需求,付费意愿高。培训内容可以覆盖LangGraph图设计、条件路由、检查点恢复,单次训练营定价2000-5000元/人,市场成熟度最高。
事件驱动范式的核心思想是Agent之间不直接调用,而是通过事件总线间接通信。一个Agent完成工作后发布事件,订阅了该事件的Agent自动被触发。这种"发布-订阅"的解耦设计带来了三个关键优势:动态拓扑(运行时可增删Agent)、天然背压(消费速度跟不上就堆积在队列中)、时间解耦(Agent不需要同时在线)。
AWS Strands SDK是2026年事件驱动Agent架构的标杆。它的multi-agent collaboration示例采用"Arbiter Pattern"——一个仲裁Agent监听事件流,根据事件内容动态分配任务给专家Agent。所有Agent通过EventBridge(或SNS/SQS)异步通信,每个Agent是一个独立的Lambda函数或容器。
import boto3
import json
from strands import Agent, tool
# 事件总线客户端
eventbridge = boto3.client('events')
@tool
def publish_event(event_type: str, payload: dict):
"""发布事件到EventBridge"""
eventbridge.put_events(
Entries=[{
'Source': 'multi-agent-system',
'DetailType': event_type,
'Detail': json.dumps(payload)
}]
)
# 仲裁Agent - 监听所有事件,决定路由
arbiter = Agent(
name="Arbiter",
system_prompt="""你是多Agent系统的仲裁者。
收到任务后分析需求,决定分配给哪个专家Agent。
通过发布事件来触发下游Agent。""",
tools=[publish_event]
)
# 专家Agent - 各自订阅特定事件
researcher = Agent(
name="Researcher",
system_prompt="你是研究专家,收到research.request事件后执行调研。",
tools=[publish_event]
)
coder = Agent(
name="Coder",
system_prompt="你是编码专家,收到code.request事件后生成代码。",
tools=[publish_event]
)
# 事件驱动流程:
# 1. 用户请求 → task.created事件
# 2. Arbiter监听 → 发布research.request
# 3. Researcher监听 → 完成 → 发布research.completed
# 4. Arbiter监听 → 发布code.request
# 5. Coder监听 → 完成 → 发布code.completed
事件驱动Agent架构在2026年引入了一个来自分布式系统的成熟模式组合:CQRS(命令查询职责分离)+ Event Sourcing(事件溯源)。
传统Agent系统将状态存储为"当前值"(例如task.status = "completed")。CQRS模式下,Agent的写操作(命令)和读操作(查询)走不同的模型。写端只追加事件(TaskCompleted),读端从事件流构建物化视图。这样做的好处是:
# Event Sourcing for Agent State
from dataclasses import dataclass
from datetime import datetime
from typing import List
@dataclass
class AgentEvent:
agent_id: str
event_type: str
payload: dict
timestamp: datetime
sequence: int
class AgentEventStore:
def __init__(self):
self.streams = {} # agent_id -> list of events
def append(self, event: AgentEvent):
if event.agent_id not in self.streams:
self.streams[event.agent_id] = []
self.streams[event.agent_id].append(event)
def get_events(self, agent_id: str, from_seq: int = 0) -> List[AgentEvent]:
return self.streams.get(agent_id, [])[from_seq:]
def rebuild_state(self, agent_id: str) -> dict:
"""从事件流重建Agent当前状态"""
state = {"tasks_completed": 0, "last_action": None}
for event in self.get_events(agent_id):
if event.event_type == "task.completed":
state["tasks_completed"] += 1
state["last_action"] = event.payload
return state
# CQRS写端
store = AgentEventStore()
store.append(AgentEvent("researcher-1", "task.started", {"task": "analyze"}, datetime.now(), 0))
store.append(AgentEvent("researcher-1", "task.completed", {"result": "done"}, datetime.now(), 1))
# CQRS读端 - 构建物化视图
state = store.rebuild_state("researcher-1")
事件驱动架构的真正杀手级优势在于背压处理。当LLM推理速度跟不上事件产生速度时(这在高并发场景下非常常见),传统DAG系统会直接失败或排队阻塞。事件驱动系统则通过队列深度自动调节:队列堆积到阈值时,自动触发水平扩容(更多Agent实例),或者通知上游Agent降低产出速率。
死信队列(DLQ)是另一个生产环境必备机制。当某个Agent处理事件连续失败3次,事件被移入DLQ,触发告警。运维可以事后检查DLQ中的事件,修复Agent逻辑后重放。这在DAG系统中需要额外开发,但在事件驱动架构中是基础设施原生支持的。
事件驱动架构适合包装为"企业级AI Agent平台建设"咨询项目,客单价5-20万。特别适合有微服务/消息队列经验的技术团队转型。2026年市场需求旺盛,但门槛较高,竞争相对较少。
Actor模型源自1973年Carl Hewitt的论文,核心思想极其简洁:一切皆为Actor,Actor之间只能通过异步消息通信,每个Actor拥有独立的私有状态。这个模型在2026年被Agent领域重新发现,因为它天然解决了多Agent系统的三个难题:并发安全(无共享状态)、位置透明(Actor可在不同机器上)、弹性扩展(动态创建/销毁Actor)。
AutoGen Core是Actor模型在Agent领域的代表实现。它用AgentRuntime管理所有Agent的生命周期,每个Agent是一个独立的Actor,拥有自己的消息邮箱(mailbox)。Agent之间通过rpc(同步等待响应)或publish(异步广播)通信。
from autogen_core import AgentRuntime, MessageContext, RoutedAgent, message_handler
from autogen_core import SingleThreadedAgentRuntime
# 定义消息类型
class TaskMessage:
def __init__(self, task: str, priority: int = 0):
self.task = task
self.priority = priority
class ResultMessage:
def __init__(self, result: str, source: str):
self.result = result
self.source = source
# 定义Agent Actor
class ResearcherAgent(RoutedAgent):
def __init__(self, name: str):
super().__init__("Research tasks")
self.name = name
self._processed = 0 # Actor私有状态
@message_handler
async def handle_task(self, message: TaskMessage, ctx: MessageContext) -> ResultMessage:
self._processed += 1 # 无需加锁,Actor串行处理邮箱消息
result = await self._do_research(message.task)
return ResultMessage(result=result, source=self.name)
async def _do_research(self, task: str) -> str:
# 实际研究逻辑
return f"Research result for: {task}"
# 构建Actor运行时
runtime = SingleThreadedAgentRuntime()
# 注册Agent Actor
researcher1 = ResearcherAgent("researcher-alpha")
researcher2 = ResearcherAgent("researcher-beta")
runtime.register_agent(researcher1)
runtime.register_agent(researcher2)
# 发送消息
await runtime.send_message(TaskMessage("Analyze market trends"), researcher1.id)
await runtime.send_message(TaskMessage("Survey competitors"), researcher2.id)
Actor模型的容错机制是Supervisor树——每个Actor有一个上级Supervisor,当下级Actor崩溃时,Supervisor决定是重启它、停止它还是将崩溃上报给自己的上级。这种"让它崩溃"(let it crash)的哲学与DAG的"检查点回滚"形成鲜明对比。
在Agent系统中,这意味着: - LLM调用超时:Supervisor重启Agent,重新处理邮箱中的消息 - Prompt注入导致Agent异常:Supervisor用隔离策略重启,不污染其他Agent - 工具调用失败:Supervisor选择重试或降级策略
实测数据表明,在100个并发Agent的场景下,Actor模型的Supervisor树可以将错误恢复时间从DAG模式的3-8秒降低到50-200毫秒。原因是Actor重启是轻量级的内存操作,而DAG回滚需要数据库事务。
Actor模型的最大问题是调试困难。异步消息流交织在一起,当系统行为不符合预期时,开发者很难追踪"哪个Agent在什么时间点做出了什么决策"。这被称为"消息地狱"(message hell),类似于回调地狱(callback hell)在Agent维度的投影。
另一个被忽视的问题是消息堆积。如果某个Agent处理速度慢(例如需要调用外部API),其邮箱中的消息会无限堆积。没有内建的背压机制(Actor模型规范本身不定义背压),需要开发者自己实现——通常是让邮箱满的Agent向发送方返回"忙碌"消息,但这就违背了Actor模型的解耦初衷。
Actor模型适合作为高吞吐场景的差异化技术壁垒,可以包装为"百万级Agent并发引擎"技术方案。但直接面向企业客户销售难度大,更适合作为SaaS产品的底层引擎。
在统一测试环境中对三种范式进行了四组基准测试:
| 指标 | DAG/图状态机 | 事件驱动 | Actor模型 |
|---|---|---|---|
| 场景A延迟 | 4.2s | 5.8s(事件开销) | 3.6s |
| 场景B吞吐 | 120 tasks/min | 340 tasks/min | 580 tasks/min |
| 场景C支持度 | 差(需重建图) | 优(动态订阅) | 良(动态创建) |
| 场景D恢复时间 | 3.2s(DB回滚) | 1.8s(事件重放) | 0.12s(Actor重启) |
| 内存占用 | 中(状态快照) | 高(事件堆积) | 低(Actor轻量) |
| 可观测性 | 优(图可视化) | 优(事件溯源) | 差(消息追踪) |
三个范式之间存在能力鸿沟,没有任何一个范式能在所有维度上胜出:
DAG的最强项是可维护性。开发者看着图就能理解整个协作流程,这在团队协作和代码审查中价值巨大。LangGraph Studio的图可视化是当前所有框架中最好的调试工具。
事件驱动的最强项是弹性。面对不可预测的负载波动(例如突发100x流量),事件驱动系统通过队列缓冲和自动扩容,可以做到"不丢一个任务"。这是生产环境的硬需求。
Actor的最强项是性能。在纯CPU/内存操作的场景下(不涉及外部IO),Actor模型的吞吐是DAG的4-5倍。这得益于零拷贝的内存消息传递和无需持久化的状态管理。
quadrantChart
title 多Agent编排范式定位矩阵
x-axis "低确定性" --> "高确定性"
y-axis "低吞吐" --> "高吞吐"
quadrant-1 "确定性+吞吐"
quadrant-2 "吞吐优先"
quadrant-3 "弹性优先"
quadrant-4 "确定性优先"
"DAG/图状态机": [0.85, 0.40]
"事件驱动/响应式": [0.35, 0.55]
"Actor模型": [0.25, 0.90]
"混合模式(趋势)": [0.60, 0.75]
生产级多Agent系统的真实需求是矛盾的:你需要DAG的确定性来通过代码审查,需要事件驱动的弹性来应对突发流量,需要Actor的性能来处理高吞吐子任务。2026年的最新趋势是混合编排引擎——在同一个系统中组合多种范式。
┌─────────────────────────────────────────────────┐
│ 编排控制层(DAG/图状态机) │
│ LangGraph定义宏观工作流,确定Agent协作的整体骨架 │
└────────────────┬────────────────────────────────┘
│ 发出事件
┌────────────────▼────────────────────────────────┐
│ 事件传输层(Event Bus) │
│ EventBridge/Kafka 解耦Agent,提供弹性和背压 │
└────────────────┬────────────────────────────────┘
│ 消息分发
┌────────────────▼────────────────────────────────┐
│ 执行运行层(Actor Pool) │
│ AutoGen Core管理Agent实例池,处理高并发任务 │
└─────────────────────────────────────────────────┘
这个三层架构的工作方式是:用LangGraph定义宏观编排图(例如"研究→编码→测试→部署"),但在每个节点内部,不是直接调用Agent,而是发布事件到事件总线。事件总线将任务分发给由AutoGen Core管理的Agent Actor池。Actor池根据负载动态伸缩。
from langgraph.graph import StateGraph, END
from strands import Agent
import json
# Strands Agent池(Actor层)
agent_pool = {
"researcher": Agent(name="Researcher", system_prompt="你是研究专家"),
"coder": Agent(name="Coder", system_prompt="你是编码专家"),
"tester": Agent(name="Tester", system_prompt="你是测试专家"),
}
# LangGraph编排层
class WorkflowState(dict):
pass
def dispatch_to_agent(state: dict, agent_role: str) -> dict:
"""将任务分发到Agent Actor池"""
agent = agent_pool[agent_role]
result = agent(state["current_task"])
state["results"][agent_role] = result
state["messages"].append(f"{agent_role}: {result}")
# 发布事件(事件层)
publish_event(f"{agent_role}.completed", {"result": result})
return state
def research_node(state):
return dispatch_to_agent(state, "researcher")
def code_node(state):
return dispatch_to_agent(state, "coder")
def test_node(state):
return dispatch_to_agent(state, "tester")
# 构建混合图
graph = StateGraph(WorkflowState)
graph.add_node("research", research_node)
graph.add_node("code", code_node)
graph.add_node("test", test_node)
graph.add_edge("research", "code")
graph.add_edge("code", "test")
graph.add_edge("test", END)
graph.set_entry_point("research")
app = graph.compile()
Google的A2A协议在2026年对编排架构产生了深远影响。A2A定义了Agent之间的标准通信格式:AgentCard(Agent名片,描述能力)、Task(任务对象,包含生命周期)、Message(消息,包含Part类型)。这意味着Agent不再需要事先知道彼此的存在——它们可以通过A2A Registry动态发现。
这对三种范式的影响是:
Task生命周期事件与事件驱动架构天然契合。每个Task状态变更(submitted→working→completed)都是一个事件。Message格式可以作为Actor邮箱中的标准消息格式,解决不同框架Actor之间的互操作问题。2026年的主流架构正在形成MCP(工具层)+ A2A(Agent层)的双层协议栈。MCP解决Agent与工具的连接(数据库、API、文件系统),A2A解决Agent与Agent的协作。两者互补不互斥:
graph LR
subgraph "Agent通信层 - A2A"
A1[Agent A] -->|A2A Task| A2[Agent B]
A2 -->|A2A Message| A3[Agent C]
end
subgraph "工具调用层 - MCP"
A1 -->|MCP Tool Call| M1[(数据库)]
A2 -->|MCP Tool Call| M2[(API)]
A3 -->|MCP Tool Call| M3[(文件系统)]
end
graph TD
START[多Agent系统选型] --> Q1{Agent协作流程是否确定?}
Q1 -->|是,流程固定| Q2{是否需要审计追踪?}
Q1 -->|否,动态变化| Q3{并发量级?}
Q2 -->|是| DAG[DAG/图状态机<br/>LangGraph]
Q2 -->|否| Q4{是否需要高性能?}
Q4 -->|是| ACTOR[Actor模型<br/>AutoGen Core]
Q4 -->|否| DAG
Q3 -->|<100 Agent| EVENT[事件驱动<br/>AWS Strands]
Q3 -->|≥100 Agent| HYBRID[混合模式<br/>DAG + Event + Actor]
Q3 --> Q5{是否跨组织协作?}
Q5 -->|是| A2A[A2A协议层<br/>Google ADK]
Q5 -->|否| EVENT
DAG --> FINAL[✅ 选定]
EVENT --> FINAL
ACTOR --> FINAL
HYBRID --> FINAL
A2A --> FINAL
| 你的场景 | 推荐范式 | 推荐框架 | 关键理由 |
|---|---|---|---|
| 企业审批流/合规检查 | DAG | LangGraph | 确定性 + 可审计 |
| 客服/实时协作 | 事件驱动 | AWS Strands | 弹性 + 低延迟 |
| 高频交易/实时分析 | Actor | AutoGen Core | 吞吐 + 恢复速度 |
| 企业级全流程 | 混合 | LangGraph+Strands | 兼顾确定性和弹性 |
| 跨组织Agent协作 | A2A | Google ADK | 标准化互操作 |
编排引擎正从"框架"演变为"基础设施"。2026年下半年的关键趋势是编排引擎将内建在云平台中——AWS Step Functions已经原生支持Agent节点,Azure Durable Functions正在集成Semantic Kernel的Agent能力,Google Cloud Workflows已经兼容A2A协议。这意味着开发者不再需要选择LangGraph还是AutoGen,而是直接在云平台的编排服务中定义Agent工作流。
Google于2026年初发布的ADK双向流式通信能力正在改变Agent协作的延迟模型。传统的请求-响应模式下,Agent A等待Agent B完成全部推理后才能继续。双向流式模式下,Agent B的推理结果以token流的形式实时推送给Agent A,Agent A可以在Agent B还在推理时就开始处理部分结果。这在"研究Agent实时向编码Agent传递发现"的场景下,端到端延迟可降低40%-60%。
受Terraform/Pulumi启发,2026年出现了"Agent编排即代码"的趋势——用声明式配置(YAML/JSON)定义多Agent协作拓扑,而非在Python代码中硬编码。这与A2A协议的AgentCard天然契合:开发者声明"我需要哪些能力的Agent,它们如何协作",运行时自动从Registry发现并绑定具体Agent。
[!tip] 51学通信知识星球 星主:爱卫生(微信:gprshome201101)——公众号「51学通信」创办者,19 年通信行业运维与讲师经验,著有《GPRS网络信令实例详解》《EPC原理与实践》《5G核心网原理与实践》三本纸质书(各大电商平台有售)。 星球定位:深耕 5G 核心网、IMS、NFV/AI、云原生等 ICT 领域,主打运维岗位与信令分析。 当前规模:5200 篇主题 / 990 个回答,198 元/年。 加入福利:加入星球后请加爱卫生微信,拉您进知识星球年度陪伴与答疑群——不限量回复您的各种问题,另有群内分享。 AI 加持:51学通信知识星球已作为 skill 接入 WorkBuddy,使用 deepseek-4-flash 在海量星球帖子中精准找贴、找视频、找 FAQ 和案例,做总结、找文档和 PPT 等场景全覆盖。
