Skip to content

短期记忆和长期记忆

短期记忆就是当前对话的上下文,所有的历史消息,system prompt,工具调用结果都在里面,直接存在context window里,llm每次推理都能看到

长期记忆是跨会话持久化的知识,比如用户偏好、项目上下文、过往的决策记录,这些数据存在外部存储里,比如向量数据库、文件系统等,需要的时候注入到context里面

短期记忆的管理策略

context window总归是有上限的,一个复杂的编程任务聊一会,加上工具调用很容易就突破限制,这个时候就要做压缩compaction,常见的有三种

  • 滑动窗口,只保留最近n轮对话,最简单但会丢失早期重要上下文
  • 摘要压缩,让LLM对历史对话生成一段摘要替换原始信息,LangChain的ConversationSummaryMemory就是这个思路
  • 选择性保留,根据消息的重要性打分,重要的原文保留,不重要的压缩或者丢弃

生产环境一般是组合使用,比如system prompt和最近5轮对话原文保留,更早的历史做摘要压缩,工具调用结果只保留关键片段

长期记忆的存储和检索

长期记忆的核心问题是存什么和怎么搜

存储内容一般分为三类

  • 事实性知识
  • 经验性知识
  • 项目上下文,代码结构,技术栈选型记录

检索方式主流是混合检索

  • 关键词检索
  • 向量检索(语义匹配)

两者的结果做rerank

短期记忆到长期记忆的自动转化

一个关键设计模式是Memory Flush(记忆刷盘)

当对话接近压缩阈值的时候,系统先触发一次llm调用,让模型把当前会话中的关键信息(决策、代办、偏好)等,提取出来写到持久化存储里,然后再做压缩

这样即使历史消息被压缩或丢弃,关键信息还能通过长期记忆检索回来

另一种设计是会话结束时自动归档,系统把本次会话内容持久化成记忆文件,实现短期记忆到长期记忆的自然过渡

MemGPT把这个机制做的更极致,它直接让LLM自主管理自己的记忆,模型可以主动决定把什么存到长期记忆,什么时候从长期记忆里检索,什么时候更新或删除旧记忆,本质上把记忆管理也做成工具调用

常见的坑

  • 长期记忆写入太频繁会导致噪音过多,检索质量下降,要做去重和过期清理,比如30天没被检索命中的记忆自动降权
  • embedding模型换了之后,旧的向量全部作废,需要重新索引,生产环境要在记忆数据里同时存原文,方便后续迁移
  • 短期记忆的压缩策略如果太激进,模型可能会出现失忆的表现

context window快满了,如何决定哪些消息要压缩,哪些要保留

  • 最简单的判断就是这条消息对当前任务有没有用,system prompt一定保留,最近3-5轮对话保留,工具调用结果只保留摘要,对于更早的消息,可以让llm去打分,低于5分就丢掉,5-8分的压缩成摘要,8分以上原文保留,LangChain的ConversationSummaryBufferMemory就是类似的思路,维护一个token上限,超了的就把最早的消息做摘要

向量检索召回的内容不相关怎么办,明明存了相关记忆但是搜不到

  • embedding模型的语义理解能力不够,换一个更好的模型,比如维度更高
  • 存储的文本粒度不对,可能粒度太粗了,要做chunk切分,一般500-1000token 一个chunk,带100token的重叠
  • 纯靠向量检索不够,还要加个全文检索做混合检索,BM25对精确关键词检索比向量匹配效果好

MemGPT让LLM自己管理记忆和人工设计记忆管理策略相比,哪个更靠谱

各有适用场景

  • 人工设计的策略确定性强,可控性好,适合生产环境里对可靠性要求高的场景,比如客服系统、企业知识库
  • MemGPT的自主记忆管理灵活性更强,模型可以根据对话内容动态决定什么,搜什么,适合开放域的个人助手场景,但是MemGPT每次记忆操作都要额外消耗token
  • 目前生产环境用的更多的还是人工策略+少量自动化,比如会话结束的时候自动归档,压缩的时候自动提取摘要

如果用户隔了一个月回来继续老项目,怎么帮agent快速恢复上下文

  • 靠长期记忆做冷启动,用户开始新会话的时候,系统先从长期记忆里检索跟当前项目相关的所有记忆条目,按照时间和相关性排序,取top10-20,同时把上一次会话的摘要也加进去
  • 关键是长期记忆存的时候要打好标签、项目名、时间戳、内容类型这些都要有,不然检索出来全是垃圾

最后更新于: