实战探索 Microsoft Agent Framework:构建我的第一个 MAF 智能体应用

张开发
2026/4/20 0:36:40 15 分钟阅读

分享文章

实战探索 Microsoft Agent Framework:构建我的第一个 MAF 智能体应用
1. 初识 Microsoft Agent Framework第一次听说 Microsoft Agent Framework简称 MAF是在一个技术社区里当时看到有人分享用这个框架快速搭建了一个智能客服系统。作为一个长期在 AI 领域摸爬滚打的老兵我立刻被这个新框架吸引住了。MAF 给我的第一印象就像是把 Semantic Kernel 和 AutoGen 这两个框架的优点都吸收进来还加入了不少新特性。简单来说MAF 是微软推出的一个开源开发套件专门用来构建人工智能代理和多智能体工作流。它支持 .NET 和 Python 两种语言这点对开发者特别友好。我特别喜欢它的设计理念 - 不是简单地封装大模型 API而是提供了一套完整的工具链让开发者能轻松实现多轮对话、函数调用、工具集成这些高级功能。2. 环境搭建与基础配置2.1 创建项目与安装依赖我决定从一个最简单的控制台项目开始。打开终端运行dotnet new console -o MyFirstMAFAgent然后进入项目目录安装核心包。这里要注意 MAF 目前还是预览版需要加上 --prerelease 参数dotnet add package Azure.AI.OpenAI --prerelease dotnet add package Microsoft.Agents.AI.OpenAI --prerelease我在实际操作时遇到了一个版本冲突问题。Azure.AI.OpenAI 2.8.1-beta.1 这个版本会和其他包产生依赖冲突后来我把版本降到 2.7.0-beta2 就解决了。这也是为什么我建议新手在 IDE比如 Visual Studio里安装包更方便可以直接看到依赖关系。2.2 配置模型访问接下来要配置大模型访问。我创建了一个简单的 ModelProvider 类来管理配置public class ModelProvider { public string ApiKey { get; init; } string.Empty; public string ModelId { get; init; } string.Empty; public string Endpoint { get; init; } string.Empty; }然后在 appsettings.json 里配置参数{ ModelProvider: { EndPoint: https://api.moonshot.cn/v1, ApiKey: 你的API_KEY, ModelId: kimi-k2-0905-preview } }读取配置的代码也很简单var config new ConfigurationBuilder() .AddJsonFile(appsettings.json) .Build(); var modelProvider new ModelProvider { ApiKey config[ModelProvider:ApiKey], ModelId config[ModelProvider:ModelId], Endpoint config[ModelProvider:Endpoint] };3. 创建第一个智能体3.1 基础聊天智能体现在可以创建我们的第一个智能体了我决定从一个笑话机器人开始var agent new OpenAIClient( new ApiKeyCredential(modelProvider.ApiKey), new OpenAIClientOptions { Endpoint new Uri(modelProvider.Endpoint) }) .GetChatClient(modelProvider.ModelId) .CreateAIAgent( instructions: 你是个幽默大师擅长讲冷笑话, name: 笑话机器人); await foreach (var update in agent.RunStreamingAsync(讲个关于程序员的冷笑话)) { Console.Write(update); }运行这个程序你会看到一个关于程序员的冷笑话。这里有几个关键点CreateAIAgent方法创建了一个智能体实例instructions参数定义了智能体的行为特征RunStreamingAsync实现了流式输出3.2 视觉智能体MAF 还支持视觉能力。我尝试创建一个能分析图片的智能体var agent new OpenAIClient( new ApiKeyCredential(modelProvider.ApiKey), new OpenAIClientOptions { Endpoint new Uri(modelProvider.Endpoint) }) .GetChatClient(qwen-vl-plus) // 注意要换支持视觉的模型 .CreateAIAgent( instructions: 你是一个图片分析专家, name: 视觉助手); var message new ChatMessage(ChatRole.User, [ new TextContent(描述这张图片的内容), new UriContent(https://example.com/image.jpg, image/jpeg) ]); await foreach (var update in agent.RunStreamingAsync(message)) { Console.Write(update); }4. 实现功能工具集成4.1 基础函数工具智能体的真正威力在于它能调用外部工具。我创建了一个查询天气的函数var agent new OpenAIClient( new ApiKeyCredential(modelProvider.ApiKey), new OpenAIClientOptions { Endpoint new Uri(modelProvider.Endpoint) }) .GetChatClient(modelProvider.ModelId) .CreateAIAgent( instructions: 你是一个智能助手, tools: [AIFunctionFactory.Create(GetWeather)]); Console.WriteLine(await agent.RunAsync(北京的天气怎么样?)); [Description(获取指定城市的天气信息)] static string GetWeather([Description(要查询的城市名称)] string location) { // 这里应该是调用真实天气API return $今天{city}的天气是晴天气温25℃; }4.2 需要人工审批的函数在实际业务中有些操作需要人工审批。MAF 提供了很好的支持var weatherFunc AIFunctionFactory.Create(GetWeather); var approvalFunc new ApprovalRequiredAIFunction(weatherFunc); var agent new OpenAIClient( new ApiKeyCredential(modelProvider.ApiKey), new OpenAIClientOptions { Endpoint new Uri(modelProvider.Endpoint) }) .GetChatClient(modelProvider.ModelId) .CreateAIAgent( instructions: 你是一个需要审批的助手, tools: [approvalFunc]); var thread agent.GetNewThread(); var response await agent.RunAsync(帮我预定会议室, thread); // 获取需要审批的请求 var approvalRequests response.Messages .SelectMany(x x.Contents) .OfTypeFunctionApprovalRequestContent() .ToList(); if (approvalRequests.Any()) { Console.WriteLine($需要审批的操作: {approvalRequests[0].FunctionCall.Name}); var approvalMessage new ChatMessage(ChatRole.User, [ approvalRequests[0].CreateResponse(true) // true表示批准 ]); Console.WriteLine(await agent.RunAsync(approvalMessage, thread)); }5. 部署为可调用服务5.1 创建 MCP 服务MAF 最酷的功能之一是可以把智能体部署为 MCP 服务var agent new OpenAIClient( new ApiKeyCredential(modelProvider.ApiKey), new OpenAIClientOptions { Endpoint new Uri(modelProvider.Endpoint) }) .GetChatClient(modelProvider.ModelId) .CreateAIAgent( instructions: 你是一个笑话服务, name: 笑话服务); var mcpTool McpServerTool.Create(agent.AsAIFunction()); var builder Host.CreateEmptyApplicationBuilder(); builder.Services .AddMcpServer() .WithStdioServerTransport() .WithTools([mcpTool]); await builder.Build().RunAsync();5.2 客户端调用其他应用可以通过标准方式调用这个服务var client new McpClient(); var result await client.InvokeToolAsync(笑话服务, 讲个笑话); Console.WriteLine(result);6. 实战构建天气查询助手现在让我们把这些知识综合起来构建一个完整的天气查询助手。6.1 项目结构设计我创建了如下项目结构WeatherAssistant/ ├── Services/ │ ├── WeatherService.cs ├── Agents/ │ ├── WeatherAgent.cs ├── Program.csWeatherService 封装了真实的天气 API 调用public class WeatherService { [Description(获取城市天气信息)] public async Taskstring GetWeatherAsync( [Description(城市名称)] string city) { // 这里调用真实天气API return ${city}今天晴转多云气温20-28℃; } }6.2 智能体实现WeatherAgent 类封装了智能体逻辑public class WeatherAgent { private readonly OpenAIClient _client; private readonly string _modelId; public WeatherAgent(OpenAIClient client, string modelId) { _client client; _modelId modelId; } public AIAgent CreateAgent() { var weatherService new WeatherService(); var weatherFunc AIFunctionFactory.Create(weatherService.GetWeatherAsync); return _client.GetChatClient(_modelId) .CreateAIAgent( instructions: 你是一个专业的天气查询助手, name: 天气助手, tools: [weatherFunc]); } }6.3 主程序集成最后在 Program.cs 中集成所有组件var modelProvider // 初始化模型配置 var client new OpenAIClient( new ApiKeyCredential(modelProvider.ApiKey), new OpenAIClientOptions { Endpoint new Uri(modelProvider.Endpoint) }); var agent new WeatherAgent(client, modelProvider.ModelId).CreateAgent(); while (true) { Console.Write(你想查询哪个城市的天气); var city Console.ReadLine(); if (string.IsNullOrEmpty(city)) break; var response await agent.RunAsync(${city}的天气怎么样); Console.WriteLine(response); }7. 调试与优化技巧在实际开发中我发现了一些有用的调试技巧日志记录MAF 提供了丰富的日志接口可以记录智能体的思考过程builder.Services.AddLogging(configure configure.AddConsole().SetMinimumLevel(LogLevel.Debug));超时设置对于长时间运行的操作记得设置合理的超时var options new OpenAIClientOptions { Endpoint new Uri(modelProvider.Endpoint), RetryPolicy new RetryPolicy(maxRetries: 2), NetworkTimeout TimeSpan.FromSeconds(30) };性能监控可以使用 Application Insights 等工具监控智能体性能builder.Services.AddApplicationInsightsTelemetry();8. 进阶功能探索完成基础项目后我开始尝试一些更高级的功能8.1 多智能体协作MAF 支持创建多个智能体协同工作var translator client.GetChatClient(modelId) .CreateAIAgent(你是一个专业翻译负责中英互译); var summarizer client.GetChatClient(modelId) .CreateAIAgent(你是一个摘要专家负责总结内容); var workflow new WorkflowBuilder() .AddAgent(translator) .AddAgent(summarizer) .Build(); var result await workflow.RunAsync(请把这篇英文文章翻译成中文并总结);8.2 记忆与上下文智能体可以记住对话历史var thread agent.GetNewThread(); await agent.RunAsync(我叫张三, thread); var response await agent.RunAsync(我叫什么名字, thread); Console.WriteLine(response); // 输出你叫张三8.3 自定义中间件可以插入自定义中间件来修改智能体行为public class LoggingMiddleware : IAgentMiddleware { public async Task InvokeAsync(AgentContext context, NextMiddleware next) { Console.WriteLine($收到请求: {context.Request}); await next(context); Console.WriteLine($返回响应: {context.Response}); } } // 注册中间件 agent.UseMiddlewareLoggingMiddleware();9. 项目部署与运维当项目开发完成后需要考虑部署问题9.1 容器化部署我通常使用 Docker 容器来部署 MAF 应用FROM mcr.microsoft.com/dotnet/sdk:8.0 AS build WORKDIR /src COPY . . RUN dotnet publish -c Release -o /app FROM mcr.microsoft.com/dotnet/aspnet:8.0 WORKDIR /app COPY --frombuild /app . ENTRYPOINT [dotnet, WeatherAssistant.dll]9.2 性能优化对于生产环境我推荐以下优化措施使用连接池管理模型客户端实现响应缓存对耗时操作使用异步处理9.3 监控与告警完善的监控系统对智能体应用至关重要。我通常会配置请求成功率监控响应时间监控异常告警10. 经验总结与避坑指南经过这个项目的实践我总结了以下几点经验版本兼容性问题MAF 目前还是预览版不同版本间可能存在兼容性问题。建议锁定特定版本号。模型选择不同模型对函数调用的支持程度不同。如果发现函数调用不工作可以尝试换一个模型。错误处理智能体可能会产生意外输出一定要做好输入验证和输出过滤。测试策略智能体行为具有一定不可预测性需要设计专门的测试用例来验证各种边界情况。成本控制频繁调用大模型可能产生高昂费用建议实现使用量监控和限流机制。在实际项目中我还发现 MAF 的一个隐藏优势 - 它很好地抽象了底层模型差异。这意味着你可以轻松切换不同的模型提供商而不用重写业务逻辑。比如今天用 OpenAI明天想换成国产模型只需要修改配置即可。

更多文章