☰
Microsoft Agent Framework实战:智能体开发从手写循环到声明式编排
2026/10/17 12:09:04 网站建设 项目流程

最近一直在折腾 AI 智能体(Agent)开发,最大的感受就是:框架选对了,效率能差出一个数量级。过去我们手工实现一个 ReAct 循环,少说几百行代码,还要处理模型调用、工具解析、状态回溯,跑起来一堆 bug。而现在,微软开源的 Microsoft Agent Framework 把这些都收进了框架层,让每位开发者都能用几行代码构建出可编排、可调试、可上生产的智能体。这篇文章不是官方文档的复读,而是我基于实际踩坑经验,从设计思路、核心概念、完整实操到问题排查的复盘。如果你正准备做 Agent 开发,或者已经在自己实现 Agent 循环、被各种边界情况折磨过,这篇应该能帮你省下不少时间。

1. 为什么需要 Agent Framework:智能体开发正在经历的转型

1.1 手写 Agent 要经历什么

说实话,我前两年做 Agent 相关项目的时候,市面上还没有特别顺手的开源框架,很多团队都是自己封装。一个最简单的、能调用外部工具的大模型应用,要手动实现的东西比你想象得多。

首先是模型接入层。你得决定用哪家模型服务、什么协议、怎么处理鉴权、怎么做 retry、怎么控制超时。这些虽然不复杂,但很琐碎,而且每家服务的细节差异很大。其次是工具调用循环。大模型返回一个“我想调用某个函数”的指令,你要去解析这个指令、校验参数、执行对应的函数、把结果再塞回给模型。这个循环看起来简单,真正做起来全是坑:模型返回的 JSON 格式偶尔不合法,参数名和你的函数签名对不上,模型调用了不存在的工具,工具执行报错之后怎么反馈给模型……每一个异常分支都要写代码处理。

更麻烦的是多轮对话的状态管理。用户问一句,模型可能为了回答这个问题连续调用三个工具,每一步的中间结果都要记录。用户不满意结果,要求重新生成或者换一种方式,你要怎么回滚?上下文越来越长,要如何压缩?这些在 Demo 里没人管,一上生产全是问题。

你会发现,大部分时间花在“伺候”模型循环上,而不是真正解决业务问题。这其实就是 Agent 开发最真实的门槛。

1.2 Microsoft Agent Framework 的定位

微软推出的这个开源框架,定位非常明确:把“构建智能体”这件事,从手写循环提升到声明式配置。

它提供了一个中间执行层(Runner),把模型调用、工具分发、历史管理都收进去了。你不需要自己写 while 循环去反复调用模型,也不需要自己维护一套 tool schema 的序列化逻辑。你只需要定义智能体的指令、工具和模型,然后启动一个 Runner,剩下的循环由框架来控制。

从开发体验上讲,这更像是在写一个普通的后端服务:定义对象、注册方法、启动运行。而不是像以前那样,在写一种“实验性的算法胶水代码”。

而且它的架构是语言无关的,提供 Python 和 .NET 两套实现,选型上比较自由。底层复用了 Semantic Kernel 那一套插件、内存、连接器的基础设施,等于说,它不是从零造轮子,而是把已有的好东西往上叠了一层“智能体生命周期”的抽象。

1.3 适合谁学

我总结下来,有三类人最应该关注这个框架:

  • 后端开发者:你有 Python 或 .NET 基础,想做 AI 应用,但没精力从零搞一套 Agent 基础设施。
  • AI 应用开发者:你已经在用大模型 API 做业务,但发现纯 Prompt 工程已经满足不了复杂任务,希望让模型真正“干活”。
  • 技术负责人或架构师:需要评估多智能体协作方案,想知道业界主流框架的抽象方式和能力边界。

有一点要提前说清楚,它不是一个低代码平台,也不是搭积木的图形化工具。你依然要写代码,只是把最脏最累的“驱动大模型循环”的部分交给了框架。理解了这一点,你才能正确评估它的价值。

2. Agent Framework 核心设计解析

2.1 智能体最小单元:Agent 对象

在 Microsoft Agent Framework 里,一个智能体就是普通得不能再普通的对象。它主要由这几个部分组成:

  • model:模型连接配置,指你这个智能体用哪个模型服务。
  • instructions:系统提示词,相当于这个智能体的人设和行为准则。
  • tools:工具列表,智能体能调用哪些外部能力。
  • chat_history:会话历史,多轮对话的上下文记录。

这个抽象非常克制,没有发明一堆花哨概念。但正是这种“简单到简单”的设计,让上手门槛降得很低。你可以把一个 Agent 理解成一个“带手(工具)有嘴巴(模型)的员工”,instructions 就是老板给他定的岗位职责。

如果你熟悉对象导向编程,一看就明白该怎么扩展。想在某个 Agent 里多加点功能,那就给它多挂几个工具;想让它更专业,就修改 instructions;想接入不同的模型能力,就替换 model 配置。

2.2 Runner 做了什么

Runner 是整个框架的引擎,也是我最喜欢的一部分。以 Python 实现为例,AgentRunner 接收一个 Agent 对象,然后就进入了一个完整的执行循环:

  1. 组装 System Prompt 和用户输入形成完整上下文。
  2. 调用模型,拿到响应。
  3. 检测响应里是否包含工具调用请求。
  4. 如果包含,就执行对应的工具函数,把执行结果写回对话历史。
  5. 带着新的历史再次调用模型。
  6. 直到模型不再请求工具,输出最终回复,Runner 结束。

这个过程就是经典的 ReAct 循环,区别在于你不需要自己写。Runner 是异步实现的,这意味着它可以和 FastAPI、异步任务队列无缝集成。你写了一个 Web 接口,收到请求后把参数塞给 Runner,Runner 跑完之后返回结果,全程不阻塞事件循环。

这里有一个很值得玩味的细节:Runner 在执行工具时,是把结果当作“一条消息”追加到 Chat History 里的。模型在下一次调用时就能看到这个结果。这种设计其实是一个通用的代理循环范式,你在其他框架里也能看到类似思路,说明微软团队是在吸收了社区经验之后做的抽象整合。

2.3 多智能体编排:Agent Group Chat

单 Agent 能解决的问题终究有限。比如一个任务需要先查数据、再写报告、最后翻译成多种语言,如果全让一个 Agent 干,它的上下文会非常臃肿,而且职责混乱。这时候就需要多智能体协作。

Agent Framework 内置了多 Agent 能力,核心有两个概念:

  • Agent Group Chat:一组可以互相交流的 Agent 的集合。
  • Orchestrator:决定当前回合应该由哪个 Agent 来发言。

这两个概念对应了多智能体系统里的关键问题:谁是我的队友、下一步谁说话。Orchestrator 有不同的策略实现,比如 RoundRobinOrchestrator 就是轮流发言,适合大家各说一段的协作场景;还有基于模型决策的编排器,由大模型动态决定当前任务最合适的接手角色。

我自己的经验是,多 Agent 设计能不能跑通,主要看你对 Orchestrator 的选择。如果任务的子步骤相对固定,轮流发言就够用;如果任务高度动态,就要让模型参与决策。框架提供这两类能力,正好覆盖了大部分业务形态。

2.4 与 Semantic Kernel 的关系

可能有人会问,微软不是已经有 Semantic Kernel 了吗,为什么又要搞一个 Agent Framework?

我的理解是,Semantic Kernel 更多是在“函数级别”做编排:把大模型能力包装成一个个 Kernel Function,然后通过 Planner 去执行一个流程。但它没有把“智能体”当作一个一等公民来对待。Agent 并不是一个简单的函数链,它需要自己的状态、自己的工具集、自己的上下文窗口,还需要能和别的 Agent 对话。

Agent Framework 在底层复用了 Semantic Kernel 的组件,相当于在 SK 之上加了“Agent 生命周期”和“多 Agent 协作”的抽象。你可以把它理解为:SK 是地基和基础设施,Agent Framework 是盖好的样板房。如果你之前用过 SK,理解起来会非常快;如果你没接触过,也完全可以直接上手 Agent Framework,它把底层的复杂度遮挡得很好。

3. 实操:用 Agent Framework 构建一个可用智能体

3.1 环境准备与安装

先搞定环境。我推荐用 Python 3.10 以上的版本,框架对类型注解和异步特性依赖比较多。装包之前先建一个干净的虚拟环境,避免跟别的项目互相污染依赖。

python -m venv .venv source .venv/bin/activate pip install microsoft-agent-framework

安装完之后,建议先跑一下官方的快速入门示例,确认你的 Python 环境和依赖都正常。这一步别跳过,很多问题其实在环境层面就注定了,等你写完代码再排查就费劲了。

接下来是模型接入。官方支持多个模型提供方,几乎所有兼容主流协议的大模型服务都能接。我的建议是,初期先用那种配置最简单、兼容性最好的服务,先把框架逻辑跑通,再去考虑别的高端模型。你并不想一边学框架一边排查模型网关的问题,那会让人崩溃。

3.2 写第一个单 Agent

安装好之后,写一个最小可用的 Agent 很简单。核心就是定义 Agent 对象,然后用 Runner 启动。

import asyncio from agent_framework import Agent, AgentRunner async def main(): agent = Agent( name="DemoAgent", instructions="你是一个简洁友好的助手,回答用户问题时不啰嗦。", model="你的模型配置" ) runner = AgentRunner(agent) result = await runner.run("你好,请介绍一下你自己。") print(result) asyncio.run(main())

你看,真正的业务代码就这么点。这个 DemoAgent 本质上就是一个大模型套了一层系统提示词,看起来没啥了不起。但请注意,这里已经具备了 Agent 的完整形态:它有名字、有人设、有模型,并且在 Runner 的控制下运行。后面加任何能力,都是在这个最小单元上做加法。

我实际跑下来,框架的初始化非常轻量,没有那种“引入一个框架就要加载一堆默认配置”的沉重感。这一点对二次开发很重要,意味着框架不会绑架你的项目结构。

3.3 给 Agent 加第一个工具

现在给这个 Agent 加一个工具。工具的本质就是一个普通函数,加上一个描述。在 Agent Framework 里,通常用装饰器来注册。

from datetime import datetime @agent.tool def get_current_time() -> str: """获取当前的日期和时间,格式为 ISO 8601。""" return datetime.now().isoformat()

然后你可以在对话里问它“现在几点了”,框架会自动识别这个请求、调用工具、把结果返回给模型并生成回答。

这里面有一个非常关键的细节:工具的“描述”写得越清晰越好。大模型是通过你的函数名和描述来决定什么时候调用它的。如果你的描述写得模棱两可,模型很容易在错误的时候调用。比如上面那个函数,描述里写了“格式为 ISO 8601”,这样用户没有特别指定格式时,模型也可以放心调用,因为它知道返回的是什么形式。

还有一点要注意,工具函数的参数最好简单,能用基本数据类型就用基本数据类型。复杂的自定义对象虽然理论上可行,但会让模型生成参数时的错误率升高,得不偿失。

3.4 多 Agent 协作案例

单 Agent 熟悉之后,可以试试多 Agent。我搭过一个模拟项目,任务是让一个“搜索型 Agent”和一个“写作型 Agent”合作,完成一个研究报告的初稿。

from agent_framework import Agent, AgentRunner from agent_framework.orchestrator import RoundRobinOrchestrator searcher = Agent( name="Searcher", instructions="你是资料检索专家,只负责查找有效信息并输出要点列表。", model="模型A" ) writer = Agent( name="Writer", instructions="你是研究报告撰写者,基于Searcher提供的信息写出结构清晰的报告。", model="模型B" ) group_chat = AgentGroupChat( agents=[searcher, writer], orchestrator=RoundRobinOrchestrator() ) runner = AgentRunner(group_chat) result = await runner.run("请调研一下智能客服行业现状,并生成一份简报。")

真实跑起来,你会看到两个 Agent 依次发言:Searcher 先输出一堆资料要点,Writer 基于这些要点生成报告。整个过程非常像两个实习生配合干活,一个查资料,一个写文档。

这个模式下有个好处,每个 Agent 的职责都很单一,上下文窗口的压力也分散了。Searcher 只需要处理资料检索相关的上下文,Writer 不需要关心那些原始搜索结果有多长,它只看到 Searcher 整理出来的要点。

3.5 运行与调试

框架在调试方面做得比较好。第一次跑多 Agent 的时候,强烈建议打开详细日志(verbose 模式),看看每一步发生了什么。

日志里能看到的关键信息包括:模型返回的原始消息、工具被调用的时间点和参数、每个 Agent 的发言顺序、上下文长度的变化。这些信息能帮你快速定位问题是出在工具逻辑,还是出在模型决策,还是出在编排策略。

等业务逻辑稳定了,再关掉详细日志,用正常的日志级别跑生产。如果你一上来就关了日志,后面出问题只能靠猜。

4. 常见问题与排查技巧实录

4.1 模型连接老报错

这是新手最容易踩的坑。症状一般是两种:一个是调用模型时报 HTTP 错误,另一个是模型返回空内容。

第一种情况多半是模型服务地址或鉴权信息配错了。请务必确认你的模型服务地址是否包含完整路径,有的服务要求末尾加/v1,有的不加。第二种空内容的情况,很多时候是因为某些模型服务不支持流式输出里的某些扩展字段,而框架默认开启了这些字段。

排查思路很简单:先用一个最简脚本直接调用模型服务,确认接口本身没问题,再用框架去连。这样能快速把问题缩小到“框架配置”还是“模型服务”。

4.2 工具定义得起,模型就是不调用

这个问题我遇到太多次了。模型没有调用你的工具,不是模型傻,而是你的“说明书”写得不到位。

工具说明书就是函数名加描述。函数名要像样,描述要说清楚“什么时候该用”。举个反例,你把一个查询天气的工具描述写成“查询天气”,模型在用户问“今天要不要带伞”时,很可能不会想到去查天气,因为你没告诉它“这个工具可以判断是否需要带伞”。

改进方法很简单,把描述写成“查询指定城市的当前天气和未来几小时降水概率,用于判断出行是否需要带伞或加衣服”。模型看到这样的描述,触发率立刻上升。这是文本工程在 Agent 开发里的重要体现,一点都不玄学。

4.3 Chat History 越来越长,上下文爆掉

Agent 的会话历史会随着对话轮次不断增长。如果你在一个长会话里让 Agent 调用了几十个工具,每个工具的结果都追加到历史里,上下文窗口迟早装不下。

缓解手段有两个层面。第一个层面是业务侧:主动清理历史。超过一定轮次后,把重要的结论用一两条消息“压缩”成一个摘要,然后丢弃旧消息。第二个层面是框架侧:它提供了一定的截断策略,但那是兜底方案,不能依赖它。

我在一个模拟客服项目里实践过:每个会话保留最近 10 轮完整消息,之前的消息用大模型跑一个摘要任务,生成一段精简的会话纪要。这样既保住了上下文关键信息,又控制了 Token 消耗。

4.4 多 Agent 互相“客气”,陷入死循环

多 Agent 协作的时候,最尴尬的情况是两个 Agent 开始互夸:“你说得很对”“我来补充一下”“我又想到一点”……如果编排器一直给它们发言机会,这个对话永远结束不了。

解决方式有几种:第一,给每个 Agent 的 instructions 里写明任务完成条件,比如“当你已输出最终报告,就不需要再补充任何内容”。第二,设置 Runner 的最大迭代次数,超过就直接终止,返回当前结果。第三,改用模型决策的编排器,它会在合适的时机主动结束对话。

我的建议是,一开始就把这三点都做了,因为多 Agent 死循环往往是组合原因,单靠一种手段压不住。

4.5 开发调试三板斧

最后分享我在实际调试中会的三板斧:

  • 第一板斧:打开详细日志,看模型的完整输出序列。
  • 第二板斧:把关键的 Chat History 导出成文本,人工检查上下文有没有缺失或错乱。
  • 第三板斧:直接调用工具函数本身,确认工具逻辑没有隐藏 bug。很多问题表面上看是 Agent 行为奇怪,查到根上其实是工具函数返回了不符合预期的数据。

这三招覆盖了框架层、模型层和应用层三个维度。先按这个顺序排查,能解决九成以上的问题。

5. 结合实践的几点体会

5.1 框架能解决 80%,剩下 20% 在业务设计

Agent Framework 把模型循环、工具分发、多 Agent 编排这些技术问题解决得很好。但真正让我头疼的,从来不是这些技术问题,而是业务的抽象和拆解。

举个例子,你要做一个“项目周报生成助手”。技术链路非常简单:读取项目数据、整理变化、生成周报。但业务层面的问题很多:项目数据从哪个系统来?哪些信息要优先展示?不同角色的读者关心的内容不一样怎么处理?周报的格式模板谁来维护?这些是框架完全管不了的。

Agent 开发有个特点,技术占比可能只有一半,另一半是你对业务的理解和建模能力。框架解决的是那 50% 的通用技术,剩下 50% 要靠你自己的领域经验来填充。

5.2 单人开发者也能撑起一条智能体流水线

过去做多 Agent 系统,听起来像是一个团队才能干的事情。但有了这类框架之后,个人开发者完全可以一个人撑起一条智能体流水线。

我做过一个私人知识库助手,三个 Agent 协作:一个负责检索知识库,一个负责整理答案,一个负责校对引用来源。代码总量也就两百行左右。放在以前,光 Agent 框架就要自己写很多,一个人根本做不过来。

这种变化意味着,Agent 应用开发的边际成本在急剧下降。很多以前需要专门团队才能启动的项目,现在一个周末就能出原型。对个人开发者来说,这绝对是一个红利期。

5.3 往后的扩展方向

从 Agent Framework 再往扩展,还有几个方向值得关注。

第一个方向是接入真实业务系统。Agent 有能力、有工具,但工具背后要对接真实的企业 IM、工单系统、数据库、审批流程。这些集成工作量比 Agent 本身都要大,但也是价值最明显的地方。

第二个方向是事件驱动。把 Agent 从一个“对话接口”变成一个“事件消费者”。比如系统检测到订单异常,自动触发一个 Agent 去分析原因并生成处理建议,而不是等着用户来问。这种非交互式的 Agent 场景,我个人认为是企业落地的大方向。

第三个方向是标准协议对接。Agent Framework 支持接入符合行业标准的工具协议,这样可以让你的 Agent 直接使用社区里的现成工具,不用每个都自己封装。

这几个方向基本都是顺着框架已有的能力往外自然延伸,技术上有迹可循,业务上空间也大。

最后说一个小经验:别一上来就搞多 Agent。先把单 Agent 加工具的链路跑通,确认模型、工具、历史这三样都稳定了,再一步步加角色。否则出了问题,你都不知道是模型抽风还是编排逻辑写错了。我踩过这个坑,所以提醒一下后来的人。

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

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

立即咨询