Actor 模型:异步消息与类型化运行时


文档摘要

Actor 模型:异步消息与类型化运行时 本节摘要:大多数 Agent 框架是同步的——一个 Agent 产出、一个 Agent 消费,挤在一个调用栈里,失败会崩栈,并发是后 bolt 上去的,要做分布式得重写。AutoGen v0.4(Microsoft Research, 2025 年 1 月)的回答是把 Agent 当 Actor:每个 Agent 是一个带私有收件箱的 Actor,消息是它们之间唯一的交互方式,运行时把投递与处理解耦,失败隔离在单个 Actor 内,并发是原生的,分布式只是换一种传输。本节吃透 Actor 模型(私有状态 + 收件箱 + 处理器,两个 Actor 不能共享内存)、AutoGen v0.

Actor 模型:异步消息与类型化运行时

本节摘要:大多数 Agent 框架是同步的——一个 Agent 产出、一个 Agent 消费,挤在一个调用栈里,失败会崩栈,并发是后 bolt 上去的,要做分布式得重写。AutoGen v0.4(Microsoft Research, 2025 年 1 月)的回答是把 Agent 当 Actor:每个 Agent 是一个带私有收件箱的 Actor,消息是它们之间唯一的交互方式,运行时把投递与处理解耦,失败隔离在单个 Actor 内,并发是原生的,分布式只是换一种传输。本节吃透 Actor 模型(私有状态 + 收件箱 + 处理器,两个 Actor 不能共享内存)、AutoGen v0.4 的三层 API(Core 底层 Actor 框架、AgentChat 任务驱动高层、Extensions 集成)、解耦带来的三大后果(故障隔离、天然并发、可分布),以及 RoundRobin / Selector / Magentic-One 三种拓扑。注意:AutoGen 已转入维护模式,Microsoft Agent Framework(2025 年 10 月公开预览)是其生产继任者,但 Actor 模型是经久不衰的思想。本节用标准库从零实现一个 Actor 运行时,并把一个双 Agent 代码评审流程搬上去。

对应原课程:Phase 14 · Lesson 14 · autogen-actor-model(原英文 phases/14-agent-engineering/14-autogen-actor-model/docs/en.md)。

学习目标

阅读完本节,你应当能够:

  1. 描述 Actor 模型:Agent 即 Actor、消息是唯一的进程间通信(IPC)、每个 Actor 故障隔离。
  2. 说出 AutoGen v0.4 的三层 API:Core、AgentChat、Extensions,以及各自的用途。
  3. 解释为什么把消息投递与处理解耦能带来故障隔离与天然并发。
  4. 用标准库实现一个 Actor 运行时,并把一个双 Agent 代码评审流程搬上去。
  5. 识别 Actor 模型相对状态图(第 13 节)的取舍:何时选哪个。

一、问题与直觉

同步框架的痛

大多数 Agent 框架是同步的:一个 Agent 产出、一个 Agent 消费,挤在一个调用栈里。失败会崩栈。并发是后 bolt 上去的。分布式需要重写。

AutoGen v0.4 的回答:Actor 模型。每个 Agent 是一个带私有收件箱的 Actor。消息是唯一的交互。运行时把投递与处理解耦。失败隔离到一个 Actor。并发是原生的。分布式只是换一种传输。

Actor 是什么

一个 Actor 有:

  • 私有状态(从不被外部直接碰)。
  • 收件箱(消息队列)。
  • 处理器:receive(message) -> effects,其中 effects 可以是「回复」「发给别的 Actor」「spawn 新 Actor」「更新状态」「停止自己」。

两个 Actor 不能共享内存,只能互发消息。

三层 API

AutoGen v0.4 把表面分成三层:

  1. Core —— 底层 Actor 框架。AgentRuntimeAgentMessageTopic。异步消息交换,事件驱动。
  2. AgentChat —— 任务驱动的高层 API(替代 v0.2 的 ConversableAgent)。AssistantAgentUserProxyAgentRoundRobinGroupChatSelectorGroupChat
  3. Extensions —— 集成:OpenAI、Anthropic、Azure、工具、记忆。

解耦为什么重要

在 v0.2 模型里,调用 agent_a.chat(agent_b) 会同步阻塞 agent_a 直到 agent_b 返回。在 v0.4 里,send(agent_b, msg) 把消息放进 agent_b 的收件箱就返回,运行时之后投递。三个后果:

  • 故障隔离 —— Agent B 崩溃不会崩 Agent A——运行时在 B 的处理器里抓住失败,决定怎么办(记日志、重试、死信队列)。
  • 天然并发 —— 同时有许多消息在飞;各 Actor 并发处理自己的收件箱。
  • 可分布 —— 收件箱 + 传输是同一个抽象,无论 Actor 在进程内还是在另一台主机上。

💡 设计要点:Actor 模型的核心心法是「不共享内存,只发消息」。这条约束初看是限制,实则是解放——它强制你把所有交互显式化成消息,于是故障边界、并发模型、分布抽象自然就位。这与第 13 节状态图的「显式状态」是两种不同的显式化路径:状态图显式化控制流,Actor 显式化通信

拓扑

  • RoundRobinGroupChat —— Agent 按固定轮次轮流。
  • SelectorGroupChat —— 一个选择器 Agent 根据对话上下文挑谁下一个。
  • Magentic-One —— 用于网页浏览、代码执行、文件处理的参考多 Agent 团队,建在 AgentChat 上。

可观测性

内置 OpenTelemetry 支持。每条消息发一个 span;工具调用带 gen_ai.* 属性,遵循 2026 年 OTel GenAI 语义约定(第 23 节)。

状态:维护模式

2026 年初:AutoGen v0.7.x 对研究与原型稳定。Microsoft 已把活跃开发转向 Microsoft Agent Framework——生产继任者(2025 年 10 月 1 日公开预览;1.0 GA 目标是 2026 年 Q1 末)。AutoGen 的模式能干净地前向移植——Actor 模型是经久不衰的思想

二、从零实现

原课程 code/main.py 用标准库实现一个 Actor 运行时:

  • Message —— 类型化载荷,带 senderrecipienttopicbody
  • Actor —— 抽象类,带 receive(message, runtime)
  • Runtime —— 带共享队列、投递、故障隔离的事件循环。
  • 双 Actor 演示:ReviewerAgent 评审代码,ChecklistAgent 跑清单;它们交换消息直到达成共识。

核心骨架如下,用伪代码展示。

Step 1:消息 + Actor

class Message: def __init__(self, sender, recipient, topic, body): self.sender = sender self.recipient = recipient self.topic = topic self.body = body class Actor: def __init__(self, aid): self.id = aid self.state = {} # 私有,外部不碰 def receive(self, msg, runtime): raise NotImplementedError

Step 2:运行时(事件循环 + 故障隔离)

class Runtime: def __init__(self): self.actors = {} # id -> Actor self.queue = [] # 待投递消息 def register(self, actor): self.actors[actor.id] = actor def send(self, msg): self.queue.append(msg) # 投递与处理解耦:放进队列就返回 def run(self): while self.queue: msg = self.queue.pop(0) actor = self.actors[msg.recipient] try: actor.receive(msg, self) # 处理 except Exception as e: # 故障隔离:一个 Actor 崩不崩别的 self.dead_letter(msg, e)

Step 3:双 Agent 代码评审

class ReviewerAgent(Actor): def receive(self, msg, runtime): if msg.topic == "code": verdict = llm_review(msg.body) self.state["last_verdict"] = verdict runtime.send(Message(self.id, "checklist", "review", verdict)) class ChecklistAgent(Actor): def receive(self, msg, runtime): if msg.topic == "review": checks = run_checklist(msg.body) if all(checks.values()): runtime.send(Message(self.id, "reviewer", "consensus", "通过")) else: runtime.send(Message(self.id, "reviewer", "review", "需修订"))

运行 python3 code/main.py 会展示消息投递、一个 Actor 内的模拟失败(不崩另一个)、以及对共享裁决的收敛。

💡 设计要点:Runtime.run() 里的 try/except 是 Actor 模型的故障隔离落点。同步框架里一个 Agent 抛异常会沿调用栈向上传播、崩掉整条链;Actor 框架里异常被运行时抓住、塞进死信队列,其他 Actor 继续干活。这就是 Erlang「let it crash」哲学在 Agent 层的重演。

三、框架对比

  • AutoGen v0.4/v0.7(维护)—— 对研究、原型、多 Agent 模式稳定。
  • Microsoft Agent Framework —— 生产继任者(2025 年 10 月公开预览);同样的 Actor 模型思想,API 焕新。
  • LangGraph 群体拓扑(第 13 节)—— 通过共享工具交接实现类似模式。
  • 自建 Actor 运行时 —— 需要特定传输(NATS、RabbitMQ、gRPC)时。
选项 模型 并发 分布 适用
AutoGen / MAF Actor 原生 收件箱+传输 高并发多 Agent
LangGraph 状态机 需配 检查点+恢复 持久状态图
LangGraph Swarm 共享工具交接 对等协作
自建 全控 全控 全控 特定传输

⚠️ 选型警示:Actor 模型适合高并发、多 Agent、需故障隔离的场景。如果你的任务是线性工作流或需精确状态恢复,第 13 节的状态图更合身。不要因为「Actor 听起来酷」就上——它的代价是调试更难(消息时序、收件箱堆积、死信排查)。

四、可复用产物

本节产出一份可复用技能(原课程 outputs/skill-actor-runtime.md):

  • skill-actor-runtime.md:生成一个最小 Actor 运行时 + 一个团队模板(RoundRobin 或 Selector),适用于给定的多 Agent 任务。包含一份 Actor 设计清单(每个 Actor 的状态边界在哪?消息载荷是否类型化?故障如何进死信?),以及一份拓扑选择清单(轮次固定用 RoundRobin,上下文敏感用 Selector,需网页/代码/文件用 Magentic-One 式分工)。

Python 代码(code/main.py)是独立可运行的 Actor 运行时骨架,消息、Actor、运行时、故障隔离都是传输无关的;把进程内队列换成 NATS/RabbitMQ/gRPC 即可分布式部署。

五、练习

  1. (Easy) 加一个死信队列:处理器抛异常时,把失败消息停泊待人工检查。你的玩具里 DLQ 多久被命中一次?
  2. (Medium) 实现 SelectorGroupChat:一个选择器 Actor 根据对话状态挑谁处理下一条消息。
  3. (Medium)分布式传输:把进程内队列换成 JSON-over-HTTP 服务器,让 Actor 能跑在不同进程里。
  4. (Hard) 给每条消息接一个 OTel span(或空操作替身)。按第 23 节发 gen_ai.agent.namegen_ai.operation.name
  5. (Hard) 读 AutoGen v0.4 架构帖。把你的玩具移植到真实 autogen_core API。你跳过的哪些东西在生产里要紧?

本节要点回顾

  1. Actor 模型三件套:私有状态 + 收件箱 + 处理器,两个 Actor 不共享内存只发消息。
  2. 解耦投递与处理:send 进队列就返回,运行时之后投递。
  3. 三大后果:故障隔离(let it crash)、天然并发、可分布(收件箱+传输同一抽象)。
  4. AutoGen 三层 API:Core(Actor 框架)、AgentChat(任务驱动高层)、Extensions(集成)。
  5. 三种拓扑:RoundRobin(固定轮次)、Selector(上下文选)、Magentic-One(网页/代码/文件分工)。
  6. 内置 OTel:每条消息一个 span,工具调用带 gen_ai.* 属性。
  7. 维护模式:AutoGen 转维护,Microsoft Agent Framework 是生产继任,Actor 模型经久不衰。
  8. 故障隔离落点:运行时的 try/except 抓异常进死信,其他 Actor 继续。
  9. 状态图 vs Actor:状态图显式化控制流,Actor 显式化通信;按场景选。
  10. 不要因为酷就上:Actor 代价是调试更难(消息时序、收件箱堆积、死信排查)。

下一节,我们看角色制团队——CrewAI 把多 Agent 协作组织成有角色、有目标、有背景故事的人类团队形态,当你的任务天然是「不同专长的角色协作」时,它比裸 Actor 更贴近直觉。


发布者: 作者: Rohit Gupta 转发
评论区 (0)
U