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

对话记忆管理实战,BufferMemory、SummaryMemory、EntityMemory对比

对话记忆管理实战,BufferMemory、SummaryMemory、EntityMemory对比

上一篇讲了记忆系统的基本概念。这一篇我们深入对话记忆的管理。

对话记忆是Agent最常用的记忆类型。用户和Agent一来一回地聊,上下文怎么维护,历史对话怎么管理,Token怎么控制。这些问题的答案,都在对话记忆策略里。

LangChain提供了好几种对话记忆组件,各有各的特点。我们一个一个看,对比它们的优缺点和适用场景。


ConversationBufferMemory

最简单粗暴的记忆方式。把所有对话原封不动地存起来。

fromlangchain_openaiimportChatOpenAIfromlangchain.memoryimportConversationBufferMemoryfromlangchain.chainsimportConversationChain llm=ChatOpenAI(model="gpt-3.5-turbo",temperature=0)memory=ConversationBufferMemory()conversation=ConversationChain(llm=llm,memory=memory)conversation.invoke("我想学Python")conversation.invoke("Python好学吗")conversation.invoke("有什么好的学习资源")# 查看记忆里存了什么print(memory.buffer)

优点是简单。不需要任何处理,原样存取。信息完整,不会遗漏任何细节。

缺点是Token爆炸。对话长了以后,所有内容都塞进Prompt,Token消耗线性增长。聊到50轮,可能一轮调用就要消耗好几千Token。又慢又贵,还会超出模型的上下文长度限制。

适合场景。短对话,几轮到十几轮。调试和开发阶段,需要看到完整的对话历史。对Token消耗不敏感的场景。


ConversationBufferWindowMemory

滑动窗口策略。只保留最近N轮对话,更早的自动丢弃。

fromlangchain.memoryimportConversationBufferWindowMemory# 只保留最近5轮对话memory=ConversationBufferWindowMemory(k=5)conversation=ConversationChain(llm=llm,memory=memory)foriinrange(10):conversation.invoke(f"这是第{i+1}条消息")# memory里只有最近5轮print(memory.buffer)

优点是Token可控。不管聊多少轮,记忆的大小是固定的。不会出现Token爆炸的问题。

缺点是丢早期信息。用户在第1轮说的信息,到第7轮就忘了。如果早期信息很重要,这个策略就不合适。

适合场景。长对话,但每轮对话相对独立,不需要回溯太远。比如闲聊、简单问答。

k值设多大,看你的场景和模型上下文长度。GPT-3.5上下文4097 Token,k设5到8比较合适。GPT-4上下文更长,k可以设大一点。


ConversationSummaryMemory

摘要策略。定期把旧对话总结成一段摘要,用摘要替代原始对话。

fromlangchain.memoryimportConversationSummaryMemory memory=ConversationSummaryMemory(llm=llm)conversation=ConversationChain(llm=llm,memory=memory)conversation.invoke("我叫张三,在一家互联网公司做后端开发")conversation.invoke("我们公司主要做电商,技术栈是Java和Go")conversation.invoke("我最近想转AI方向,在学Python和机器学习")# 查看摘要print(memory.buffer)# 输出类似:# "用户叫张三,在互联网公司做后端开发,公司主要做电商,# 技术栈Java和Go。最近想转AI方向,在学Python和机器学习。"

三轮对话的内容被压缩成了一段摘要。Token大幅减少,关键信息保留了。

优点是Token省。长对话也能压缩成简短的摘要,不会随对话增长而无限膨胀。

缺点是有信息损失。摘要不可能保留所有细节。具体的措辞、语气、细节信息可能会丢。摘要质量依赖大模型的能力。每次生成摘要也要消耗Token。

适合场景。超长对话,需要保留整体脉络但不需要每句话的细节。客服对话、咨询场景。


ConversationSummaryBufferMemory

混合策略。近期对话保留原文,旧对话变成摘要。两个策略的优点都占了。

fromlangchain.memoryimportConversationSummaryBufferMemory# 设一个Token阈值,超过阈值的旧对话会被摘要memory=ConversationSummaryBufferMemory(llm=llm,max_token_limit=200,# 超过200 Token的旧对话会被压缩)conversation=ConversationChain(llm=llm,memory=memory)foriinrange(20):conversation.invoke(f"消息{i+1}:这是一段对话内容,包含一些信息。")# 近期对话是原文,早期对话是摘要print(memory.buffer)

优点是平衡。近期对话完整保留,细节不遗漏。旧对话压缩成摘要,控制Token。既保留了近期的上下文,又不让Token无限增长。

缺点是实现复杂。需要管理原文和摘要的切换,内部逻辑比较复杂。摘要生成也需要消耗额外的Token。

适合场景。大部分需要多轮对话的场景。既能保持近期上下文的准确性,又能控制总Token量。这是我比较推荐的策略。


ConversationEntityMemory

实体记忆。从对话中提取实体信息,单独存储和维护。

fromlangchain.memoryimportConversationEntityMemory memory=ConversationEntityMemory(llm=llm)conversation=ConversationChain(llm=llm,memory=memory)conversation.invoke("我叫张三,在阿里巴巴做算法工程师")conversation.invoke("我老婆叫李四,她在字节跳动做产品经理")conversation.invoke("我们住在杭州")# 查看实体记忆print(memory.entity_store.store)# 输出类似:# {# "张三": "用户的名字,在阿里巴巴做算法工程师",# "阿里巴巴": "用户工作的公司",# "李四": "用户的妻子,在字节跳动做产品经理",# "字节跳动": "李四工作的公司",# "杭州": "用户居住的城市"# }conversation.invoke("我老婆在哪家公司")# Agent能回答"字节跳动",因为它记住了李四这个实体

优点是结构化。实体信息被提取出来单独存储,不会因为对话变长而丢失。查询特定实体的信息很方便。

缺点是只关注实体。实体之间的复杂关系、时间序列信息、非实体的上下文,它不太好处理。实体提取的质量依赖大模型。

适合场景。需要跟踪人物、地点、组织等实体信息的场景。比如个人助手、客户关系管理。


怎么选

对比一下这几种策略。

策略Token控制信息保留实现难度适合场景
Buffer完整最简单短对话、调试
Window丢早期简单长对话、闲聊
Summary有损失中等超长对话
SummaryBuffer较好近期完整较复杂大部分场景
Entity实体完整中等实体追踪

我的建议是,先用BufferWindowMemory,k设5到10。简单有效,大部分场景够用。

如果对话特别长,换成SummaryBufferMemory。近期原文加远期摘要,兼顾效果和Token。

如果需要追踪用户信息、实体关系,加一层EntityMemory。跟其他策略可以组合使用。

记住,这些策略可以组合。比如同时用WindowMemory管理近期对话,用EntityMemory管理实体信息,用向量数据库做长期记忆。组合使用效果更好。


下一篇讲知识库记忆。怎么把对话中的重要信息提取出来,存入知识库,形成长期记忆。

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

相关文章:

  • 本地宝推荐!温州非急救救护车转运联系渠道,全车型按需调配 - 滚动商讯
  • AutowareArchitectureProposal规划模块设计原理:场景选择与轨迹生成
  • PForth vs 传统Forth:为什么这款C实现的解释器更适合跨平台开发?
  • NestJS + Kafka 秒杀系统完整实践总结
  • Voice Builder资源库使用指南:音频文件管理与语音特征提取技巧
  • MoneyPrinterTurbo终极指南:10分钟生成专业级短视频的革命性工具
  • 揭秘NixThePlanet工作原理:QEMU虚拟化与Nix包管理的完美结合
  • B站字幕下载终极指南:3步轻松获取BiliBiliCCSubtitle字幕资源
  • 河北钨钢圆环供应商怎么选认准任丘市恒纳模具有限公司 - 品牌优推
  • 2026 重庆铝合金压铸产业观察:全产业链一体化制造成为新能源零部件核心竞争力 - 市场沸点
  • 从0到1开发macOS命令行工具:dark-mode项目架构与实现详解
  • 警惕!硬盘频繁休眠的危害与hd-idle的安全使用建议
  • 2026石家庄装修公司推荐:新房/二手房装修避坑指南 - 品牌优企推荐
  • MFC框架解析:从消息映射到文档视图,掌握Windows桌面开发核心
  • GetQzonehistory:三步极速备份QQ空间,让青春回忆永不褪色
  • qt生成dump文件并定位异常
  • TrollFools源码解析:深入理解MachO文件处理与dylib加载机制
  • NocoDB数据导出技术解析:架构设计与最佳实践
  • 3分钟找回你的QQ空间青春:GetQzonehistory开源备份工具全解析
  • 保持Teams在线状态:Powershellisfun防止自动变为离开状态的终极技巧
  • 为什么选择RaspberryIO?.NET开发者的树莓派硬件控制利器
  • 终极BitTorrent加速方案:83个公共Tracker实战配置深度指南
  • 同城推荐,德州跨省非急救返乡救护车出租,转运安全保障细则全解读 - 滚动商讯
  • 3步掌握B站直播推流码技术架构:开源工具深度解析
  • 年中更新:曲靖体育赛事救护保障车租赁,跨省重症转院安全护送 - 滚动商讯
  • 2026广州安监电工证考证机构推荐:北区教育规范办学 - 思溯深度专栏
  • Node-rules实战案例:6个示例带你玩转规则引擎在业务场景中的应用
  • f8x 与其他安全工具的对比分析:为什么选择自动化部署
  • Seedance 2.5 多少钱一秒?全网最便宜平台 RunningHub 价格与使用指南 - 生活动态圈
  • 免费网页监控神器changedetection.io:三步搭建你的智能网站监控系统