在 .NET AI 聊天应用中升级到 Microsoft 代理框架

在 .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>&gt; 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 =&gt; 
            $"<result filename="\&quot;{r.DocumentId}\&quot;" page_number="\&quot;{r.PageNumber}\&quot;">{r.Text}</result>");
    }
}

这种设计实现了关注点分离,便于测试和扩展。

3.3 配置 AI 代理

在 Program.cs 中注册代理服务:

csharp 复制代码
// 注册搜索功能服务
builder.Services.AddSingleton<searchfunctions>();

// 配置 AI 代理
builder.AddAIAgent("ChatAgent", (sp, key) =&gt; 
{
    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 =&gt; 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) =&gt; 
{
    // ... 其他配置
    tools: [
        AIFunctionFactory.Create(searchFunctions.SearchAsync),
        AIFunctionFactory.Create(weatherFunctions.GetWeatherAsync)
    ]
});
6.2 多代理协作

实现专业化代理协作:

csharp 复制代码
// 研究代理
builder.AddAIAgent("ResearchAgent", (sp, key) =&gt; 
{
    // 专注于信息检索
});

// 写作代理
builder.AddAIAgent("WritingAgent", (sp, key) =&gt; 
{
    // 专注于内容生成
});

// 协调代理
builder.AddAIAgent("CoordinatorAgent", (sp, key) =&gt; 
{
    // 协调其他代理工作
});

这种架构适合复杂的内容生成场景。

6.3 自定义中间件

添加代理行为定制:

csharp 复制代码
.AsBuilder()
.Use(async (messages, options, next, ct) =&gt; 
{
    // 调用前处理
    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 =&gt; 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能力,包括复杂任务处理、工具集成和多代理协作。本文详细介绍了从环境准备、框架集成到高级应用的完整流程,并提供了最佳实践指导。关键优势包括:

  1. 架构清晰:实现关注点分离,提升可维护性
  2. 扩展性强:易于添加新工具和代理类型
  3. 开发友好:基于熟悉的 .NET 模式构建
  4. 可观测性好:内置遥测和监控支持

随着 AI 代理技术的不断发展,采用 Microsoft 代理框架将为 .NET 开发者提供构建下一代智能应用的坚实基础。

相关推荐
唐青枫9 小时前
C#.NET Random 深入解析:随机数生成原理与最佳实践
c#·.net
JosieBook14 小时前
【.NET】WinForm中如何调整DataGridView控件的列宽?
.net
追逐时光者19 小时前
一款基于 .NET WinForm 开源、轻量且功能强大的节点编辑器,采用纯 GDI+ 绘制无任何依赖库仅仅100+Kb
后端·.net
.NET修仙日记1 天前
第一章:从零开始构建你的第一个C#/.NET应用程序
c#·.net·.net core
三天不学习1 天前
APIJSON:用JSON自动生成API,告别手写CRUD!【.NET 8 集成案例,也支持JAVA】
json·.net·apijson
唐青枫1 天前
循环插入太慢?试试 C#.NET SqlBulkCopy,一次导入上百万数据
c#·.net
sky-stars2 天前
.NET 泛型编程(泛型类、泛型方法、泛型接口、泛型委托、泛型约束)
c#·.net·.netcore
huoshan123453 天前
给旧版 .NET 也开一扇“私有之门”——ILAccess.Fody 实现原理与设计
c#·.net·fody·il·mono.cecil