多智能体系统实战:基于微软Agent Framework的架构与落地
2026/9/8 19:07:25 网站建设 项目流程

2025年如果让我只挑一个方向持续加码,那一定是多智能体系统。最近微软把 Agent Framework 的设计细节逐步公开之后,很多朋友跑来问我:这和 Semantic Kernel 到底什么关系?多智能体是不是就是把好几个大模型接在一起各干各的?说实话,等我把一个真实项目从单 Agent 改造成多 Agent 之后,最大的感触是——多智能体系统设计,真正难的从来不是调用几个模型,而是协作拓扑、状态传递和失败兜底。这篇文章我就围绕微软这套多智能体设计思路,把我自己的理解、搭建过程、踩过的坑,以及一个浏览器自动化场景里的落地方案完整拆开讲。

无论你是刚接触 Agent 开发的初学者,还是已经在用 LangChain、AutoGen 做原型的老手,这篇文章都适合你。我会先讲清楚微软多智能体框架的设计哲学,再给出一套可落地的实现路径,最后用一个真实的自动化任务场景,把从任务拆解到稳定性设计的完整链路串起来。

1. 微软为什么要做多智能体框架:先看清协作模式的地图

很多人一听到"多智能体系统"就默认它一定比单 Agent 高级,这其实是个误区。微软在 Agent Framework 的设计文档里反复强调一个观点:Agent 是 Workflow 的超集,而不是替代品。这句话是所有后续设计决策的起点。

1.1 多智能体系统真正要解决的三类问题

我自己的体会是,多智能体架构不是用来炫技的,它只适合解决三类问题。

第一类是任务复杂度过高。单个 Agent 如果既要理解用户意图、又要检索知识库、还要调用业务系统、最后还要生成结构化报表,你很快就会把提示词写成一个几千字的巨无霸。Prompt 越长,模型的注意力越分散,出错率越高。把不同职责拆成不同 Agent,每个 Agent 只维护自己领域的 Prompt 和工具,复杂度就从"一个巨型系统"变成了"几个小系统加上一套路由逻辑"。

第二类是上下文窗口的限制。即使现在模型上下文已经到了百万 token 级别,在实际业务中你也不可能把所有内容都塞进去。多 Agent 的天然优势是每个 Agent 只接收与自己相关的上下文,比如搜索 Agent 只接收搜索指令和结果摘要,审核 Agent 只接收格式化之后的结论。这让 token 使用效率高了一个量级。

第三类是工具域与权限的隔离。一个系统里经常同时存在内部 API、外部服务、数据库、文件系统这些不同敏感级别的资源。单 Agent 模式下,一个越权工具调用可能把整个链路带崩。多 Agent 模式下,每个 Agent 的工具箱是独立配置的,权限边界清晰,审计也容易做——出了问题能精确到是哪个 Agent 在哪一步调的哪个工具。

1.2 Workflow、Agent 与 Graph:MAF 的设计取舍

微软这套框架最核心的设计决策,是把 Workflow 和 Agent 统一在同一个抽象里:Workflow 是显式定义的控制流,Agent 是让模型在运行时决定控制流

两者各有适用场景。Workflow 适合流程固定、每一步做什么都明确的场景,比如"用户输入 -> 数据清洗 -> 格式校验 -> 入库 -> 返回结果"。这种流程写成代码,每一步都确定,延迟可控,成本可预测。Agent 模式则适合路由逻辑会频繁变化的场景,比如"根据用户意图决定调用哪个专业 Agent",这种意图判断用代码硬编码会非常脆弱,交给语义路由反而更稳。

微软在这套框架里同时提供了两种模式,并且在底层用 Actor 模型支撑 Agent 之间的消息传递。每个 Agent 是一个独立执行单元,有自己的状态机,通过消息和其他 Agent 交互。这种设计带来的一个直接好处是:同一个 Agent 可以同时被 Workflow 调用,也可以被另一个 Agent 动态唤起,不需要为两种模式写两套逻辑。

1.3 什么场景才值得上多智能体

聊完原理,我直接给一份"该用/不该用"的清单,这是我被同事问过无数次之后的总结。

如果满足以下任一条件,不建议上多智能体:

  • 任务本身是单步调用,比如"把这段文本翻译成英文"。
  • 调用链固定不变,所有用户请求走完全相同的路径。
  • 对延迟极其敏感,每增加一个 Agent 节点就增加一次模型往返。
  • 团队还处于单 Agent Prompt 都调不明白的阶段。

反过来,如果出现这些信号,就该考虑多智能体:

  • Prompt 已经超过一千行,而且还在继续膨胀。
  • 同一个模型调用里塞了多个互相冲突的角色指令。
  • 你需要把工具按权限域拆分,不同角色只能访问特定资源。
  • 系统里有明显的"分工"诉求,比如先采集再清洗再分析再生成报告。

我个人判断的标准很简单:如果单个 Agent 的错误率可以通过拆分子任务显著下降,就值得拆;如果只是把同样的复杂度从一个 Prompt 搬到了十个 Prompt,那就不值得。后者正是很多团队踩坑的地方——拆完之后提示词总量反而更多了,系统更不稳定了。

2. 围绕 Microsoft Agent Framework 搭建系统的核心步骤

明确完设计哲学,接下来进入实操层面。先交代一个关键点:微软的多智能体生态里目前有几套东西容易混淆,我先把它们的关系理清楚。

2.1 MAF、Semantic Kernel、AutoGen 的边界

很多人在社区里问"微软出了 Agent Framework 是不是 Semantic Kernel 就不用了",这其实是个误解。

根据我自己的实践,三者的关系是这样:Semantic Kernel 定位在单 Agent 的能力层,负责模型接入、Prompt 模板、Function Calling、记忆这些基础能力;AutoGen 的 GroupChat 模式解决的是多 Agent 对话编排;而新出的 Agent Framework(简称 MAF)更像一个运行时协调层,把 Agent 的创建、注册、消息路由、状态管理、生命周期统一起来。

举个类比:Semantic Kernel 是发动机,AutoGen 是变速箱,MAF 是整个底盘和控制系统。发动机决定动力上限,变速箱决定动力怎么分配,底盘决定整辆车怎么开、怎么转向、怎么在不同路况下保持稳定。

所以你在 MAF 里写的 Agent,底层完全可以依赖 Semantic Kernel 提供的模型 Abstraction 和工具调用能力,两者是互补关系,不是替代关系。

2.2 Agent 建模:名称、描述、工具与状态的最小完备集

在开始写任何业务逻辑之前,先想清楚你系统中的每个 Agent 需要哪四个要素:Name、Description、Tools、State

Name 和 Description 的作用很多人低估了。在语义路由模式下,路由 Agent 是根据其他 Agent 的 Description 来决定把任务转给谁的。Description 写得含糊,路由准确率就直接下降。我见过最典型的反例是把描述写成"负责处理用户请求",这种描述等于没写。正确的写法是"负责处理用户退款申请,输入为订单号和退款原因,输出为退款审核结构体,依赖订单系统 Agent 验证订单状态"。

Tools 是 Agent 的能力边界。MAF 的设计里,每个 Agent 有独立的 Tool 注册表,这意味着你可以精确控制某个 Agent 能调用哪些函数。我强烈建议一开始就把工具的读写权限分清楚:数据采集 Agent 只挂只读工具,订单处理 Agent 才能挂写入工具。

State 是经常被忽视的一块。Agent 不是无状态的,尤其是跨多轮任务的时候,每个 Agent 需要维护自己的状态。MAF 里每个 Agent 是独立的 Actor,状态默认隔离,只有通过显式消息进行传递。

2.3 工作流装配:把 Agent 注册进 Workflow

这里我基于 MAF 的设计模式整理了一个核心的代码骨架。实际 API 细节可能随版本迭代,但思想是一致的。

from agent_framework import Agent, Workflow, AgentChatMessage class SearchAgent(Agent): """搜索任务执行 Agent""" def __init__(self, name: str, description: str, context): super().__init__(name=name, description=description, context=context) async def add_to_workflow(self, wf: Workflow): # 把当前 Agent 的消息处理函数注册到工作流 self._delegate_to_workflow(wf, self._handle_task, AgentChatMessage) return self async def _handle_task(self, message: AgentChatMessage): # 1. 从消息中解析任务参数 # 2. 调用自己的工具执行搜索 # 3. 返回带结果的消息 pass # 创建 Workflow 并装配 Agent wf = Workflow() wf.add_agent(SearchAgent( name="search_agent", description="执行必应搜索并返回结构化结果列表,输入为关键词,输出为标题、链接、摘要。", context=context )) wf.add_agent(ParseAgent( name="parse_agent", description="解析搜索结果页面内容,抽取正文关键信息,输出为 Markdown 格式摘要。", context=context )) wf.add_agent(ReportAgent( name="report_agent", description="汇总解析结果并生成最终报告,输出为 JSON 结构。", context=context ))

这个骨架的核心思想是:Agent 之间不直接互相调用方法,而是通过向 Workflow 发送消息,由 Workflow 根据消息类型和内容路由给对应能力的 Agent。这样做的好处是职责收口,出问题的时候只需要查消息流就能定位。

2.4 语义路由:让模型决定谁干活

如果流程固定,上面的 Workflow 装配已经够了。但实际业务里经常出现"要根据用户意图动态决定走哪个子流程"的情况,这时候就需要语义路由。

语义路由的基本逻辑是:把每个 Agent 的 Description 转换成向量或者直接作为候选给模型,让模型根据当前任务内容匹配最合适的 Agent。微软的做法是把语义路由组件内建在 Agent 基类中,每个 Agent 都可以通过add_action_to_workflow注册自己的行为,路由层自动完成匹配。

我实践中的经验是,语义路由的准确率高度依赖 Description 的质量。建议给每个 Agent 的 Description 至少写清楚三要素:输入格式、处理方式、输出格式。比如"接收一段 Python 代码,使用静态分析工具检查潜在 bug,输出问题列表及严重等级",这种描述路由准确率就会高很多。

另外一个技巧是给路由加一个"兜底 Agent"。当所有候选 Agent 的匹配度都不超过阈值时,不直接报错,而是进入一个兜底 Agent,它会把任务重新拆解、尝试换一种表达方式重新路由,或者请求人工介入。这套机制能显著提升系统的鲁棒性。

2.5 底层模型与上下文策略

Agent 框架本身不绑定具体模型,你可以在不同 Agent 上用不同模型。我的建议是:高频、简单、延迟敏感的任务用小模型,低频、复杂、需要推理的任务用大模型

比如在浏览器自动化的场景里,拆分任务和调度路由用大模型保证准确率,但具体的"判断页面是否加载完成""提取某个元素的文本"这种操作完全不需要大模型,用规则和 Playwright 选择器就够了。混合模型策略能把成本压到纯大模型方案的十分之一左右。

上下文策略方面,每个 Agent 的消息队列不能无限膨胀。我的做法是给每个 Agent 设置一个消息保留窗口,比如最近 5 轮交互记录,更早的压缩成摘要存到记忆里。这既保证了长期任务的连续性,又避免了 token 浪费。

3. 多智能体在浏览器自动化任务中的落地:以必应搜索自动任务为例

理论讲完,用实际场景串一遍。最近社区里很多人讨论"自动化脚本处理浏览器任务"这类场景,我就用它来演示多智能体的设计思路。先说清楚,这里的重点不是教你刷指标,而是展示一个真实的、需要分治的浏览器自动化任务该怎么拆成多智能体系统。

3.1 场景拆解:一个浏览器自动化任务涉及的子环节

假如你需要做一个浏览器自动化任务,比如每天定时用必应搜索若干关键词、打开结果页、阅读内容并完成任务打卡。这类任务看似简单,但如果用单脚本硬写,你会发现要处理的事情相当多。

拆开来看至少包含这些子任务:管理浏览器配置和登录态、根据关键词列表发起搜索、判断搜索结果页是否正常加载、处理可能的弹窗验证、保存搜索结果、对结果内容做摘要分析、最后把执行状态汇总成报告。

这些子任务的逻辑彼此独立,但又有数据依赖关系。这正是多智能体擅长的场景。

3.2 Coordinator-Crawler-Writer 三 Agent 分工

我在这类任务里用的拓扑结构是经典的"中心化协调"模式,三个 Agent 各有分工。

Coordinator Agent(协调者)是整个任务的大脑。它读取任务配置文件,把关键词列表拆成小批次,逐批下发执行指令,收集结果,判定是否重试,最后生成汇总报告。它自身不执行任何搜索动作。

Crawler Agent(采集者)是执行层。它只做一件事:接收一个搜索关键词,打开必应搜索结果页,提取结果列表。内部包含固定的浏览器控制逻辑和一个短 Prompt,用于过滤无关广告结果。执行完后返回结构化的搜索结果。

Writer Agent(记录者)负责结果落盘。它把 Crawler 返回的结构化结果转换成统一的 JSON 行格式,写入本地文件或数据库,在积累到一定数量后生成 Markdown 摘要报告。

三个 Agent 之间只有 Coordinator 能主动发起消息,Crawler 和 Writer 完成后必须回传状态。这个设计的好处是:任何一步出错,Coordinator 都可以单独重试,不会影响其他 Agent 的状态。

3.3 稳定性设计:重试、校验与人工确认

浏览器自动化最大的敌人是环境不确定性,页面改版、网络超时、验证码弹出,随便一个都能让脚本中断。多智能体系统在这方面的优势是可以在不同层级做容错。

我在这个项目里设计了三层容错机制。第一层是工具级重试:爬取失败时,Crawler 自带的重试逻辑换个等待时间重新加载页面,最多 3 次。第二层是消息级重试:Coordinator 收到超时或不完整结果时,把同一个任务换一种表达方式重新下发给 Crawler。第三层是链路级降级:如果连续失败超过 5 次,Coordinator 不再盲目重试,而是进入人工确认流程,通过通知接口发送提醒,等待人工确认后再继续。

三层容错搭下来,整个任务的完成率从最初的不到 60% 提升到了 95% 以上。这里的关键不是每一层有多强,而是错误不会从一层直接穿透到任务整体失败

4. 系统设计中最容易翻车的细节:状态、记忆与容错

把系统搭起来只是第一步。我在实际运行中踩过不少坑,这几类是最常见的。

4.1 Agent 之间共享状态时的并发陷阱

多智能体系统里,Agent 是并发运行的。如果你在多个 Agent 之间共享同一个可变状态对象,比如一个全局字典用来保存中间结果,很容易出现数据竞争问题。

我踩过的一个具体坑是:Coordinator 下发任务后立即读取结果文件,但 Crawler 还在写入过程中,导致读到半个 JSON。后面我强制规定:Agent 之间不直接共享内存对象,一切数据传递走消息通道,结果落盘由 Writer 统一负责,Coordinator 只能通过 Writer 的消息确认来感知数据是否就绪。

这个约束看似损失了效率,实际上让系统稳定了一个量级。并发带来的隐形 bug 排查成本远超那一点性能收益。

4.2 工作流和 Agent 混用时的上下文丢失问题

MAF 允许你同时使用 Workflow 和 Agent 模式,但混用的时候要小心上下文丢失。

我遇到过一个问题:任务从一个 Workflow 步骤进入 Agent 模式后,Agent 完成处理返回 Workflow 时,Workflow 之前累积的上下文变量被重置了,后续步骤拿不到前置结果。排查了很久才发现,问题出在 Workflow 的状态管理器没有和 Agent 的状态管理器打通。

解决办法是在设计阶段就明确状态归属:Workflow 的上下文变量只存流程级参数,Agent 的业务数据走独立的状态通道,两者不混用。凡是需要跨环节传递的数据,统一放在消息负载里,不依赖框架的隐式状态传递。

4.3 可观测性设计:多 Agent 排障的唯一抓手

多智能体系统最让人头疼的事情是排障。几个 Agent 互相发送消息,一旦某个环节逻辑判断错误,错误会被下游 Agent 当成有效输入继续处理,最后产出一个完全错误的结果,你很难倒推是哪一步出的问题。

我对自己的项目做了一个强制要求:所有 Agent 的入站消息和出站消息必须结构化记录,包括消息类型、来自哪个 Agent、发往哪个 Agent、耗时、当时的工具调用列表。字段统一格式之后灌入日志系统。

有了这个消息日志,排障的效率完全不一样。比如任务结果不对,直接按任务 ID 拉出整条消息链路,看哪一步传递的数据发生了偏移,基本几分钟就能定位。没有这套日志,多 Agent 系统就是一个黑箱,出了错只能碰运气。

4.4 成本爆炸的预防

多 Agent 系统的 token 消耗是单 Agent 的很多倍,因为一次任务要从协调者到执行者来好几个来回。如果每个 Agent 都配大模型,一个简单任务的成本可能翻 5 倍以上。

我的成本控制三板斧:一是 Agent 分级配模型,简单代理用小模型,复杂代理用大模型;二是消息长度控制,Agent 之间只传必要字段,不把完整上下文反复转发;三是路由预算,Coordinator 路由失败时先尝试语义压缩,而不是无条件重试。

有一次我发现某个生产任务成本突然飙升,查日志发现是语义路由连续 8 次匹配失败,每次都触发兜底 Agent 走了一次大模型调用。后来给路由加了一个熔断机制:连续失败 3 次直接进入人工确认流程,成本立刻回归正常。

5. 个人实测后的几条经验总结

多智能体系统设计是一套组合拳,框架只是基础设施,真正决定系统质量的是你对任务的理解程度。我已经在这套架构上持续迭代了几个月,分享几条实打实的经验。

第一,先做减法再做加法。不要一开始就设计六个 Agent,我建议先把一个 Agent 跑通完整流程,再逐步拆分。你会发现很多"需要拆"的想法实际上是"Prompt 没写好",拆开之后反而引入了不必要的通信开销。

第二,给每个 Agent 写清楚边界。Description 不是给人看的,是给模型看的。写的时候幻想一下:如果我只把这个描述给一个完全不知道上下文的大模型,它能不能准确地把任务路由过来?不能就继续改。

第三,多 Agent 系统不是银弹,它只是把"单点复杂度"变成了"协作复杂度"。如果你连单 Agent 的稳定性都没调明白,就先别上多 Agent。分布式系统的第一课永远是:分布式不会让系统更可靠,它只是让系统能够在不同的失败模式下继续运行。

第四,日志和追踪系统要提前做,不要等出了问题再补。我见过太多项目初期觉得日志系统浪费人力,上线三个月后遇到一个幽灵 bug,花了整整一周才定位——那周的时间足够把日志系统做三遍。

如果你现在正好在往上多智能体系统的路上,我建议你把这篇文章提到的协作拓扑和状态管理优先级提到模型选择前面。模型可以随时换,拓扑和状态设计一旦定型,返工成本可能远比你预想的高。

需要专业的网站建设服务?

联系我们获取免费的网站建设咨询和方案报价,让我们帮助您实现业务目标

立即咨询