这道题问的是长期记忆,其实本质上是问怎么把大模型从单轮对话的“近视”状态,变成能跨会话感知用户上下文。很多团队做[[Agent]],短期记忆靠窗口,长期记忆就简单存个用户画像,但实际落地你会发现,光存画像不够,用户行为是动态的,需要一套分层方案。
我倾向于把记忆分成三层。第一层是工作记忆,就是当前窗口的对话上下文,直接送进模型。第二层是短期记忆,存最近几轮完整的对话记录,按时间序列存,方便回溯。第三层才是长期记忆,这里又可以细分成三类:用户画像,用结构化数据存,比如偏好、习惯;事件记忆,用向量存重要交互片段,比如用户投诉过某个功能;知识记忆,用户专属的知识,可以结合 [[RAG]] 来搞。
具体存储上,用户画像我倾向用关系型或者文档数据库,支持原子更新。事件记忆必须用 [[Vector Database]],同时带上元数据,比如时间戳、主题标签,不然纯向量检索容易跑偏。原始对话压缩归档,定期拿来生成摘要。
检索这块,我不会只用向量相似度。因为用户话题可能漂移,时间越久越不重要。所以我会做多路召回:向量相似度、时间衰减、主题标签过滤,三条路一起走,然后拿一个轻量模型做 [[重排]],比如 [[Cross-Encoder]] 打分,取Top-K。这里有个坑:如果召回太多,重排成本会很高,所以我会先粗筛,控制候选数在几十条以内。
更新策略分实时和定期。实时更新:每轮对话后,用LLM或者规则提取关键信息,增量写到短期记忆,异步更新长期记忆。定期总结:对话结束后触发一个总结任务,生成会话摘要;周期性比如每周,聚合摘要更新用户画像。冲突处理上,我倾向于时间戳优先,新覆盖旧。但如果模型对某个信息的置信度低,我会标记成待确认,不直接覆盖,避免把用户随口一说当作真实偏好。
和大模型协同的方式,就是把记忆拼到输入里。我会用特殊标记区分来源,比如[用户偏好:喜欢简洁回复],让模型知道这是长期记忆。同时控制记忆长度,如果太长,我会先摘要再注入,避免淹没当前上下文。敏感记忆,比如用户纠正过的错误,我会高亮处理,让模型优先参考。
这里其实有个更底层的取舍:长期记忆的更新频率和检索延迟之间怎么平衡。如果用户每句话都实时更新向量库,写入压力会很大;但如果延迟更新,又可能错过关键信息。我倾向的做法是,对高频但低价值的信息做缓冲区,批量写入;对关键事件,比如用户明确表达不满,就立即写入并触发重索引。这个缓冲区的策略,其实跟数据库的写缓冲有点像,但具体阈值怎么设,得看业务场景。
所以整体来说,我不会把长期记忆当成一个静态的数据库,而是看作一个动态的上下文管理问题。核心是分层的架构、多路检索、以及和模型输入的无缝拼接。落地时我会特别关注检索延迟和记忆一致性,如果这两点没保障,记忆再多也是噪音。