第一次真正动手做 AI 记忆系统时,我很快意识到一件事:长上下文不是记忆,RAG 也不是记忆。长上下文像临时摊开的工作台,窗口一关就清空;RAG 像资料室,问得准才能翻得出。真正的外挂记忆,应该介于两者之间:它既要能保存经历,又要能在需要时主动浮现,还要知道哪些内容已经过期、哪些内容会污染判断。
我最初的原型很简单:把用户对话、文档片段、任务结果切成 chunk,生成 embedding,写进向量库。检索时,用当前问题向量召回 top-k,再交给 reranker 排序,最后塞进模型上下文。这个结构看上去像标准 RAG。Lewis 等人在 2020 年提出的 RAG,把参数化知识和非参数化外部知识结合起来,证明检索可以显著增强知识密集型任务表现。但当我把它用于“长期陪伴式 Agent”时,问题立刻暴露出来:系统能查资料,却不会“记得我”。
差别在写入端。
普通 RAG 的核心问题是“如何找回相关文档”;记忆系统的核心问题是“什么值得被写入”。如果把所有对话都存下来,向量库很快变成噪声池:一句临时抱怨、一次已经作废的计划、一个半成品判断,都会在未来某个相似问题里被召回。模型不会天然知道这些记忆的可信度,它只会把它们当成上下文的一部分。于是我给每条记忆加了四个字段:source、time、confidence、scope。来源决定可信度,时间决定衰减,置信度决定是否能直接参与推理,作用域决定它是用户偏好、项目事实、临时状态,还是模型自己的观察。
这时,记忆开始像一个小型操作系统。
MemGPT 的思路给了我很大启发。它把 LLM 的上下文窗口类比为主存,把外部存储类比为磁盘,由模型通过工具调用管理不同层级的记忆。这个类比很准确:不是所有信息都应该常驻上下文。当前任务目标、用户刚刚给出的约束、正在编辑的代码片段,应当进入“热记忆”;历史偏好、长期项目背景、之前踩过的坑,可以放在“冷记忆”;而低置信度推测,只能作为候选线索,不能直接当事实使用。
我后来把记忆系统拆成三条流水线。
第一条是“即时缓存”。它保存当前会话里的短期状态,比如“用户正在写一篇关于 AI 外挂记忆系统的文章,希望有技术细节,风格像工程师测试手记”。这类信息不需要向量检索,应该直接放进会话状态里。
第二条是“语义记忆”。它存储稳定事实和偏好,例如用户常用的技术栈、项目命名习惯、写作风格偏好。它适合用 embedding 检索,但不能只靠相似度。我给它加了 BM25 混合召回,因为很多工程问题依赖精确词,比如函数名、错误码、版本号。DPR 证明了稠密检索在开放域问答中的效果,但工程场景里,稠密向量经常会把“语义相近但实体错误”的内容召回来。混合检索更保守,也更可靠。
第三条是“反思记忆”。这部分最危险,也最有价值。Generative Agents 论文里提到,Agent 会把观察记录转化为更高层次的 reflection,再用于规划行为。我在原型里做了一个类似的 consolidation job:每隔一段时间扫描新记忆,把重复、冲突、过期的信息合并成摘要。例如十几条“用户不喜欢营销口吻”的片段,最终会收敛成一条稳定偏好:“写技术文章时,用户倾向于工程化、克制、少口号。”这条摘要比原始记录更容易被检索,也更不容易超出上下文预算。
但 consolidation 不能让模型自由发挥。我的第一版让模型自动总结记忆,结果它会把偶然行为提炼成长期偏好。用户某天要求“写得犀利一点”,系统就记成“用户喜欢攻击性表达”。这就是记忆污染。后来我加了一个规则:只有跨时间、跨任务重复出现的信息,才能升级为长期记忆;单次事件最多进入临时记忆,并带过期时间。
检索端的工程细节也很关键。
向量库我选 HNSW 索引,因为它在高维近邻搜索里足够成熟:多层图结构先从稀疏高层快速定位,再进入底层精细搜索。实际调参时,M影响图连接密度,efConstruction影响建库质量,efSearch影响查询召回和延迟。外挂记忆系统不是离线搜索引擎,它要插在每次模型回复之前,所以延迟预算非常硬。我给整条检索链路设了 300ms 软上限:向量召回 50 条,rerank 到 8 条,再按 token 预算压缩成 3 到 5 条上下文。
真正让我改变设计的是一次失败测试。
我问 Agent:“继续上周那个数据库迁移方案。”系统召回了三条记忆:一条是上周真实方案,一条是两个月前废弃方案,还有一条是模型自己曾经提出但被用户否定的建议。三条都“语义相关”,但只有一条应该进入上下文。问题不在召回,而在缺少记忆生命周期。
于是我给每条记忆增加了状态机:candidate -> active -> stale -> archived。候选记忆不能直接影响回答;活跃记忆可以进入上下文;陈旧记忆只能在用户明确追溯历史时使用;归档记忆默认不可见。每次新事实写入时,系统会检查是否与旧记忆冲突。如果冲突,不是简单追加,而是生成一条 revision:谁覆盖了谁,依据是什么,什么时候发生。AI 的记忆不能像日志一样只增不改,它必须能承认“我之前知道的是旧版本”。
这也是 A-MEM 这类 agentic memory 研究有意思的地方:记忆不是静态向量集合,而是一个会自组织的网络。它借鉴 Zettelkasten 的思想,让记忆之间形成链接、分类和更新关系。对工程系统来说,这意味着我们不能只问“top-k 召回了什么”,还要问“这些记忆之间是什么关系”。孤立片段适合回答事实问题,网络化记忆才适合支撑长期任务。
测试外挂记忆系统,我现在主要看五个指标。
第一是召回命中率:该想起的东西有没有被找回。第二是引用准确率:找回的记忆是否真的支持回答。第三是冲突处理率:新旧信息不一致时,系统有没有识别并降权旧记忆。第四是记忆污染率:错误、偶然、过时的信息有没有进入长期层。第五是延迟和 token 成本:记忆再聪明,如果每次回复都慢两秒,就很难产品化。
最后我得到一个有点反直觉的结论:外挂记忆系统的难点不在“存得更多”,而在“忘得正确”。
大模型本身已经很会生成,外挂记忆真正补上的不是知识量,而是连续性。它让模型从一次性问答工具,变成能跨会话维护状态的工程实体。但这块外接硬盘不能只是向量数据库。它需要写入策略、检索策略、冲突修订、时间衰减、权限边界和可解释引用。否则所谓记忆,只是把历史噪声重新包装成上下文。
我现在更愿意把 AI 记忆系统看成一层“认知缓存”:热数据进上下文,冷数据进检索库,旧结论等待修订,低可信信息留在隔离区。它不神秘,也不浪漫,更不像人脑。它像一个需要持续压测的基础设施组件。做得好,模型会显得更懂用户;做得差,它只会更自信地记错。
参考素材
- Retrieval-Augmented Generation for Knowledge-Intensive NLP Tasks
- Dense Passage Retrieval for Open-Domain Question Answering
- Improving language models by retrieving from trillions of tokens
- MemGPT: Towards LLMs as Operating Systems
- Generative Agents: Interactive Simulacra of Human Behavior
- A-MEM: Agentic Memory for LLM Agents
- Efficient and robust approximate nearest neighbor search using Hierarchical Navigable Small World graphs
热门跟贴