Microsoft.Extensions.AI 是微软推出的一个强大的AI集成库,旨在为.NET开发者提供简单、高效的方式来集成人工智能功能到他们的应用程序中。这个库的核心价值在于它提供了一套标准化的接口和中间件模式,使得开发者可以轻松地将各种AI能力整合到现有系统中。
让我们从最基本的聊天功能开始。在Microsoft.Extensions.AI中,创建一个聊天客户端非常简单:
csharp复制var chatOptions = new ChatOptions()
{
Temperature = 0.1f,
TopP = 0.9f,
MaxOutputTokens = 5000
};
var chatClient = AiClient.GetClient();
var response = await chatClient.GetResponseAsync("请跟我讲解CAP在项目的用法", chatOptions);
这里有几个关键参数需要注意:
提示:对于分类任务或需要确定性输出的场景,建议使用较低的Temperature值(0.1-0.3);对于创意生成类任务,可以适当提高(0.7-1.0)。
在实际应用中,精心设计的提示词可以显著提升模型输出质量。以下是几个经过验证的提示词设计技巧:
csharp复制var rolePrompt = """
你是一名铁路票务意图识别专家,负责在前端界面与后端服务之间准确判断用户意图。
仅从以下选项中选择:订票意图、退票意图、咨询意图。
当接收到输入时,请按以下步骤思考:
1. 关键词扫描:检查是否包含订票相关词,如"买票""预订""订"
2. 退票检测:若无订票相关词,再查找"退票""取消""退"
3. 咨询判断:若前两步未命中,判断是否属于咨询或闲聊
4. 置信度评估:若不确定,选择咨询意图并在reason中说明原因
5. 格式输出:严格按JSON模板返回结果
""";
这种结构化提示词设计包含了:
Microsoft.Extensions.AI支持灵活的函数调用功能,这是实现复杂AI应用的关键:
csharp复制var travelTools = new TravelTool();
IList<AITool> batchRegisteredTools =
typeof(TravelTool)
.GetMethods()
.Select(method => AIFunctionFactory.Create(
method,
travelTools,
name: method.Name.ToLowerInvariant(),
description: method.GetCustomAttribute<DescriptionAttribute>()?.Description))
.Cast<AITool>()
.ToList();
工具调用配置选项非常丰富:
csharp复制ChatOptions batchOptions = new()
{
ToolMode = ChatToolMode.Auto, // 自动决定是否调用工具
Tools = batchRegisteredTools, // 可调用的工具集合
AllowMultipleToolCalls = true, // 允许一次调用多个工具
ConversationId = "planner-2024-05-01", // 会话标识
Instructions = "保持中文回答,并在需要时调用工具", // 附加系统提示
ModelId = "gpt-4o", // 指定模型
Temperature = 0.3f, // 控制随机性
StopSequences = ["[DONE]"], // 停止序列
ResponseFormat = ChatResponseFormat.Json // 强制JSON输出
};
实际经验:在工具调用中,建议设置MaximumIterationsPerRequest参数(默认40次)以防止无限循环,生产环境可以设置为5-10次。
缓存是提升AI应用性能的关键。Microsoft.Extensions.AI支持内存缓存和分布式缓存:
csharp复制IDistributedCache distributedCache = new MemoryDistributedCache(
Options.Create(new MemoryDistributedCacheOptions()));
var cacheChatClient = new ChatClientBuilder(chatClient)
.UseDistributedCache(distributedCache)
.Build();
csharp复制var redisCache = new RedisCache(Options.Create(new RedisCacheOptions() {
Configuration = "redis-server:6379",
InstanceName = "MEAICache"
}));
var cacheChatClient = new ChatClientBuilder(chatClient)
.UseDistributedCache(redisCache)
.Build();
缓存性能对比数据:
| 请求类型 | 耗时(ms) | Token使用量 |
|---|---|---|
| 首次请求 | 1200 | 85 |
| 缓存请求 | 15 | 0 |
实测数据:使用Redis缓存后,相同请求的响应时间从1200ms降至15ms,提升80倍!
在生产环境中,限流和内容过滤是必不可少的:
csharp复制// 限流配置
var rateLimiter = new ConcurrencyLimiter(new ConcurrencyLimiterOptions
{
PermitLimit = 1, // 并发请求数限制
QueueLimit = int.MaxValue // 队列长度
});
// 敏感词列表
var sensitiveWords = new[] { "密码", "账号", "机密" };
// 组合中间件
IChatClient protectedClient = new ContentFilteringChatClient(
new RateLimitingChatClient(chatClient, rateLimiter),
sensitiveWords
);
Microsoft.Extensions.AI天然支持.NET的依赖注入系统:
csharp复制var services = new ServiceCollection();
// 配置缓存服务
services.AddSingleton<IDistributedCache>(sp =>
new MemoryDistributedCache(Options.Create(new MemoryDistributedCacheOptions())));
// 注册基础ChatClient
services.AddChatClient(chatClient)
.UseDistributedCache() // 添加缓存中间件
.UseFunctionInvocation(); // 添加函数调用
// 注册多客户端配置
services.AddKeyedChatClient("fast", chatClient)
.Use((messages, options, innerClient, cancellationToken) => {
Console.WriteLine("⚡ 快速处理请求");
return innerClient.GetResponseAsync(messages, options, cancellationToken);
});
services.AddKeyedChatClient("cached", chatClient)
.UseDistributedCache()
.UseFunctionInvocation();
你可以轻松创建自定义中间件来扩展功能:
csharp复制// 重试中间件示例
.Use(getResponseFunc: async (messages, options, innerClient, cancellationToken) =>
{
const int maxRetries = 3;
int attempt = 0;
while (true) {
try {
attempt++;
if (attempt > 1)
Console.WriteLine($"🔄 第 {attempt} 次尝试");
return await innerClient.GetResponseAsync(messages, options, cancellationToken);
}
catch (Exception ex) when (attempt < maxRetries) {
Console.WriteLine($"⚠️ 失败: {ex.Message},准备重试...");
await Task.Delay(1000 * attempt); // 指数退避
}
}
})
在生产环境中,监控AI调用的性能至关重要:
csharp复制options.FunctionInvoker = (context, cancellationToken) =>
{
DateTime beginDate = DateTime.Now;
var functionCall = context.Function;
Console.WriteLine($"调用函数: {functionCall.Name}");
var result = context.Function.InvokeAsync(context.Arguments, cancellationToken);
Console.WriteLine($"耗时: {(DateTime.Now - beginDate).TotalMilliseconds}ms");
return result;
};
问题现象:模型无法准确识别用户意图
解决方案:
csharp复制{
"intention": "咨询意图",
"reason": "输入不够明确,默认为咨询"
}
问题现象:函数调用不执行或报错
排查步骤:
问题现象:相同请求没有命中缓存
检查项:
优化建议:
在实际项目中使用Microsoft.Extensions.AI时,建议从简单功能开始,逐步添加缓存、限流等中间件。特别注意Temperature参数的设置,不同任务类型需要不同的值。对于生产环境,一定要实现完善的监控和日志记录,这对后期排查问题至关重要。