Microsoft.Extensions.AI 入门指南
引言
在 AI 技术日新月异的今天,.NET 开发者终于迎来了属于自己的 AI 开发标准——Microsoft.Extensions.AI (MEAI)。作为微软官方推出的 AI 抽象层,MEAI 旨在为 .NET 生态系统提供统一、简洁的 AI 服务集成方式,让开发者能够轻松地在不同 AI 模型和服务之间切换,而无需重写代码。
本文将带你快速了解 MEAI 的核心概念、使用方法,以及它为何能成为 .NET AI 开发的基石。
为什么需要 MEAI?
传统痛点
在 MEAI 出现之前,.NET 开发者接入 AI 服务面临诸多挑战:
- 🔴 API 不统一:每个 AI 提供商都有自己的 SDK,学习成本高
- 🔴 切换成本高:从 OpenAI 切换到 Azure OpenAI 需要大量代码改动
- 🔴 难以测试:缺乏统一的抽象接口,Mock 和单元测试困难
- 🔴 功能分散:日志、缓存、遥测等横切关注点需要重复实现
MEAI 的解决方案
MEAI 通过提供统一的抽象接口,完美解决了这些问题:
graph TB
A[你的应用] --> B[Microsoft.Extensions.AI]
B --> C1[OpenAI]
B --> C2[Azure OpenAI]
B --> C3[DeepSeek]
B --> C4[Ollama]
B --> C5[其他模型]
style B fill:#4CAF50,stroke:#2E7D32,stroke-width:3px
核心接口详解
1. IChatClient:对话型 AI 的统一抽象
IChatClient 是 MEAI 的核心接口之一,定义了与聊天型 AI 服务交互的标准方式。
核心方法:
// 完整响应
Task<ChatResponse> GetResponseAsync(
IEnumerable<ChatMessage> messages,
ChatOptions? options = null,
CancellationToken ct = default
)
// 流式响应
IAsyncEnumerable<ChatResponseUpdate> GetStreamingResponseAsync(
IEnumerable<ChatMessage> messages,
ChatOptions? options = null,
CancellationToken ct = default
)
示例:快速上手
// 安装必要的包
// #r "nuget: Microsoft.Extensions.AI"
// #r "nuget: Microsoft.Extensions.AI.OpenAI"
using Microsoft.Extensions.AI;
using Azure.AI.OpenAI;
// 1. 创建客户端(以 OpenAI 兼容服务为例)
OpenAIClientOptions clientOptions = new OpenAIClientOptions();
clientOptions.Endpoint = new Uri("https://api.deepseek.com");
OpenAIClient aiClient = new(
new ApiKeyCredential("your-api-key"),
clientOptions
);
IChatClient chatClient = aiClient.AsChatClient("deepseek-chat");
// 2. 构建消息
var messages = new List<ChatMessage>
{
new ChatMessage(ChatRole.System, "你是一个专业的.NET开发助手"),
new ChatMessage(ChatRole.User, "什么是依赖注入?")
};
// 3. 发送请求并获取响应
var response = await chatClient.GetResponseAsync(messages);
Console.WriteLine(response.Text);
2. IEmbeddingGenerator:向量嵌入生成器
IEmbeddingGenerator<TInput, TEmbedding> 提供了生成向量嵌入的统一接口,支持多种输入类型:
// 为文本生成向量嵌入
IEmbeddingGenerator<string, Embedding<float>> embeddingGenerator = ...;
var embeddings = await embeddingGenerator.GenerateAsync(
new[] { "Hello, world!", "AI is amazing!" }
);
foreach (var embedding in embeddings)
{
Console.WriteLine($"向量维度: {embedding.Vector.Length}");
}
MEAI 的五大核心优势
1. 服务无关性:一次编码,多处运行
通过统一的 IChatClient 接口,你可以轻松切换 AI 服务提供商:
// 切换服务只需改变客户端创建方式
IChatClient chatClient;
// 使用 OpenAI
chatClient = new OpenAIClient(...).AsChatClient("gpt-4");
// 切换到 Azure OpenAI
chatClient = new AzureOpenAIClient(...).AsChatClient("gpt-4");
// 切换到 Ollama
chatClient = new OllamaApiClient(...);
// 后续代码完全不变!
var response = await chatClient.GetResponseAsync(messages);
2. 依赖注入友好:原生支持 .NET DI
MEAI 完全拥抱 .NET 的依赖注入(DI)模式:
// 在 Startup 或 Program.cs 中注册
services.AddSingleton<IChatClient>(serviceProvider =>
{
var openAIClient = new OpenAIClient(...);
return openAIClient.AsChatClient("gpt-4");
});
// 在服务中注入使用
public class MyService
{
private readonly IChatClient _chatClient;
public MyService(IChatClient chatClient)
{
_chatClient = chatClient;
}
public async Task<string> AnalyzeCodeAsync(string code)
{
var messages = new[]
{
new ChatMessage(ChatRole.User, $"分析这段代码:{code}")
};
var response = await _chatClient.GetResponseAsync(messages);
return response.Text;
}
}
3. 中间件模式:横切关注点一站式解决
MEAI 引入了中间件(Middleware)模式,让你能够轻松添加日志、缓存、遥测等功能:
IChatClient chatClient = new OpenAIClient(...)
.AsChatClient("gpt-4")
.UseLogging() // 添加日志记录
.UseOpenTelemetry() // 添加遥测
.UseDistributedCache(cache) // 添加缓存
.UseFunctionInvocation(); // 添加自动函数调用
4. 多模态支持:不止于文本
IChatClient 原生支持多模态内容:
var messages = new List<ChatMessage>
{
new ChatMessage(ChatRole.User,
[
new TextContent("图片中是什么?"),
new ImageContent(imageBytes, "image/jpeg")
])
};
var response = await chatClient.GetResponseAsync(messages);
5. 流式响应:实时反馈优化用户体验
对于长文本生成场景,流式响应能显著提升用户体验:
var messages = new[]
{
new ChatMessage(ChatRole.User, "写一篇关于.NET的文章")
};
await foreach (var update in chatClient.GetStreamingResponseAsync(messages))
{
Console.Write(update.Text); // 逐字输出
}
ChatOptions:精细控制生成行为
ChatOptions 类提供了丰富的配置选项来控制 AI 的行为:
var options = new ChatOptions
{
ModelId = "gpt-4o", // 指定模型
Temperature = 0.7f, // 控制创造性(0-2)
TopP = 0.9f, // 核采样
MaxOutputTokens = 2000, // 最大输出长度
StopSequences = new[] { "\n\n" },// 停止序列
ResponseFormat = ChatResponseFormat.Json, // 输出格式
// 工具调用
Tools = new[] { weatherTool },
ToolMode = ChatToolMode.Auto,
// 对话管理
ConversationId = "user-123",
};
var response = await chatClient.GetResponseAsync(messages, options);
关键参数说明
参数
说明
推荐值
Temperature
控制随机性,值越高越创造性
0.7-1.0(创意任务)
0.0-0.3(精确任务)
TopP
核采样,与 Temperature 互补
0.9-1.0
MaxOutputTokens
限制输出长度
根据需求设置
ToolMode
工具调用模式
Auto(自动判断)
Required(强制调用)
ResponseFormat
输出格式
Text、Json、JsonSchema
结构化输出:让 AI 返回可靠的数据
MEAI 支持强制 AI 按照预定义的 JSON Schema 返回数据:
// 定义数据模型
public record PersonInfo(string Name, int Age, string City);
// 直接获取强类型结果(推荐方式)
var response = await chatClient.GetResponseAsync<PersonInfo>(
new[] { new ChatMessage(ChatRole.User, "张三今年25岁,住在北京") }
);
PersonInfo person = response.Result;
Console.WriteLine($"{person.Name}, {person.Age}岁, {person.City}");
// 输出: 张三, 25岁, 北京
与其他框架的集成
1. Semantic Kernel
using Microsoft.SemanticKernel;
// MEAI 客户端可以无缝集成到 SK
var kernel = Kernel.CreateBuilder()
.AddChatCompletionService(chatClient) // 使用 MEAI 客户端
.Build();
2. Microsoft Agent Framework
using Microsoft.Extensions.AI.Agents;
// 创建 Agent(构建在 MEAI 之上)
var agent = new AIAgent(chatClient, new AIAgentOptions
{
Name = "编程助手",
Instructions = "你是一个专业的.NET开发专家"
});
最佳实践
1. 使用依赖注入管理客户端生命周期
// ❌ 避免:每次请求都创建新客户端
var client = new OpenAIClient(...).AsChatClient("gpt-4");
// ✅ 推荐:使用 DI 注册为单例
services.AddSingleton<IChatClient>(sp =>
new OpenAIClient(...).AsChatClient("gpt-4")
);
2. 合理配置缓存减少成本
services.AddDistributedMemoryCache();
services.AddSingleton<IChatClient>(sp =>
{
var cache = sp.GetRequiredService<IDistributedCache>();
return new OpenAIClient(...)
.AsChatClient("gpt-4")
.UseDistributedCache(cache); // 相同请求直接返回缓存
});
3. 使用日志监控 AI 调用
IChatClient chatClient = new OpenAIClient(...)
.AsChatClient("gpt-4")
.UseLogging(loggerFactory); // 自动记录所有请求/响应
4. 设置合理的超时和重试
var options = new ChatOptions
{
// 使用取消令牌设置超时
};
using var cts = new CancellationTokenSource(TimeSpan.FromSeconds(30));
var response = await chatClient.GetResponseAsync(messages, options, cts.Token);
实战案例:构建一个智能代码审查助手
让我们整合所学知识,构建一个完整的应用:
using Microsoft.Extensions.AI;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Logging;
// 1. 配置依赖注入
var services = new ServiceCollection();
services.AddLogging(builder => builder.AddConsole());
services.AddDistributedMemoryCache();
services.AddSingleton<IChatClient>(sp =>
{
var logger = sp.GetRequiredService<ILoggerFactory>();
var cache = sp.GetRequiredService<IDistributedCache>();
return new OpenAIClient(new ApiKeyCredential("your-key"))
.AsChatClient("gpt-4")
.UseLogging(logger)
.UseDistributedCache(cache);
});
services.AddSingleton<CodeReviewService>();
var provider = services.BuildServiceProvider();
// 2. 定义服务
public class CodeReviewService
{
private readonly IChatClient _chatClient;
private readonly ILogger<CodeReviewService> _logger;
public CodeReviewService(
IChatClient chatClient,
ILogger<CodeReviewService> logger)
{
_chatClient = chatClient;
_logger = logger;
}
public async Task<CodeReviewResult> ReviewCodeAsync(string code)
{
var messages = new List<ChatMessage>
{
new(ChatRole.System, @"你是一个专业的代码审查专家。
请分析代码并返回以下内容:
- 潜在的bug
- 性能问题
- 最佳实践建议"),
new(ChatRole.User, $"请审查这段代码:\n```csharp\n{code}\n```")
};
var options = new ChatOptions
{
Temperature = 0.3f, // 审查任务需要更确定的结果
MaxOutputTokens = 1000
};
try
{
var response = await _chatClient.GetResponseAsync<CodeReviewResult>(
messages,
options
);
_logger.LogInformation("代码审查完成,发现 {Count} 个问题",
response.Result.Issues.Count);
return response.Result;
}
catch (Exception ex)
{
_logger.LogError(ex, "代码审查失败");
throw;
}
}
}
public record CodeReviewResult(
List<string> Bugs,
List<string> PerformanceIssues,
List<string> BestPractices
)
{
public int TotalIssues => Bugs.Count + PerformanceIssues.Count + BestPractices.Count;
public List<string> Issues => Bugs.Concat(PerformanceIssues).Concat(BestPractices).ToList();
}
// 3. 使用服务
var reviewService = provider.GetRequiredService<CodeReviewService>();
var result = await reviewService.ReviewCodeAsync(@"
public void ProcessData(List<string> data)
{
for(int i=0; i<data.Count; i++)
{
Console.WriteLine(data[i]);
}
}
");
Console.WriteLine($"发现 {result.TotalIssues} 个问题");
总结
Microsoft.Extensions.AI 为 .NET 开发者带来了:
✅ 统一的抽象接口:IChatClient 和 IEmbeddingGenerator 简化 AI 集成
✅ 服务无关性:轻松切换不同 AI 提供商
✅ 中间件生态:日志、缓存、遥测开箱即用
✅ 依赖注入友好:完美融入 .NET 生态
✅ 生产级特性:结构化输出、流式响应、多模态支持
MEAI 不仅是一个库,更是 .NET AI 生态系统的基石。无论你是构建简单的聊天机器人,还是复杂的企业级 AI 应用,MEAI 都能提供坚实的支持。