Microsoft Agent Framework 详解与实践
核心组件用户输入 → AI代理 → 工具调用 → 外部服务 ↓ ↓ LLM处理 MCP服务器 ↓ ↓ 决策逻辑 ← 执行结果 ← ↓ 响应生成增强组件会话Session管理多轮对话状态上下文提供者Context Provider提供代理记忆能力中间件Middleware拦截和增强代理行为工具集成通过MCP客户端集成外部工具适用场景✅适合使用AI代理的场景客户支持处理多模态查询文本、语音、图像教育辅导利用外部知识库提供个性化辅导代码生成与调试辅助开发者进行实现、代码审查和调试研究助手搜索网络、总结文档、整合多源信息动态任务处理需要自主决策、临时规划和试错探索的场景❌不适合使用AI代理的场景高度结构化且需要严格遵循预定义规则的任务可以直接编写函数处理的确定性任务简单的CRUD操作需要100%确定性结果的场景关键原则如果可以编写函数来处理任务就直接编写函数而不是使用AI代理。可以用AI辅助编写函数。2. 工作流Workflows定义工作流是一种图形化的执行流程它可以连接多个AI代理和函数来执行复杂的多步骤任务同时保持一致性和可靠性。工作流结构开始节点 ↓ AI代理1 → 决策节点 → AI代理2 ↓ ↓ ↓ 函数调用 ← 条件路由 → 并行处理 ↓ ↓ 结束节点 ← 汇总结果 ←核心特性模块化可分解为更小的可重用组件代理集成可整合多个AI代理和非代理组件类型安全强类型确保组件间消息正确流转灵活控制流支持条件路由、并行处理和动态执行路径外部集成内置请求/响应模式用于系统集成检查点机制保存工作流状态支持恢复和续接多代理编排内置顺序、并发、移交等编排模式可组合性工作流可嵌套或组合创建更复杂流程AI代理 vs 工作流对比特性AI代理工作流执行方式LLM驱动的动态步骤预定义的操作序列决策方式基于对话上下文和可用工具自动决定明确定义的流程路径适用任务非结构化、需要探索的任务结构化、多步骤的复杂任务控制程度较低LLM自主决策较高显式定义可预测性较低较高安装与配置.NET环境要求# 前置条件 - .NET 8.0 SDK 或更高版本 - Azure OpenAI 资源已部署模型如 gpt-4o-mini - Azure CLI已安装并认证可选创建项目# 创建新控制台应用 dotnet new console -o AgentFrameworkDemo cd AgentFrameworkDemo安装NuGet包# 安装核心包实际使用的包 dotnet add package Azure.AI.OpenAI --prerelease dotnet add package Azure.Identity dotnet add package Microsoft.Extensions.Configuration.Json # 注意Microsoft.Agents.AI 包仍在开发中 # 当前示例使用 Azure.AI.OpenAI 实现相同功能配置Azure认证# 使用Azure CLI登录可选 az login # 确保账户具有以下角色之一 # - Cognitive Services OpenAI User # - Cognitive Services OpenAI Contributor创建配置文件创建appsettings.json文件{ AzureOpenAI: { Endpoint: https://your-resource.openai.azure.com/, DeploymentName: gpt-4o-mini, ApiKey: } }注意Endpoint: 你的 Azure OpenAI 资源端点DeploymentName: 部署的模型名称如 gpt-4o-mini, gpt-4oApiKey: 可留空使用 Azure CLI 认证或填入 API 密钥快速入门基础AI代理示例C#注意Microsoft Agent Framework 目前仍在预览阶段本示例使用 Azure OpenAI SDK 实现相同的功能。using System; using Azure; using Azure.AI.OpenAI; using Azure.Identity; using Microsoft.Extensions.Configuration; using OpenAI.Chat; // 加载配置 var configuration new ConfigurationBuilder() .AddJsonFile(appsettings.json) .Build(); var endpoint configuration[AzureOpenAI:Endpoint]; var deploymentName configuration[AzureOpenAI:DeploymentName]; var apiKey configuration[AzureOpenAI:ApiKey]; // 创建Azure OpenAI客户端 AzureOpenAIClient openAIClient; if (!string.IsNullOrEmpty(apiKey)) { // 使用API Key认证 openAIClient new AzureOpenAIClient( new Uri(endpoint), new AzureKeyCredential(apiKey) ); } else { // 使用Azure CLI认证 openAIClient new AzureOpenAIClient( new Uri(endpoint), new AzureCliCredential() ); } // 获取聊天客户端 var chatClient openAIClient.GetChatClient(deploymentName); // 创建对话 var messages new ListChatMessage { new SystemChatMessage(You are good at telling jokes.), new UserChatMessage(Tell me a joke about a pirate.) }; var response await chatClient.CompleteChatAsync(messages); Console.WriteLine(response.Value.Content[0].Text);配置文件示例创建appsettings.json文件{ AzureOpenAI: { Endpoint: https://your-resource.openai.azure.com/, DeploymentName: gpt-4o-mini, ApiKey: } }Python快速示例import asyncio from agent_framework.azure import AzureAIClient from azure.identity.aio import AzureCliCredential async def main(): async with ( AzureCliCredential() as credential, AzureAIClient(async_credentialcredential).as_agent( nameJokeAgent, instructionsYou are good at telling jokes., ) as agent, ): result await agent.run(Tell me a joke about a pirate.) print(result.text) if __name__ __main__: asyncio.run(main())AI代理详解代理工具Agent Tools / Function Calling定义工具函数using System.ComponentModel; public class CustomerServiceTools { [Description(Search for customer order by order ID)] public async Taskstring GetOrderInfoAsync( [Description(Order ID to search, format like ORD-12345)] string orderId) { // 模拟数据库查询 await Task.Delay(100); return $订单信息查询成功 - 订单号{orderId} - 客户姓名张三 - 产品Surface Laptop 5 - 状态已发货 - 物流单号SF1234567890; } [Description(Process refund request for an order)] public async Taskstring ProcessRefundAsync( [Description(Order ID to refund)] string orderId, [Description(Refund reason provided by customer)] string reason) { await Task.Delay(200); var refundId $RF-{DateTime.Now:yyyyMMddHHmmss}; return $退款申请已成功提交 - 退款单号{refundId} - 订单号{orderId} - 退款原因{reason} - 预计处理时间3-5个工作日; } }使用 Function Callingusing OpenAI.Chat; // 创建工具实例 var tools new CustomerServiceTools(); // 定义工具Function Calling var chatOptions new ChatCompletionOptions(); chatOptions.Tools.Add(ChatTool.CreateFunctionTool( GetOrderInfo, Search for customer order by order ID, BinaryData.FromString( { type: object, properties: { orderId: { type: string, description: Order ID to search, format like ORD-12345 } }, required: [orderId] } ) )); chatOptions.Tools.Add(ChatTool.CreateFunctionTool( ProcessRefund, Process refund request for an order, BinaryData.FromString( { type: object, properties: { orderId: { type: string, description: Order ID to refund }, reason: { type: string, description: Refund reason provided by customer } }, required: [orderId, reason] } ) )); // 调用AI并处理工具调用 var messages new ListChatMessage { new SystemChatMessage(你是专业的客户服务助手), new UserChatMessage(查询订单 ORD-12345) }; var completion await chatClient.CompleteChatAsync(messages, chatOptions); // 检查是否需要调用工具 if (completion.Value.FinishReason ChatFinishReason.ToolCalls) { // 添加助手消息到历史 messages.Add(new AssistantChatMessage(completion.Value)); // 执行工具调用 foreach (var toolCall in completion.Value.ToolCalls) { var functionName toolCall.FunctionName; var arguments JsonDocument.Parse(toolCall.FunctionArguments.ToString()); string result functionName switch { GetOrderInfo await tools.GetOrderInfoAsync( arguments.RootElement.GetProperty(orderId).GetString()! ), ProcessRefund await tools.ProcessRefundAsync( arguments.RootElement.GetProperty(orderId).GetString()!, arguments.RootElement.GetProperty(reason).GetString()! ), _ 未知工具 }; // 添加工具结果到历史 messages.Add(new ToolChatMessage(toolCall.Id, result)); } // 再次调用AI生成最终响应 var finalResponse await chatClient.CompleteChatAsync(messages, chatOptions); Console.WriteLine(finalResponse.Value.Content[0].Text); }多轮对话Multi-turn Conversationusing OpenAI.Chat; // 创建对话历史以保持上下文 var conversationHistory new ListChatMessage { new SystemChatMessage(You are a helpful assistant.) }; // 第一轮对话 conversationHistory.Add(new UserChatMessage(My name is John.)); var response1 await chatClient.CompleteChatAsync(conversationHistory); var assistantMessage1 response1.Value.Content[0].Text; Console.WriteLine(assistantMessage1); // 将助手响应添加到历史 conversationHistory.Add(new AssistantChatMessage(assistantMessage1)); // 第二轮对话AI记得之前的上下文 conversationHistory.Add(new UserChatMessage(Whats my name?)); var response2 await chatClient.CompleteChatAsync(conversationHistory); var assistantMessage2 response2.Value.Content[0].Text; Console.WriteLine(assistantMessage2); // 输出Your name is John. // 将响应添加到历史 conversationHistory.Add(new AssistantChatMessage(assistantMessage2)); // 第三轮对话 conversationHistory.Add(new UserChatMessage(Tell me a joke about my name.)); var response3 await chatClient.CompleteChatAsync(conversationHistory); Console.WriteLine(response3.Value.Content[0].Text);代理记忆Agent Memory注意此示例展示记忆管理概念实际实现通过维护对话历史来管理上下文。using OpenAI.Chat; // 使用对话历史实现记忆功能 var conversationHistory new ListChatMessage { new SystemChatMessage(You are a personal assistant. Remember user preferences.) }; // 用户设置偏好 conversationHistory.Add(new UserChatMessage(Remember that I prefer meetings in the morning.)); var response1 await chatClient.CompleteChatAsync(conversationHistory); conversationHistory.Add(new AssistantChatMessage(response1.Value.Content[0].Text)); conversationHistory.Add(new UserChatMessage(My favorite programming language is C#.)); var response2 await chatClient.CompleteChatAsync(conversationHistory); conversationHistory.Add(new AssistantChatMessage(response2.Value.Content[0].Text)); // 稍后查询 - AI会从对话历史中回忆 conversationHistory.Add(new UserChatMessage(When do I prefer meetings?)); var response3 await chatClient.CompleteChatAsync(conversationHistory); Console.WriteLine(response3.Value.Content[0].Text); // 输出You prefer meetings in the morning.代理中间件Agent Middleware注意此示例展示中间件概念实际实现可以通过包装函数来实现类似功能。using OpenAI.Chat; // 创建包装类实现日志和过滤功能 public class ChatClientWrapper { private readonly ChatClient _chatClient; public ChatClientWrapper(ChatClient chatClient) { _chatClient chatClient; } public async Taskstring CompleteChatWithLoggingAsync( ListChatMessage messages, ChatCompletionOptions? options null) { // 日志记录请求 var userMessage messages.LastOrDefault(m m is UserChatMessage); if (userMessage ! null) { Console.WriteLine($[Request] {((UserChatMessage)userMessage).Content[0].Text}); } // 检查敏感内容 if (userMessage ! null ContainsSensitiveInfo(((UserChatMessage)userMessage).Content[0].Text)) { Console.WriteLine([Filter] Sensitive information detected); return I cannot process sensitive information.; } // 调用实际的API var response await _chatClient.CompleteChatAsync(messages, options); var responseText response.Value.Content[0].Text; // 日志记录响应 Console.WriteLine($[Response] {responseText}); return responseText; } private bool ContainsSensitiveInfo(string message) { // 实现敏感信息检测逻辑 return message.Contains(password) || message.Contains(credit card); } } // 使用示例 var wrapper new ChatClientWrapper(chatClient); var messages new ListChatMessage { new SystemChatMessage(You are a helpful assistant.), new UserChatMessage(Tell me a joke.) }; var response await wrapper.CompleteChatWithLoggingAsync(messages);工作流详解重要说明以下工作流示例为概念性设计展示多代理协作的思路。Microsoft Agent Framework 的工作流 API 仍在开发中实际实现需要通过组合多个 ChatClient 调用来完成。基础工作流结构概念性示例using OpenAI.Chat; using System.Text.Json; // 概念性的客户支持工作流实现 public class CustomerSupportWorkflow { private readonly ChatClient _chatClient; public CustomerSupportWorkflow(ChatClient chatClient) { _chatClient chatClient; } public async Taskstring ExecuteAsync(string userQuery) { // 步骤1: 意图识别 var intent await TriageAsync(userQuery); // 步骤2: 根据意图路由到专门的处理逻辑 return intent switch { technical await HandleTechnicalIssueAsync(userQuery), billing await HandleBillingIssueAsync(userQuery), _ await HandleGeneralQueryAsync(userQuery) }; } private async Taskstring TriageAsync(string query) { var messages new ListChatMessage { new SystemChatMessage(你是客户服务分类助手。分析用户问题并返回以下类别之一 - technical: 技术问题 - billing: 账单问题 - general: 一般咨询 只返回类别名称不要其他内容。), new UserChatMessage(query) }; var response await _chatClient.CompleteChatAsync(messages); return response.Value.Content[0].Text.Trim().ToLower(); } private async Taskstring HandleTechnicalIssueAsync(string query) { var messages new ListChatMessage { new SystemChatMessage(你是技术支持专家负责解决技术问题。), new UserChatMessage(query) }; var response await _chatClient.CompleteChatAsync(messages); return response.Value.Content[0].Text; } private async Taskstring HandleBillingIssueAsync(string query) { var messages new ListChatMessage { new SystemChatMessage(你是账单支持专家负责处理账单相关问题。), new UserChatMessage(query) }; var response await _chatClient.CompleteChatAsync(messages); return response.Value.Content[0].Text; } private async Taskstring HandleGeneralQueryAsync(string query) { var messages new ListChatMessage { new SystemChatMessage(你是客户服务代表负责回答一般性问题。), new UserChatMessage(query) }; var response await _chatClient.CompleteChatAsync(messages); return response.Value.Content[0].Text; } }条件路由概念性示例using OpenAI.Chat; public class OrderProcessingWorkflow { private readonly ChatClient _chatClient; public async Taskstring ExecuteAsync(string orderId) { // 步骤1: 验证订单 var isValid await ValidateOrderAsync(orderId); if (isValid) { // 步骤2: 处理支付 await ProcessPaymentAsync(orderId); // 步骤3: 发货 return await ShipOrderAsync(orderId); } else { // 通知客户 return await NotifyCustomerAsync(orderId, 订单验证失败); } } private async Taskbool ValidateOrderAsync(string orderId) { // 实现订单验证逻辑 await Task.Delay(100); return orderId.StartsWith(ORD-); } private async Task ProcessPaymentAsync(string orderId) { // 实现支付处理逻辑 await Task.Delay(200); } private async Taskstring ShipOrderAsync(string orderId) { // 实现发货逻辑 await Task.Delay(150); return $订单 {orderId} 已发货; } private async Taskstring NotifyCustomerAsync(string orderId, string reason) { // 实现客户通知逻辑 await Task.Delay(100); return $订单 {orderId} 处理失败: {reason}; } }并行处理概念性示例using OpenAI.Chat; public class DataAnalysisWorkflow { private readonly ChatClient _chatClient; public async Taskstring ExecuteAsync(string data) { // 步骤1: 加载数据 var loadedData await LoadDataAsync(data); // 步骤2: 并行执行三种分析 var statisticalTask StatisticalAnalysisAsync(loadedData); var sentimentTask SentimentAnalysisAsync(loadedData); var trendTask TrendAnalysisAsync(loadedData); await Task.WhenAll(statisticalTask, sentimentTask, trendTask); // 步骤3: 汇总结果 return await AggregateResultsAsync( statisticalTask.Result, sentimentTask.Result, trendTask.Result ); } private async Taskstring LoadDataAsync(string data) { await Task.Delay(100); return data; } private async Taskstring StatisticalAnalysisAsync(string data) { var messages new ListChatMessage { new SystemChatMessage(你是统计分析专家。), new UserChatMessage($对以下数据进行统计分析{data}) }; var response await _chatClient.CompleteChatAsync(messages); return response.Value.Content[0].Text; } private async Taskstring SentimentAnalysisAsync(string data) { var messages new ListChatMessage { new SystemChatMessage(你是情感分析专家。), new UserChatMessage($对以下数据进行情感分析{data}) }; var response await _chatClient.CompleteChatAsync(messages); return response.Value.Content[0].Text; } private async Taskstring TrendAnalysisAsync(string data) { var messages new ListChatMessage { new SystemChatMessage(你是趋势分析专家。), new UserChatMessage($对以下数据进行趋势分析{data}) }; var response await _chatClient.CompleteChatAsync(messages); return response.Value.Content[0].Text; } private async Taskstring AggregateResultsAsync( string statistical, string sentiment, string trend) { var messages new ListChatMessage { new SystemChatMessage(你是数据分析总结专家。), new UserChatMessage($汇总以下分析结果 统计分析{statistical} 情感分析{sentiment} 趋势分析{trend}) }; var response await _chatClient.CompleteChatAsync(messages); return response.Value.Content[0].Text; } }多代理编排模式1. 顺序编排Sequential概念性示例using OpenAI.Chat; public class ResearchWorkflow { private readonly ChatClient _chatClient; public async Taskstring ExecuteAsync(string topic) { // 步骤1: 搜索信息 var searchResults await SearchAsync(topic); // 步骤2: 分析数据 var analysis await AnalyzeAsync(searchResults); // 步骤3: 生成摘要 var summary await SummarizeAsync(analysis); // 步骤4: 审查结果 return await ReviewAsync(summary); } private async Taskstring SearchAsync(string topic) { var messages new ListChatMessage { new SystemChatMessage(你是信息搜索专家。), new UserChatMessage($搜索关于 {topic} 的相关信息) }; var response await _chatClient.CompleteChatAsync(messages); return response.Value.Content[0].Text; } private async Taskstring AnalyzeAsync(string data) { var messages new ListChatMessage { new SystemChatMessage(你是数据分析专家。), new UserChatMessage($分析以下数据{data}) }; var response await _chatClient.CompleteChatAsync(messages); return response.Value.Content[0].Text; } private async Taskstring SummarizeAsync(string analysis) { var messages new ListChatMessage { new SystemChatMessage(你是内容摘要专家。), new UserChatMessage($总结以下分析{analysis}) }; var response await _chatClient.CompleteChatAsync(messages); return response.Value.Content[0].Text; } private async Taskstring ReviewAsync(string summary) { var messages new ListChatMessage { new SystemChatMessage(你是质量审查专家。), new UserChatMessage($审查以下摘要{summary}) }; var response await _chatClient.CompleteChatAsync(messages); return response.Value.Content[0].Text; } }2. 并发编排Concurrent概念性示例using OpenAI.Chat; public class ContentCreationWorkflow { private readonly ChatClient _chatClient; public async Taskstring ExecuteAsync(string topic) { // 步骤1: 生成大纲 var outline await CreateOutlineAsync(topic); // 步骤2: 并行撰写各部分 var section1Task WriteSectionAsync(outline, section1); var section2Task WriteSectionAsync(outline, section2); var section3Task WriteSectionAsync(outline, section3);