当前位置: 首页 > news >正文

使用 IChatReducer 进行聊天记录缩减

序言

在多轮对话场景中,随着聊天次数增加,发送给大语言模型(LLM)的上下文会持续膨胀,带来 Token 成本上升与上下文溢出风险。 Microsoft Agent Framework 将这一问题抽象为 Chat Reduction(聊天记录缩减),并通过IChatReducer策略对聊天历史进行统一治理,而不是在业务代码中零散地裁剪或拼接历史消息。

本文基于“客户端本地存储聊天记录(Client-side history)”的典型场景,演示如何使用MessageCountingChatReducer自动限制历史长度,防止上下文无限增长,并观察在“历史被遗忘”后 Agent 行为的变化。


1. 代码关键实现步骤

引入必要的依赖

  • Microsoft.Extensions.AI:提供统一的 AI 抽象(ChatMessageReducer等)

  • Azure.AI.OpenAI:用于连接 Azure OpenAI 服务

  • Microsoft.Agents.AI:Agent Framework 核心能力

配置 Agent 与缩减策略(Reducer)

AIAgent agent = new AzureOpenAIClient( new Uri(endpoint), new AzureCliCredential()) .GetChatClient(deploymentName) .CreateAIAgent(new ChatClientAgentOptions { ChatOptions = new() { Instructions = "你是一位江湖说书人,擅长用幽默、接地气的方式讲笑话和故事。" }, Name = "Joker", // 关键点:自定义 ChatMessageStoreFactory ChatMessageStoreFactory = ctx => new InMemoryChatMessageStore( new MessageCountingChatReducer(2), // 仅保留最近 2 条 非 System 的 ChatMessage ctx.SerializedState, ctx.JsonSerializerOptions) });

组件说明

  • InMemoryChatMessageStore

    • 聊天记录保存在客户端内存中

    • 适用于 Chat Completion / 本地上下文管理场景

  • MessageCountingChatReducer(2)

    • 基于“消息数量”的缩减策略

    • 参数 2 表示仅保留最近 2 条非系统消息( 非 System 的 ChatMessage)

    • 超出部分的历史消息会被自动移除,而不是无限累积


2. 验证缩减效果

通过多轮连续对话,观察聊天记录在 Reducer 作用下的变化。在每一轮调用agent.RunAsync(...)后,读取当前线程中实际保留的聊天历史数量:

AgentThread thread = agent.GetNewThread(); Console.WriteLine(await agent.RunAsync("给我讲一个发生在茶馆里的段子,轻松一点的那种。", thread)); IList<ChatMessage>? chatHistory = thread.GetService<IList<ChatMessage>>(); Console.WriteLine($"\n 聊天有 {chatHistory?.Count} 消息.\n"); // Invoke the agent a few more times. Console.WriteLine(await agent.RunAsync("现在把这个段子加上一些表情符号,并用说书人的语气再讲一遍。", thread)); Console.WriteLine($"\n 聊天有 {chatHistory?.Count} 消息.\n"); Console.WriteLine(await agent.RunAsync("保持刚才的语气,讲一个关于健忘冒险者的轻松小故事,像是在讲笑话一样。", thread)); Console.WriteLine($"\n 聊天有 {chatHistory?.Count} 消息.\n"); // At this point, the chat history has exceeded the limit and the original message will not exist anymore, // so asking a follow up question about it will not work as expected. Console.WriteLine(await agent.RunAsync("接着刚才的氛围,讲一个发生在日常生活里的小乌龙事件,轻松随意一点。", thread)); Console.WriteLine($"\n 聊天有 {chatHistory?.Count} 消息.\n");

对话过程说明

  • 第一轮对话:「给我讲一个发生在茶馆里的段子,轻松一点的那种。」

    • 聊天历史较短,Reducer 尚未触发,历史消息正常累积

  • 第二轮对话:「现在把这个段子加上一些表情符号,并用说书人的语气再讲一遍。」

    • 新消息加入,历史仍在阈值范围内,早期消息仍可访问

  • 第三轮及之后:「保持刚才的语气,讲一个关于健忘冒险者的轻松小故事。」

    • 聊天记录达到缩减条件,MessageCountingChatReducer开始生效

    • 最早的消息被自动移除,chatHistory.Count保持在稳定范围内


3. 演示结果

结果一

结果二

结果三

结果四


4. 技术总结与适用场景

适用场景

  • Client-side history:聊天历史由客户端或应用自身维护(如 OpenAI / Azure OpenAI Chat Completion API)

不适用场景

  • Server-side history(如 Azure Foundry Agents):聊天历史由服务端统一管理,客户端无法直接干预裁剪策略

可扩展性

IChatReducer只是一个策略接口,可扩展更复杂的上下文治理逻辑:

  • TokenCountingChatReducer:按 Token 数量而非消息条数进行缩减

  • SummaryChatReducer:将旧消息压缩为摘要,而非直接删除

小结

  • 聊天历史不应无限增长

  • “遗忘”是一种主动、可控的系统设计

  • 上下文治理应以策略形式存在,而非散落在业务代码中

  • 合理使用 Chat Reduction,可在成本、稳定性与对话效果之间取得更好平衡

源代码地址

https://github.com/bingbing-gui/aspnetcore-developer/tree/master/src/09-AI-Agent/Agent-Framework/15-ChatReduction

http://www.jsqmd.com/news/235596/

相关文章:

  • 批量服务器操作:结合screen命令的高效管理策略
  • Session与Cookies
  • DeepSeek降AI有用吗?实测告诉你真相
  • UE5 C++(22-3生成类对象的函数):template<class R> R* UObject :: CreateDefaultSubobject(FName SubobjName,...)
  • 顶尖AI竟输给三岁宝宝,BabyVision测试暴露多模态模型硬伤
  • 二极管(一)——反向恢复时间
  • 通过Python实现Elasticsearch数据库访问的手把手教程
  • Gerber文件转PCB:新手必看反向流程
  • 结型场效应晶体管JEFT(一)——原理
  • 文档解析结果脏乱差?零样本适配各类格式!这个OCR多模态解析工具相当给力!
  • 《技术领先,市场沉默?专知智库白皮书定制,唤醒企业“沉睡的估值”》
  • 手把手教你排查Multisim数据库依赖项问题
  • 论文AI率从80%降到10%:我的亲身经历和方法分享
  • CANoe中UDS诊断报文发送手把手教程
  • 新一代信息技术 vs 人工智能
  • CANoe中UDS诊断报文发送手把手教程
  • 《不止于报告:专知智库如何用一份白皮书,为“隐形冠军”抢到行业定价权》
  • 快速理解USB-Blaster驱动在Quartus中的配置流程
  • 奇偶校验在异步通信中的应用:通俗解释核心要点
  • 【C++入门】05、复合类型-数组
  • 计及电转气协同的含碳捕集与垃圾焚烧虚拟电厂优化调度(Matlab代码实现)
  • 【企业白皮书定制解决方案】专知智库:将技术资产,转化为行业定义权
  • 双层锚点图哈希(Two-Layer Anchor Graph Hashing)压缩函数实现详解
  • 互补投影哈希(CPH)编码过程详解
  • 《企业战略白皮书服务新定义:从“报告”到“认知操作系统”》
  • Altium中如何创建原理图符号:零基础手把手教学
  • 《认知升维白皮书定制:为什么80%的企业战略,困于20%的旧维度?》
  • 谱回归判别分析(SRDA)预测函数详解与实现
  • 学长亲荐2026TOP10AI论文网站:本科生毕业论文写作全测评
  • 异或门在TTL集成电路中的级联使用技巧:实战案例