摘要:高级配置1. 流式响应缓存缓存同样支持流式模式,通过控制行为:var cachedClient = baseChatClient.AsBuilder.UseDistributedCache(cache, configure: c =>{// true(默认):
通过 Microsoft.Extensions.AI 的缓存功能,智能存储和复用 AI 响应,显著降低 API 成本并将响应速度提升 10-100 倍。
✅ 成本优化:相同请求直接返回缓存,避免重复 API 调用 ✅ 性能飞跃:缓存命中响应时间可缩短至毫秒级 ✅ 全场景支持:自动处理流式与非流式两种响应模式 ✅ 生产就绪:支持 Redis、SQL Server 等企业级分布式存储在生产环境中,大语言模型调用存在三大痛点:
痛点
影响
缓存方案
成本高昂每次 API 调用产生费用 重复请求直接返回缓存 延迟较高网络+模型推理耗时 缓存命中毫秒级响应 重复请求用户常问相同问题 智能识别并复用结果FAQ 系统:用户反复咨询相同问题
文档查询:内容相对固定的知识库
批量处理:大量重复或相似的查询任务
️ 核心组件组件
职责
CachingChatClient抽象基类,定义缓存逻辑 DistributedCachingChatClient 基于 IDistributedCache的实现缓存键生成基于消息+选项+版本的哈希计算 流式处理自动合并/拆分流式更新 快速开始1. 安装依赖包dotnet add package Microsoft.Extensions.AIdotnet add package Microsoft.Extensions.AI.OpenAI
dotnet add package Microsoft.Extensions.Caching.Memory
生产环境推荐使用 Redis:
dotnet add package Microsoft.Extensions.Caching.StackExchangeRedis2. 启用缓存(3 行代码)using Microsoft.Extensions.AI;
using Microsoft.Extensions.Caching.Distributed;
// 创建缓存存储
IDistributedCache cache = new MemoryDistributedCache(/*...*/);
// 启用缓存中间件
var cachedClient = new ChatClientBuilder(baseChatClient)
.UseDistributedCache(cache)
.Build;
核心要点:
使用 ChatClientBuilder构建管道UseDistributedCache一行启用缓存透明集成,无需修改业务代码
3. 验证缓存效果var question = "什么是 Microsoft.Extensions.AI?";// 第一次请求 - 调用模型
var sw1 = Stopwatch.StartNew;
var response1 = await cachedClient.GetResponseAsync(question);
sw1.Stop;
Console.WriteLine($"⏱️ 第一次: {sw1.ElapsedMilliseconds}ms");
// 第二次请求 - 从缓存返回
var sw2 = Stopwatch.StartNew;
var response2 = await cachedClient.GetResponseAsync(question);
sw2.Stop;
Console.WriteLine($"⏱️ 第二次: {sw2.ElapsedMilliseconds}ms");
Console.WriteLine($"✨ 加速比: {sw1.ElapsedMilliseconds / sw2.ElapsedMilliseconds}x");
典型效果:
首次请求: 800-2000ms
缓存命中: 10-50ms
⚡ 性能提升: 10-100 倍高级配置1. 流式响应缓存缓存同样支持流式模式,通过控制行为:var cachedClient = baseChatClient.AsBuilder
.UseDistributedCache(cache, configure: c =>
{
// true(默认):合并流式更新后缓存,读取时再拆分
c.CoalesceStreamingUpdates = true;
})
.Build;
配置
存储方式
适用场景
true合并为完整响应 节省存储,推荐 false保留流式序列 需要精确重放流 2. 生产环境使用 Redisusing Microsoft.Extensions.Caching.StackExchangeRedis;var redisCache = new RedisCache(Options.Create(new RedisCacheOptions
{
Configuration = "localhost:6379",
InstanceName = "MEAICache:"
}));
var cachedClient = baseChatClient
.AsBuilder
.UseDistributedCache(redisCache)
.Build;
Redis 优势:
分布式部署,多实例共享缓存
⚡ 高性能,支持持久化
支持过期策略和内存管理
3. 缓存键分区管理通过创建独立的缓存分区:var productionClient = baseChatClient.AsBuilder
.UseDistributedCache(cache, configure: c =>
{
c.CacheKeyAdditionalValues = new { "prod", "v2", "zh-CN" };
})
.Build;
场景
分区策略
示例
多语言 按语言分区 ["zh-CN"]["en-US"]版本管理 按版本分区 ["v1"]["v2"]环境隔离 按环境分区 ["dev"]["prod"]企业级最佳实践1. 自定义缓存策略继承public class CustomCachingClient : CachingChatClient{
protected override bool EnableCaching(
IEnumerable
ChatOptions? options)
{
// 自定义规则:不缓存包含敏感词的请求
var text = string.Join(" ", messages.Select(m => m.Text));
return !text.Contains("机密") && base.EnableCaching(messages, options);
}
}
2. 何时不应使用缓存? ⚠️ 会话型对话:设置了ConversationId的请求 ⚠️ 敏感数据:包含个人信息或机密内容 ⚠️ 实时性要求:股票报价、实时新闻等 ⚠️ 随机性响应:需要每次生成不同结果3. FAQ 客服系统示例var faqQuestions = new
{
"营业时间是什么?",
"如何申请退款?",
"支持哪些支付方式?",
"营业时间是什么?", // 重复问题
};
foreach (var question in faqQuestions)
{
var response = await cachedClient.GetResponseAsync(question);
// 重复问题自动从缓存返回,响应时间显著降低
}
实测效果:
总请求: 4 次
缓存命中: 1 次 (25%)
⚡ 平均响应时间: 降低 30-50%
API 成本: 节省 25%
⚠️ 注意事项JSON 序列化限制限制项
说明
RawRepresentation不会被序列化 AdditionalPropertiesobject值会变为JsonElement自定义类型 可能无法完整往返建议:如果依赖这些属性,请谨慎使用或实现自定义序列化。
缓存版本管理MEAI 会在序列化格式变更时自动更新缓存版本号(当前 v2),使旧缓存失效,避免兼容性问题。
总结 ✅ 简单集成: 通过UseDistributedCache一行代码启用缓存 ✅ 显著收益: 响应速度提升 10-100 倍,成本显著降低 ✅ 灵活配置: 支持流式/非流式、自定义策略、分区管理 ✅ 生产就绪: 支持 Redis、SQL Server 等企业级存储下一步:探索 MEAI 的 Chat Reducer(消息压缩)和自定义中间件功能,构建更强大的 AI 应用管道。
来源:opendotnet
