Microsoft.Extensions.AI 上下文压缩功能详解
概述
Microsoft.Extensions.AI 提供了两种上下文压缩策略,用于解决长对话场景中的token限制问题,通过智能缩减历史消息来保持对话连贯性。
两种压缩策略对比
一、MessageCountingChatReducer(直接计数压缩)
基本配置
csharp
var countingReducer = new MessageCountingChatReducer(targetCount: 3);
var reducingClient = chatClient.AsBuilder()
.UseChatReducer(reducer: countingReducer)
.Build();工作流程
初始化: 设置目标消息数(如保留最近3条非系统消息)
对话模拟: 进行多轮对话,消息列表不断增长
压缩效果:
始终保留系统消息
仅保留最近N条用户/助手消息
删除早期的对话内容
示例输出
text
📤 用户: 我的订单号是多少?
📥 助手: 您的订单号是...
📊 当前消息总数: 3 条
📤 用户: 订单什么时候发货?
📥 助手: 通常在下单后...
📊 当前消息总数: 5 条
...
✅ 压缩前: 13 条消息
✅ 压缩后: 7 条消息(系统+最近3轮对话)二、SummarizingChatReducer(智能摘要压缩)
基本配置
csharp
var summarizingReducer = new SummarizingChatReducer(
chatClient: chatClient, // 需要AI客户端生成摘要
targetCount: 2, // 保留最近消息数
threshold: 1 // 触发阈值
);工作机制
1. 触发条件
text
触发摘要 = (总消息数 - 系统消息) > (targetCount + threshold)示例:
targetCount=2,threshold=1当非系统消息超过 3 条时触发摘要生成
保留:系统消息 + 最近2条消息 + 历史摘要
2. 摘要生成过程
收集旧消息: 获取超过保留数量的历史消息
调用AI总结: 使用聊天客户端生成简洁摘要
重构消息列表:
text
压缩前: [系统消息, 历史1, 历史2, 历史3, 历史4, 最近1, 最近2] 压缩后: [系统消息, 摘要, 最近1, 最近2]
医疗对话示例
原始对话流程
系统提示: "你是一位专业的医疗咨询助手。"
用户: "我最近经常头痛,是什么原因?"
助手: 给出头痛可能原因和建议
用户: "我每天睡眠时间大概5小时..."
助手: 建议保证睡眠
用户: "除了头痛,我还感觉眼睛很干涩。"
助手: 解释干眼原因并建议(触发摘要)
压缩效果
text
📊 初始消息数: 6 条(未触发摘要)
📊 当前消息数: 7 条(已超过阈值 3 条)
✅ 压缩后消息数: 5 条
[系统消息, 摘要消息, 最近2条对话]高级功能:自定义摘要提示词
医疗专用提示词配置
csharp
customReducer.SummarizationPrompt = """
请为以下医疗咨询对话生成简洁的临床摘要(不超过 3 句话):
要求:
- 提取患者主诉症状和时长
- 记录已提供的初步建议
- 保留关键医学信息(用药史、过敏史等,如有)
- 使用专业医学术语
- 不要添加推测性诊断或建议
格式:【患者主诉】症状描述 | 【已知信息】关键背景 | 【初步建议】已给出的建议
""";自定义摘要输出示例
text
📋 压缩后的消息结构:
[系统消息]
[自定义摘要] 【患者主诉】持续低烧3天,体温37.8℃ | 【已知信息】青霉素过敏史 | 【初步建议】多休息、多喝水,监测体温,超过38.5℃需就医
[最近对话1]
[最近对话2]三、技术实现要点
集成方式
csharp
// 方式1:通过Builder集成
var client = chatClient.AsBuilder()
.UseChatReducer(reducer)
.Build();
// 方式2:直接使用Reducer
var reducedMessages = await reducer.ReduceAsync(messages, cancellationToken);压缩时机控制
手动触发: 在合适时机调用
ReduceAsync自动触发: 集成到聊天客户端中,每次对话自动检查
阈值调整: 根据应用场景调整
targetCount和threshold
四、应用场景推荐
适合MessageCountingChatReducer
✅ 短期对话(如订单查询)
✅ 需要完整上下文理解的场景
✅ 资源受限环境
❌ 长期记忆要求高的对话
适合SummarizingChatReducer
✅ 医疗咨询(需要长期病史)
✅ 技术支持(多步骤问题解决)
✅ 教育辅导(渐进式学习)
✅ 任何需要"记住"早期对话的场景
五、性能考虑
六、最佳实践
混合策略: 短期用计数,长期转摘要
阈值调优:
高频交互:设置较高阈值
重要信息:设置较低阈值及早摘要
领域优化: 为不同场景编写专用摘要提示词
监控: 记录压缩率、摘要质量指标
七、注意事项
信息丢失: 摘要可能遗漏重要细节
成本控制: 摘要生成需要额外API调用
一致性: 确保摘要准确反映历史对话
调试: 保留原始对话日志以便问题排查
通过合理使用这两种压缩策略,可以在有限的token预算下,实现更长的、有记忆的智能对话体验。