在 .NET AI 聊天应用中升级到 Microsoft 代理框架
引言
随着人工智能技术的快速发展,简单的聊天机器人已经不能满足复杂业务场景的需求。Microsoft 代理框架(Microsoft Agent Framework)为 .NET 开发者提供了构建智能代理(AI Agent)的能力,使应用程序能够实现多步推理、工具调用和复杂工作流编排。本文将详细介绍如何将一个基础的 .NET AI 聊天应用升级为基于 Microsoft 代理框架的智能代理系统,包括环境准备、框架集成、功能扩展和最佳实践等内容。
1. Microsoft 代理框架概述
Microsoft 代理框架是微软推出的 .NET AI 代理开发框架,相比传统聊天机器人,它具有以下核心能力:
- 多步骤工作流推理:能够分解复杂任务为多个执行步骤
 - 工具调用能力:可与API、数据库和服务进行交互
 - 上下文保持:维护整个对话的上下文一致性
 - 自主决策:根据指令和数据做出智能判断
 - 多代理协作:支持多个代理协同工作
 
该框架基于 .NET 开发者熟悉的模式构建,如依赖注入、中间件和遥测技术,与 Microsoft.Extensions.AI 深度集成,为开发者提供了熟悉的开发体验。
2. 环境准备与基础应用创建
2.1 先决条件
在开始升级前,需要准备以下环境:
- .NET 9 SDK
 - Visual Studio 2022 或 VS Code(含 C# Dev Kit)
 - Azure 账号(可访问 Azure OpenAI)
 - 安装 .NET AI 应用模板
 
2.2 创建基础应用
使用 .NET AI 模板创建基础聊天应用:
            
            
              bash
              
              
            
          
          dotnet new install Microsoft.Extensions.AI.Templates
dotnet new ai-chat-webapp -n ChatApp20 -ai azure-openai -vs local -or aspire
        该命令会创建一个包含三个项目的解决方案:
- ChatApp20.Web:Blazor Server 聊天界面
 - ChatApp20.AppHost:.NET Aspire 业务流程
 - ChatApp20.ServiceDefaults:共享服务配置
 
2.3 项目结构分析
关键文件结构如下:
            
            
              bash
              
              
            
          
          ChatApp20/
├── ChatApp20.Web/
│   ├── Components/Pages/Chat/ # 聊天界面
│   ├── Services/ # 数据服务
│   ├── Program.cs # AI 配置
│   └── wwwroot/Data/ # 示例PDF
├── ChatApp20.AppHost/
└── ChatApp20.ServiceDefaults/
        初始的 Program.cs 已配置了 Azure OpenAI 客户端、语义搜索和向量存储功能。
3. 集成 Microsoft 代理框架
3.1 安装必要的 NuGet 包
在 ChatApp20.Web.csproj 中添加以下包引用:
            
            
              xml
              
              
            
          
          <itemgroup>
  <packagereference Include="Microsoft.Agents.AI" Version="1.0.0-preview.251009.1" />
  <packagereference Include="Microsoft.Agents.AI.Abstractions" Version="1.0.0-preview.251009.1" />
  <packagereference Include="Microsoft.Agents.AI.Hosting" Version="1.0.0-preview.251009.1" />
  <packagereference Include="Microsoft.Agents.AI.Hosting.OpenAI" Version="1.0.0-alpha.251009.1" />
  <packagereference Include="Microsoft.Agents.AI.OpenAI" Version="1.0.0-preview.251009.1" />
</itemgroup>
        这些包提供了代理框架的核心功能、抽象定义和 OpenAI 集成支持。
3.2 创建专用工具服务
将搜索功能从 UI 组件移到专用服务类中:
            
            
              csharp
              
              
            
          
          using System.ComponentModel;
namespace ChatApp20.Web.Services;
public class SearchFunctions
{
    private readonly SemanticSearch _semanticSearch;
    public SearchFunctions(SemanticSearch semanticSearch)
    {
        _semanticSearch = semanticSearch;
    }
    [Description("Searches for information using a phrase or keyword")]
    public async Task<ienumerable<string>> SearchAsync(
        [Description("The phrase to search for.")] string searchPhrase,
        [Description("Filter by filename if specified")] string? filenameFilter = null)
    {
        var results = await _semanticSearch.SearchAsync(searchPhrase, filenameFilter, 5);
        return results.Select(r => 
            $"<result filename="\"{r.DocumentId}\"" page_number="\"{r.PageNumber}\"">{r.Text}</result>");
    }
}
        这种设计实现了关注点分离,便于测试和扩展。
3.3 配置 AI 代理
在 Program.cs 中注册代理服务:
            
            
              csharp
              
              
            
          
          // 注册搜索功能服务
builder.Services.AddSingleton<searchfunctions>();
// 配置 AI 代理
builder.AddAIAgent("ChatAgent", (sp, key) => 
{
    var searchFunctions = sp.GetRequiredService<searchfunctions>();
    var chatClient = sp.GetRequiredService<ichatclient>();
    
    return chatClient.CreateAIAgent(
        name: key,
        instructions: "You are a helpful assistant that provides short and accurate answers.",
        tools: [AIFunctionFactory.Create(searchFunctions.SearchAsync)]
    )
    .UseOpenTelemetry(c => c.EnableSensitiveData = builder.Environment.IsDevelopment())
    .Build();
});
        关键配置点包括:
- 代理名称标识
 - 系统指令定义代理行为
 - 工具注册和方法绑定
 - 集成遥测监控
 
4. 更新聊天界面组件
4.1 修改 Chat.razor
更新组件代码以使用代理框架:
            
            
              razor
              
              
            
          
          @inject IServiceProvider ServiceProvider
@using Microsoft.Agents.AI
@code {
    private AIAgent _agent;
    protected override void OnInitialized()
    {
        _agent = ServiceProvider.GetRequiredKeyedService<aiagent>("ChatAgent");
    }
    private async Task AddUserMessageAsync(ChatMessage userMessage)
    {
        // ... 原有消息处理逻辑
        
        await foreach (var update in _agent.RunStreamingAsync(
            messages.Skip(statefulMessageCount),
            currentResponseCancellation.Token))
        {
            // 处理流式响应
        }
    }
}
        4.2 响应流处理
代理框架支持流式响应,提供更流畅的用户体验。
5. 测试与验证
5.1 使用 .NET Aspire 运行
.NET Aspire 提供了统一的服务管理面板,可以:
- 查看服务发现
 - 监控日志和遥测数据
 - 检查服务健康状况
 - 管理配置和密钥
 
启动应用后,Aspire 仪表板会自动打开,显示各组件状态和交互情况。
5.2 测试代理行为
典型的测试场景包括:
基础对话测试:
用户:你好!
代理:你好!我是一个乐于助人的AI助手。
        工具调用测试:
            
            
              ini
              
              
            
          
          用户:应急生存套装应该包含哪些物品?
代理:基础生存套装应包含:<result filename="Survival_Kit.pdf" page_number="2">防水火柴、急救包...</result>
        文件特定查询:
            
            
              ini
              
              
            
          
          用户:GPS手表有哪些功能?
代理:主要功能包括:<result filename="GPS_Watch.pdf" page_number="3">实时追踪、路线规划...</result>
        通过 Aspire 仪表板可以实时观察代理的决策过程、工具调用参数和响应生成情况。
6. 高级应用场景
6.1 添加更多工具
扩展代理能力,如添加天气查询:
            
            
              csharp
              
              
            
          
          public class WeatherFunctions
{
    [Description("获取指定位置的天气情况")]
    public async Task<string> GetWeatherAsync(
        [Description("城市名称")] string city)
    {
        // 调用天气API
        return $"{city}天气:晴,25°C";
    }
}
// 注册到代理
builder.AddAIAgent("ChatAgent", (sp, key) => 
{
    // ... 其他配置
    tools: [
        AIFunctionFactory.Create(searchFunctions.SearchAsync),
        AIFunctionFactory.Create(weatherFunctions.GetWeatherAsync)
    ]
});
        6.2 多代理协作
实现专业化代理协作:
            
            
              csharp
              
              
            
          
          // 研究代理
builder.AddAIAgent("ResearchAgent", (sp, key) => 
{
    // 专注于信息检索
});
// 写作代理
builder.AddAIAgent("WritingAgent", (sp, key) => 
{
    // 专注于内容生成
});
// 协调代理
builder.AddAIAgent("CoordinatorAgent", (sp, key) => 
{
    // 协调其他代理工作
});
        这种架构适合复杂的内容生成场景。
6.3 自定义中间件
添加代理行为定制:
            
            
              csharp
              
              
            
          
          .AsBuilder()
.Use(async (messages, options, next, ct) => 
{
    // 调用前处理
    logger.LogInformation("Processing {count} messages", messages.Count());
    
    var result = await next(messages, options, ct);
    
    // 调用后处理
    logger.LogInformation("Generated response");
    return result;
})
        可用于实现缓存、日志、验证等横切关注点。
7. 最佳实践与性能优化
7.1 工具设计指南
- 提供清晰的工具描述
 - 参数说明要详细具体
 - 返回格式标准化
 - 错误处理要健壮
 
7.2 测试策略
编写全面的单元和集成测试:
            
            
              csharp
              
              
            
          
          [Fact]
public async Task SearchAsync_ReturnsFormattedResults()
{
    // 准备模拟数据
    var mockSearch = new Mock<semanticsearch>();
    mockSearch.Setup(x => x.SearchAsync("test", null, 5))
        .ReturnsAsync(/* 测试数据 */);
    
    // 执行测试
    var functions = new SearchFunctions(mockSearch.Object);
    var results = await functions.SearchAsync("test");
    
    // 验证结果
    Assert.Contains("test data", results.First());
}
        7.3 性能考量
- 流式 vs 非流式:交互式场景用流式,批处理用非流式
 - 工具调用优化:减少不必要的工具调用
 - 监控指标:跟踪令牌用量、响应时间、错误率等
 
7.4 部署到 Azure
使用 .NET Aspire 的 Azure 部署工具:
            
            
              bash
              
              
            
          
          az login
cd ChatApp20.AppHost
azd init
azd up
        该流程会自动配置所有必要的 Azure 资源。
结论
通过将 .NET AI 聊天应用升级到 Microsoft 代理框架,开发者可以获得更强大的AI能力,包括复杂任务处理、工具集成和多代理协作。本文详细介绍了从环境准备、框架集成到高级应用的完整流程,并提供了最佳实践指导。关键优势包括:
- 架构清晰:实现关注点分离,提升可维护性
 - 扩展性强:易于添加新工具和代理类型
 - 开发友好:基于熟悉的 .NET 模式构建
 - 可观测性好:内置遥测和监控支持
 
随着 AI 代理技术的不断发展,采用 Microsoft 代理框架将为 .NET 开发者提供构建下一代智能应用的坚实基础。