Chapter 02

运行原理与设计取舍:两套编排底下的运行时

上一章把 MAF 拆成部件,并立了两个门槛:Agent 无状态、编排分两套(图 1.3)。 这一章下探到 API 的下一层——AgentChat 模式 与 Workflow 图引擎底下的运行时究竟怎么转,每个设计为什么这么选,以及该用哪一套。最后用一个真实场景把所有机制串起来,并给出截至 2026-06 的前沿地图。

本章你将建立的 schema

  • actor 消息运行时:agent 是异步 actor,靠 request/response 与 publish/subscribe 两种方式通信;单机与分布式共用一套 API。
  • Workflow 图引擎:Executor + Edge 组成有向图,按 Pregel 超步推进,在屏障处落检查点——这是确定性与可恢复的来源。
  • 两套并存的判别标准、Magentic 的动态规划机制,以及 MAF 与 LangGraph/CrewAI/OpenAI Agents SDK 的取舍。

2.1actor 消息运行时:autogen-core 的血统

图 1.3 结尾留了个钩子:AgentChat 模式 和 Workflow 图引擎"都运行在同一个 actor 运行时上"。这个运行时来自 AutoGen v0.4 的 autogen-core,是 MAF 从 AutoGen 继承的核心资产。

运行方式:在这一层,每个 agent 是一个异步 actor——有自己的身份、自己的信箱,只通过消息与外界往来,不直接相互调用方法。运行时负责投递消息、管理 actor 的身份与生命周期、划定安全边界。两种通信方式:

  • request / response:直接寻址——给某个具体 actor 发一条消息、等它回。点对点。
  • publish / subscribe:主题广播——往一个 topic 发布消息,所有订阅该 topic 的 actor 都收到。一对多、解耦。

actor 的身份是一个 (type, key) 对:type 是 agent 的类别,key 区分同类的不同实例。运行时用它路由消息。

① req/resp:直接寻址 Agent A (type, key) Agent B (type, key) Agent Runtime 投递 · 身份 · 生命周期 request response Topic 发布 / 订阅主题 Agent C 订阅者 publish 广播投递给订阅者 ② pub/sub:主题广播
图 2.1同一个运行时上的两种消息方式:实线是点对点 request/response,虚线是经 topic 的一对多 pub/sub。 注意:agent 之间从不直接调用彼此,一切经运行时投递——正因如此,把 SingleThreadedAgentRuntime(单进程)换成分布式运行时(host servicer 跨进程转发)时,agent 代码一行不用改。

底层机制(比文档深一层):"换运行时不改代码"不是营销话术,是 actor 模型的直接推论。因为 agent 只面对"发消息 / 收消息"这个接口,消息怎么送达(同进程内存队列,还是跨网络经 host servicer 转发)被运行时藏起来了。SingleThreadedAgentRuntime 在一个进程里串行投递;分布式运行时让一个 host 在多语言 worker 之间中转消息。两者 API 一致,所以同一段编排既能本机跑,也能扩到一群进程上。

表 2.1 · 为什么用 actor 消息,而不是直接方法调用
方案优势为什么没选 / 代价
直接方法调用(调用栈)简单、可单步调试、同步直观耦合死在同进程;扩不到分布式;一个 agent 阻塞拖垮整条链
共享内存 + 锁快并发复杂、易死锁;同样扩不出进程
actor 异步消息解耦、可分布式、开放式编排、单机/分布式同 API代价:调用链更难追(要靠 OpenTelemetry)、异步心智负担、消息顺序需自己设计
想一想

一个多 agent 系统在本机 SingleThreadedAgentRuntime 上跑通了。要扩成跨多进程的分布式部署,agent 的业务代码需要大改吗?为什么?

展开答案(先停 10 秒)

基本不用改业务代码。agent 只依赖"发消息 / 收消息"的运行时接口,消息怎么投递是运行时的事。换成分布式运行时,投递从进程内队列变成跨进程中转,但 agent 看到的接口不变。这正是 actor 模型把"通信机制"和"业务逻辑"解耦带来的红利——代价记在表 2.1 右列(更难追踪、异步负担)。

2.2Workflow 图引擎:Pregel 超步与检查点

actor 运行时是开放、松耦合的——适合"让 agent 自由对话"。但生产流程常常要反过来的东西:确定的执行顺序、可审计、能从中断处恢复。Workflow 图引擎就是为此叠在 actor 运行时之上的第二层。

运行方式:用 WorkflowBuilder 把 Executor(工作单元,可包一个 agent 或一段逻辑)用 Edge(带类型、带条件)连成有向图。执行不是简单地"沿边走",而是按 Pregel 超步(superstep)推进——这套模型和 LangGraph 同源,熟悉 BSP(bulk-synchronous parallel)的会很快认出来:

  • 一个超步内,所有"被激活"的 executor 并行处理各自收到的消息;
  • 超步结束有一道同步屏障(barrier)——所有 executor 都跑完,才统一进入下一超步;
  • 屏障处是检查点(checkpoint)边界:此刻图的状态可被完整存档,于是流程能从这里恢复。
超步 N Executor A Executor B 同超步内并行 屏障 存档 检查点 超步 N+1 Executor C 存档 超步 N+2 Executor D · 输出
图 2.2图引擎按超步推进,不是按"调用栈"跳转。 注意:红色的检查点只落在屏障处——这是"能从中断恢复"的物理位置。崩溃后重启,从最近一个检查点的超步继续,而不是从头重跑。这也解释了为什么图引擎比 actor 自由对话"重":每个屏障都要等齐 + 存档。

底层机制(比文档深一层):除了走 edge 传消息,executor 之间还能共享一块带作用域的状态(shared state)——大块数据不必塞进消息里逐跳传递,放进共享状态让需要的 executor 直接读写。还有HITL(human-in-the-loop):图可以在某个节点暂停,把一个"请求"抛给人,等人回了再从检查点继续——本质就是用检查点机制把"等人"变成一次可恢复的中断。

表 2.2 · 图引擎 vs 纯对话式编排
方案优势为什么没选它做生产流程 / 代价
纯对话式(agent 自由轮流发言)灵活、低仪式感、贴近"让模型自己想"非确定、难审计、崩了从头来、类型不校验
Pregel 超步图(Workflow)确定、可审计、屏障处可检查点恢复、边带类型校验代价:要预先画图、屏障引入等待、结构比对话重
陷阱

同一个 workflow 实例跨多次运行会带着上次的状态,导致任务之间状态串味。修复:每个请求新建一个 workflow 实例,别复用。另外在 .NET 上,RunStreamingAsync 在出错 / 取消时会丢掉 thread 状态——流被打断,这一程对话历史就没了。两者根因相同:状态的生命周期边界没划清。

2.3为什么是两套:怎么选 AgentChat 还是 Workflow

§2.1 和 §2.2 揭示了真正的张力:同一个框架里有两套执行模型——松耦合的 actor 自由对话(AgentChat 模式直接架在上面),和确定性的超步图(Workflow)。这是收敛的产物:AutoGen 带来前者的基因,生产需求催生后者。冗余是真实的——Handoff / GroupChat / Magentic 这些名字在两套框架下都出现过。

选择标准可以压成一个判断:你需要"可恢复 / 可审计 / 类型校验"吗?

多 agent 任务 要可恢复 / 审计 / 类型? 是 Workflow 图引擎 否 要动态规划? 是 Magentic / GroupChat 否 Sequential / Concurrent
图 2.3选型决策树。 注意:第一个菱形就把"生产可恢复流程"分流到 Workflow——它是分界线。落到 AgentChat 那一侧后,再按"要不要让 LLM 动态规划"区分 Magentic/GroupChat 与朴素的 Sequential/Concurrent。

带来的代价:两套并存意味着更高的学习成本——要同时理解 AutoGen 的对话/actor 心智和 Workflow 的图/超步心智,还要在两边重名的模式间分清当前用的是哪套。这是 MAF 学习曲线被诟病"陡"的主要来源。

2.4无状态 Agent + Thread:为什么这么设计

01 章讲了 thread 的两种持久化(表 1.1)。这里补上设计取舍:为什么 MAF 要把状态从 agent 里拆出去,而 AutoGen v0.2/v0.4 当初把它留在 agent 里。

运行方式回顾 + 深一层:无状态 agent 把"逻辑"和"会话数据"分开。逻辑(指令、工具)在 agent 上,可被任意会话复用;数据(消息历史)在 thread 上,一会话一份。于是同一个 agent 实例能并发服务海量会话,且因为 thread 可序列化、可换后端,会话能跨进程恢复、能交给服务端托管。

表 2.3 · 有状态 agent vs 无状态 agent + 显式 thread
方案优势为什么没选 / 代价
有状态 agent(AutoGen v0.2/v0.4)"对象记住对话"符合直觉、单机简单状态和逻辑耦合;水平扩展难;服务端托管对话别扭;并发会话要复制 agent
无状态 agent + 显式 thread(MAF)水平扩展、跨进程恢复、服务端托管、一实例服务多会话代价:thread 必须显式创建并传递,忘了传就"失忆";心智上要反直觉
洞察 · 三个门槛串起来了

无状态 agent(§2.4)+ actor 运行时(§2.1)是一对:正因为 agent 无状态、靠消息通信,运行时才能把它随意调度到任意进程。再叠上 Workflow 的检查点(§2.2),就凑齐了"分布式 + 可恢复"的生产能力。三块拼图本是一张图——这就是 01 章"一句话本质"在机制层的兑现。

2.5Magentic 深挖:让一个 LLM 当编排者

前面的编排模式(Sequential/Concurrent/Handoff)结构是人预先定死的。Magentic(源自微软的 Magentic-One 研究)反过来:让一个 LLM Manager 在运行时动态规划——这正是 actor 运行时"开放式编排"能力的招牌用法。

运行方式:Manager 维护两本"账本":

  • Task Ledger(任务账本):已知事实 + 当前计划。开局由 Manager 根据任务写出。
  • Progress Ledger(进度账本):逐步跟踪每个子任务谁在做、做到哪、有没有进展。

循环是:Manager 看进度账本 → 把下一个子任务派给合适的专家 agent → 专家执行、回报 → Manager 更新进度。关键机制是一个停滞计数器(stall counter):如果连续若干步没有实质进展,Manager 判定"卡住了",重写 Task Ledger 的计划(replan),换个打法。

Magentic Manager Task Ledger · 计划 Progress Ledger · 进度 专家 Agent A 执行子任务 专家 Agent B 执行子任务 ① 派活 ② 回报 停滞超阈值 → 重写计划 replan
图 2.4Magentic 的"经理-专家"环。 注意:红色那条自环是 Magentic 区别于固定流程的关键——停滞计数器触发重规划,让编排能在跑不动时自己换计划,而不是傻跑到底。代价:Manager 每步都要调一次 LLM 做判断,贵。
陷阱

动态编排最现实的风险是循环失控——agent 之间来回踢皮球,把预算烧光。停滞计数器是一道防线,但别只靠它。开发期用 DevUI(preview)观察编排回合,能在烧钱前看见死循环;生产里给回合数 / token 设硬上限。

2.6横向对比:MAF 该不该是你的选择

把 MAF 放进 2026 年的 agent 框架版图里看。它的真正独特点常被误判成"深度 Azure 集成",其实更硬的差异在别处。

表 2.4 · MAF 与主流 agent 框架
框架强项什么时候选它(以及不选)
MAFPython↔.NET 同一 workflow 跨语言;actor 运行时 + 超步图两套;深 Azure/Foundry;MCP GA;企业级可观测选:.NET 或 Azure 重度团队、要分布式开放编排、要生产级可恢复流程。不选:跨云 / 非 Azure、要最成熟生态、嫌学习曲线陡
LangGraph图编排成熟、社区大、云中立、已被大厂规模化用现在就要成熟度、复杂有环状态机、不想绑某朵云
CrewAIrole-based、最快出 demo(几小时)快速做角色协作原型、不想绑 Azure
OpenAI Agents SDK轻量、OpenAI 原生、handoff/guardrail、语音OpenAI 生态、轻量 handoff 流水线、做 pilot
AutoGen v0.4研究 / 前沿多智能体模式做实验、追前沿(已非生产路径,维护模式)
洞察 · 真正的护城河

MAF 最难被别家复制的,不是 Azure 集成,而是 Python 与 .NET 的 agent 能进同一个 workflow 互操作——这来自底层那套语言无关的 actor 运行时。LangGraph/CrewAI 是 Python 世界的;OpenAI Agents SDK 是轻量的。对一个同时有 Python 数据团队和 .NET 业务团队的企业,这条独此一家。

诚实的弱点:生态最年轻(2026-04 才 GA,远落后于 LangChain 的体量与心智份额)、Azure 绑定带来 TCO 与可移植性顾虑、学习曲线陡(要同时懂 AutoGen + SK 两套概念)、A2A/协议互操作仍脆。迁移也是一个真实工程,不是改个配置——下一节展开。

2.7前沿地图:截至 2026-06 什么稳、什么在动

MAF 太新,把"什么能压上生产、什么还在变"分清,本身就是这门技术的一部分。下表按"稳定 / 在变 / 已被取代"三栏,带日期。

表 2.5 · MAF 现状三栏(截至 2026-06)
状态内容日期 / 版本
稳定(可压生产)核心 SDK:单 agent、连接器(OpenAI/Azure/Anthropic/Bedrock/Gemini/Ollama)、middleware、记忆/上下文、Workflow 图引擎、编排模式、声明式 YAML、MCP1.0 GA 2026-04;今为 Python 1.7 / .NET 1.8
在变(别压生产)A2A 绑定仍 preview("即将 1.0");DevUI 调试器、Foundry 托管 agent V2、Skills、AG-UI/CopilotKit 适配器、Agent Harness;Build 2026 把方向延伸到 OS 层(Windows Agent Runtime、NPU 本地 agent)preview;Build 2026 = 2026-05
已被取代AutoGen(v0.2 + v0.4)与独立 Semantic Kernel → 维护模式(只修 bug/安全、无新功能、无硬性下线日期);Java 被砍;迁移自愿("lazy migration")维护模式自 2025-10

两个运行时版本号不同步:Python 与 .NET 独立发版,.NET 略领先(今为 1.8 vs 1.7),别假设跨语言版本一一对应。GA 过程很干净——2026-02 出 RC,六周后 GA,RC→1.0 没有破坏性改动;真正会咬人的是RC 期的博客代码,里面常用已删除的 AgentGroupChat 等类,照抄会编译不过。

从 AutoGen v0.4 迁移:关键改名

迁移是一个真实工程,但官方有指南。最常撞到的改动:

表 2.6 · AutoGen v0.4 → MAF 关键对照
AutoGen v0.4MAF注意
AssistantAgentChatAgent语义变了:MAF 默认多轮工具循环、且无状态
FunctionTool / @function_tool@ai_function从签名自动生成 schema
model_clientchat_client参数改名
OpenAIChatCompletionClientOpenAIChatClientimport 路径改到 agent_framework.openai
RoundRobinGroupChat / MagenticOneGroupChat无直接替代要按 Workflow / 新编排重建
洞察 · 迁移不被强制

AutoGen/SK 进维护模式但没有硬性下线日期,迁移是"按需迁移"(lazy migration):现有负载不会被破坏性变更逼着改,等你要新功能时再迁。所以"是否现在迁"本身是个决策——03 章的判别题会专门练它。

2.8跨概念综合:一个跨天可恢复的审批流

把本章机制拧成一股绳。场景:一个采购审批流程,要跨多天、可中断恢复,其中"风控评估"一步需要多个 agent 协商,且最终要人工签字。逐个机制对位:

  • 整体用 Workflow 图引擎(§2.2),不是自由对话——因为要跨天、可中断恢复。屏障处的检查点(图 2.2)正是"今天没批完,明天从这步继续"的物理位置。
  • "风控评估"子步内部用 Magentic 或 GroupChat(§2.5)——这一步需要多 agent 动态协商,结构没法预先定死,交给 LLM Manager 规划。它作为一个 Executor 嵌进图里。
  • 人工签字用 HITL(§2.2)——图在签字节点暂停、抛请求给人,人回了从检查点续跑。
  • 会话状态用 server-managed thread(§2.4 / 表 1.1)——跨天跨进程,历史不能放进程内存,交给服务端托管,本地只留 ConversationId。
  • 底层仍是 actor 运行时(§2.1)——图里的 executor、Magentic 里的 agent,最终都是运行时上的 actor;要扩成分布式,业务代码不动。

这一个场景同时落到本章五个机制上——能把它讲顺,本章就过关了。

§本章 self-check

先合上教程作答,再展开对照。

  1. actor 运行时的两种通信方式是什么?各自的寻址特征(点对点 / 一对多)是?
  2. "换运行时不改代码"成立的根本原因是什么?把它落到 actor 模型的一条性质上。
  3. Workflow 的检查点为什么只落在屏障处?这和"可恢复"是什么关系?
  4. "无状态 agent + actor 运行时"为什么是天生一对?(综合 §2.1 与 §2.4。)
  5. Magentic 的停滞计数器解决了动态编排的什么风险?
  6. (综合题)§2.8 的审批流里,为什么"风控评估"用 Magentic 而整体用 Workflow,而不是反过来?
答案(先做完再展开)
  1. request/response(直接寻址、点对点)与 publish/subscribe(主题广播、一对多、解耦)。
  2. 因为 agent 只依赖"发消息/收消息"接口,消息怎么投递被运行时封装。actor 模型把"通信机制"与"业务逻辑"解耦,所以同/分布式可换。
  3. 屏障是"所有 executor 跑齐、统一推进"的同步点,此刻图状态一致、可完整存档。崩溃后从最近检查点的超步续跑,不必从头——可恢复就建立在这个一致快照上。
  4. 无状态 agent 不持有数据、只靠消息通信,运行时才能把它随意调度到任意进程、任意并发复用;有状态 agent 绑死在持有状态的那个实例上,扩不动。
  5. 循环失控 / 来回踢皮球烧光预算的风险:连续无进展就触发重规划,而不是傻跑到底(但仍需回合/token 硬上限兜底)。
  6. 整体要跨天、可中断恢复 + 人工签字 → 需要确定性、检查点、HITL,这是 Workflow 的强项;而"风控评估"内部是开放式多 agent 协商、结构无法预先定死 → 适合 Magentic 的动态规划。两者各取所长,嵌套使用。
进阶挑战 · 刚好够不着

把"冗余"想透

§2.3 说 Handoff / GroupChat / Magentic 在 AgentChat 模式和 Workflow 图引擎下都出现,是收敛带来的冗余。问题:如果一个"多 agent 协商"既能用 AgentChat 的 GroupChat、也能在 Workflow 里塞一个 GroupChat-Executor,二者跑出来的行为有什么实质差别?

提示(卡住再展开)

差别不在"协商本身",而在外层壳给了什么。裸 GroupChat(AgentChat)没有屏障检查点,崩了从头来、过程难审计;塞进 Workflow 当一个 Executor,它就继承了图引擎的检查点、类型边、可恢复——协商成了一个"可断点续跑、可审计"的步骤。同样的内核,确定性与可恢复性由外层决定。回到图 2.3 的第一个菱形:要不要可恢复/审计,就是分界线。