☰
Engram:为大语言模型构建可读写的长期记忆系统
2026/10/20 23:34:46 网站建设 项目流程

最近圈子里讨论最热烈的新论文,名字叫 Engram。如果你光看标题,大概率会以为这是一篇脑科学或者心理学研究,但它实际上出自国内某 AI 研究机构的大模型团队,讲的是怎么给大语言模型配一套真正可用的“记忆系统”。这个团队此前因为在推理模型上的积累已经刷过一波存在感,所以新论文一出来,我第一时间就从头到尾读了一遍。读完后的判断是:这不是一个简单的上下文压缩技巧,也不是又一个 RAG 变体,而是把神经科学里的“记忆痕迹”概念系统地迁移到了大模型上,试图解决大模型“过目就忘”的顽疾。

这篇文章适合谁?如果你在做大模型应用开发、Agent 编排、长对话场景调优,或者在 RAG 方向反复调试却一直觉得“检索出来是一回事,模型记住是另一回事”,那 Engram 的这套思路值得你逐字拆解。下面我从问题本源、方案设计、核心机制、工程落地和避坑经验五个层面,把这篇论文的脉络完整梳理一遍,你拿去可以直接指导自己的项目改造。

1. 大模型的“金鱼记忆”:上下文窗口救不了所有问题

1.1 上下文窗口扩展的本质是“边上边忘”

这两年各家团队都在卷长上下文,8k、32k、128k、甚至百万级,数字一个比一个大。表面上看,窗口越长模型能“看到”的信息就越多,但实际用下来你会发现一个很尴尬的事实:窗口变长,模型并不会把所有历史都当作有效的“记忆”来使用。注意力机制本身是软性的,远距离的早期 token 在经过深层的归一化之后,注意力权重会逐渐衰减,信息会被中段的干扰内容稀释。

我在实测中见过一次典型的例子:对话进行到第 100 轮,某模型已经把第 3 轮用户明确说过的“金额单位用元,不要用万元”完全忘记了,最后的回答单位全错,而且错得非常自信。这个问题的本质是:Transformer 根本没有“存储”这个概念,它只有“瞬时激活”。上下文窗口只是给模型一个临时可看的舞台,不是让模型把这些信息真正沉淀下来。窗口再长,本质上也只是一次性工作台的面积变大了,而不是模型长了脑子。

1.2 长对话里的隐性遗忘比显性报错更致命

早期模型在上下文过长的场景下会直接报错,那至少你还知道自己遇到了问题。现在的模型基本都能“硬吃”长上下文,但隐性遗忘更隐蔽:它不会告诉你某条历史信息没被记住,而是直接给出一个与历史明显矛盾的回答。我自己在跑一个多轮客服类模拟项目时踩过一次:用户在第一轮说“我对花生过敏,所有推荐都避开花生制品”,中间聊了 40 轮烹饪话题,最后一轮模型推荐了一份含花生酱的食谱,而且语气非常笃定。

这种错误在真实产品里非常危险,因为用户会默认你记得他提供过的重要信息,而当系统给出错误回答时,信任感瞬间清零。隐性遗忘的根源在于所有历史信息在注意力计算中处于“平等竞争”状态,没有优先级、没有持久性标识、也没有定期回顾机制。靠提示词让模型“注意之前提到过的内容”只能缓解几轮,一旦信息量超出工作记忆的承载范围,该忘的还是会忘。

1.3 记忆缺失在 Agent 和 RAG 场景里代价更大

如果你只是在做单轮问答,上下文窗口短一点其实无所谓。但一旦进入 Agent 场景,问题就严重了:多步任务需要多次调用模型,每次调用之间是无状态的,要么靠外部编排框架把全部历史塞进系统提示词,要么让模型“凭感觉猜”。塞提示词的办法短期能用,但框架会把上下文越滚越重,到了第 N 步请求体已经膨胀到影响响应延迟。

RAG 场景表面上看起来有“记忆”——每次检索都会拉回相关内容,但它解决的问题是外部知识获取,不是历史经验复用。RAG 检索到的知识片段,模型并没有内化,下一次遇到同样的问题还是要重新检索、重新理解。Engram 论文瞄准的恰恰是这个空白:它要做一个显式的、可读写、可更新的记忆模块,让模型真正把经验存下来、在需要时主动取出来用,而不是每次都从头开始。

2. Engram 是什么:从脑科学借来的“记忆痕迹”

2.1 “记忆痕迹”在神经科学里的原本含义

Engram 这个词在脑科学里是一个经典概念,中文通常翻译成“记忆痕迹”。它指的是:当个体经历某个事件后,一组特定的神经元会发生持久性的物理或化学变化,这个变化就是记忆得以保留的基质。简单说,大脑并不是把原封不动的画面保存在某个硬盘里,而是通过改变神经元连接强度来“刻录”一段经历。几十年过去,这套理论仍然是记忆研究的根基。

把这个词拿来命名大模型的记忆系统,含义其实很准确。论文作者想表达的并不是“把对话原样存进数据库”,而是“把经历转化为一种能长期影响后续行为的内部状态”。这跟我们平时说的缓存、日志完全是不同层级的概念。缓存是“下次可能用到的原始数据”,记忆是“已经被消化吸收、能改变判断依据的经验”。

2.2 论文对记忆系统提出了四个核心操作

根据我对论文思路的梳理,Engram 的核心是把模型上下文之外的信息组织成一个“记忆池”,并且给这个记忆池定义了四个基本操作:写入、读取、更新、遗忘。这看起来像数据库,但关键在于“语义敏感”。数据库的读写是结构化、确定性的:写入一行记录,查询时按字段匹配。Engram 的读写则是由模型自己判断的:什么信息值得写入,什么旧信息需要更新,什么记忆已经失效需要遗忘,这些决策都由模型在语义层面完成。

这四个操作简单说就是:写入负责把对话中值得长期保存的信息提取并压缩成记忆单元;读取负责在后续对话中按需把相关记忆找回来注入上下文;更新负责处理记忆之间的冲突和过期;遗忘负责控制记忆池的体积,防止无限膨胀。有了这套闭环,大模型才第一次具备了“回顾经验”的能力,而不仅仅是“阅读长文本”。这种设计思路往大了说,是在朝“持续学习”的方向试探。

2.3 这条技术路线和“无限长上下文”是两种哲学

现在业内有一部分人坚信,只要把窗口做到足够长,记忆问题自然就解决了。Engram 的立场显然不是这样。它的潜台词是:上下文窗口再长,也只是一种“工作记忆”,而不是“长期记忆”。人类工作记忆容量非常有限,但我们照样能处理一生积累的知识,靠的是“分层”:重要的信息被固化为长期记忆,临时信息用完即弃。

如果模型每一次推理都得从头把所有历史浏览一遍,计算成本、注意力稀释、信息冗余的问题都会随窗口长度非线性放大。与其在窗口长度上做加法,不如在记忆结构上做乘法。论文选择了后者,这也是我认为它值得认真研究的原因。窗口扩展解决的是“单次会话内能不能装下更多原始信息”,Engram 解决的是“跨会话、跨任务的经验能不能复用”,两者目标并不相同。

3. 方案设计拆解:Engram 的整体架构长什么样

3.1 工作记忆与长期记忆的分层设计

Engram 最基础的设计就是记忆分层。工作记忆对应模型当前的上下文窗口,它保存的是本轮对话的原始 token 和最近几轮的关键信息;长期记忆则是上下文之外的显式存储池,对应经过编码、压缩后的记忆单元。两条记忆路径并行工作:每次推理时,模型先读取长期记忆中与当前问题相关的部分,注入工作记忆;对话进行中,系统不断评估工作记忆里哪些信息值得沉淀到长期记忆,达到条件就执行写入。

这个分层的好处很直接。第一,模型不需要每次都在海量历史里翻找,注意力可以聚焦在“近期上下文 + 相关记忆”这个较小的信息集上,响应质量和速度都有改善。第二,长期记忆不受上下文窗口长度限制,它可以跨会话持续积累。第三,提取和压缩后的记忆单元比原始对话更“浓缩”,单位信息密度更高。我在自己项目里试过类似的思路,哪怕只用很粗的摘要式记忆,多轮 Agent 的最终成功率都能明显提升。

3.2 记忆单元:从“看到什么”到“记住什么”

记忆单元是 Engram 系统里的基本操作对象。一个记忆单元可以理解为一条结构化的语义记录,它包含三部分内容:核心事实(用户偏好、任务约束、关键结论等)、摘要正文(由模型对原始对话片段改写而成的紧凑描述)、元数据(时间、重要性评分、来源话题、当前状态)。这里有一个容易误解的点:记忆单元不是把整段对话粘贴进去,而是由模型判断“这段对话里真正值得长期保存的是什么”,然后进行提炼改写。

为什么不用原始文本?原因很简单:原始对话噪声太多。用户可能用了很长一段话表达一个很简单的偏好,也可能夹带大量情绪化表达和与目标无关的闲聊。如果原样存进去,检索时语义匹配会被噪声干扰,存储空间也被无效内容占据。通过模型改写生成摘要,相当于做了一次“信息提纯”,后续注入上下文时占用的 token 更少,语义也更强。实测下来,同样容量的记忆池,提炼过的摘要方案在检索命中率上明显高于原始文本方案。

3.3 Engram、RAG、上下文压缩,三者怎么分工

我把这三种方案放在同一个表格里对比,你在实际选型时可以直接对号入座:

方案解决的核心问题存储内容操作方式典型场景
上下文压缩单次会话内降本压缩后的历史对话每次按需展开长对话单次会话
RAG外部知识获取文档片段和知识条目检索后注入知识问答、内容生成
Engram历史经验与状态复用语义记忆单元写入/读取/更新/遗忘多轮 Agent、跨会话助手

需要特别说明的是,这三者不是替代关系而是互补关系。Engram 管的是“模型自己的经历”,RAG 管的是“外部世界的知识”,上下文压缩管的是“本次对话的临时降载”。我建议在上手时先不要互相替代,而是组合使用:RAG 负责知识供给,Engram 负责经验沉淀,长上下文兜底近期原始信息。这样各管一段,系统才不会在一棵树上吊死。

4. 核心运作机制:写入、读取、更新、遗忘怎么实现

4.1 写入:怎么判断“这信息值得记住”

记忆系统最容易犯的错误就是“什么都记”。如果每一步对话都变成记忆单元,那记忆池很快就会塞满价值不高的内容,检索效率下降,还容易干扰模型的判断。Engram 的写入环节通常需要经过三层筛选:重要性判断、信息去重、摘要生成。重要性判断可以让模型对候选记忆内容打分,比如 0 到 1 之间,只有超过阈值(一般建议 0.7 左右)才进入下一步。去重是为了避免同一话题不断产生重复记忆,可以通过向量相似度判断是否已有近义记忆,低于相似度阈值就合并或丢弃。摘要生成则是在前两层通过后用专门提示词提炼出简洁、自包含的语义单元。

实操中我强烈建议:宁可漏记,不要乱记。记忆污染修复成本极高,而漏记最多就是少了一点信息,后续还可以通过更多轮次补回来。刚上手时把写入阈值调高一点,跑一段时间观察漏记和错记的占比再逐步下调,是效率最高的调参路径。另外,写入环节尽量用便宜的小模型来处理,主模型每轮调用都很贵,这个环节耗不起大模型的 token。

4.2 读取:怎么把记忆“捞回来”还保证不喧宾夺主

读取环节的核心问题是检索质量和注入方式。Engram 的检索不能只依赖向量相似度,因为用户提问的表述和记忆内容的表述经常存在差异,比如记忆里存储的是“用户住在杭州”,当前提问是“我们公司写字楼附近有没有推荐的餐厅”,单靠向量很难把两者关联起来。实践证明,双路检索是性价比最高的方案:一路靠向量语义相似度召回,另一路靠主题标签或关键词索引召回,两路结果做融合排序。

注入位置同样重要。我在自己的项目里对比过三种位置:放在系统提示词之前、放在系统提示词之后对话开始处、放在最近一轮用户消息前面。实测下来,放在系统提示词尾部、正式对话之前,记忆单元对模型行为的影响最稳定。放在对话尾部容易被当成本轮新内容处理,反而可能与用户消息混淆;放在最前面则可能被模型当成“系统设定”的一部分,权重又太高,模型会过分遵循记忆里的话。记忆单元数量上,单次注入 3 到 5 条比较合适,再多模型容易顾此失彼,回答会变得前后矛盾。

4.3 更新:新旧记忆冲突,直接覆盖是大忌

对话场景里存在大量“信息被推翻”的情况:用户一开始说“周末有空”,后来改口“周末要加班”;用户先定了 A 方案,随后改成 B 方案。如果你把新记忆直接覆盖旧记忆,模型在后续推理中就可能出现不自洽的情况,因为其它记忆单元里可能还引用着旧信息。更稳妥的做法是给记忆加一个状态字段,分三类:active(有效)、superseded(已经被替换)、archived(归档留痕)。每次读取时只把 active 状态的记忆注入上下文。

当新记忆写入时,系统把相关联的旧记忆标记为 superseded,而不是物理删除。这样冲突问题从“消灭历史”变成了“标记历史”,模型拿到的永远是一份自洽的当前状态,而旧状态仍然保留可追溯。这在真实项目里尤其重要,因为如果后面发现用户又改回了原始方案,你还能把旧记忆重新激活,而不是从头记录一遍。实际开发时我通常会在记忆管理模块里加一个“状态变更日志”,记录每条记忆从 active 变成 superseded 的时间和原因,排查问题的时候能省大量时间。

4.4 遗忘:不让记忆池无限膨胀

记忆池如果只增不减,跑几个月之后体积会非常可观,检索延迟和存储成本都会上去。更麻烦的是,旧记忆会与新记忆互相干扰。遗忘机制在 Engram 里不是额外选项,而是必需组件。我的建议是给记忆池设置容量上限,比如最多保留 500 条记忆单元;超限时按“重要性 × 新鲜度”的加权分数做淘汰。同时定期做记忆合并,把多条相似记忆合并成一条概要记忆,保留关键细节、丢弃重复内容。另外可以增加“长期未命中淘汰”:某条记忆如果连续多次检索都未被命中,就把它的状态降级,优先淘汰。

遗忘策略要避免一个误区:不要只按时间淘汰。有些信息即使过了很久依然重要,比如用户的过敏史、公司的核心业务约束。如果纯粹按时间戳淘汰,这些关键信息很容易被误删。我建议在评分公式里把“重要性”权重加大,例如重要性权重 0.6、新鲜度权重 0.4,这样一来即使是很久以前的记忆,只要重要性足够高,就仍然可以留在池子里。

5. 把 Engram 的思路搬进自己的项目:轻量版实操

5.1 先识别:你的项目到底需不需要显式记忆

不是所有项目都适合引入记忆系统。如果你的场景是单轮问答,用户每次对话相互独立,引入记忆反而可能造成“历史信息干扰当前判断”。真正需要显式记忆的场景有几个特征:会话轮次长且状态持续变更(比如客服、导购)、跨会话需要记住用户偏好(比如个人助理)、多步任务需要累积中间结果(比如 Agent 工作流)、或者模型经常在长对话后半段丢失早期关键信息。

你可以先用一个简单测试:在现有系统里连续问五轮,每轮都抛出一个需要后续参考的信息点,看看模型在第 5 轮还能不能完全回忆出来。如果不行,再考虑上记忆层。测试用例可以自己捏造,比如“第一轮说预算不超过三千,第二轮说优先考虑续航,第三轮说颜色只要深色系”,然后第五轮问“给我推荐三款符合条件的”。很多项目在这个测试面前原形毕露,这时候再上 Engram 就有明确的收益预期了。

5.2 轻量实现:模型判断 + 向量库 + 记忆注入

不需要等开源代码落地,你完全可以用现有组件搭一个“简易版 Engram”。整个系统就三块:一个负责判断和提炼的大模型(可以用主模型,也可以单独用便宜的小模型)、一个向量库(本地用轻量嵌入式向量库就行,线上可以用云数据库)、一个记忆注入模块。

大体流程是这样:对话过程中,主模型每完成一轮,判断模块拿到完整对话历史,提取其中值得长期保存的信息,打分后生成摘要记忆;写入向量库的同时记录元数据。下一轮用户提问时,系统先做双路召回,把命中记忆注入到系统提示词尾部,再让主模型生成回答。整个链路不需要改模型本身,不涉及权重微调,纯靠提示词编排就能跑通。我在自己一个客服项目里就是这么干的,把原来 40 轮以上就会失忆的会话体验提到了基本不丢关键信息,改动量只有一个记忆管理模块。

5.3 关键参数与评估方法

给一套可以直接抄的初始参数,你在自己的项目里按这个基线跑,再根据效果微调:

参数建议初始值调整方向
重要性写入阈值0.7漏记多就降低,误记多就提高
检索 Top-K5注入效果差就降低,信息不足就提高
去重相似度阈值0.85记忆重复就降低,合并过度就提高
记忆容量上限500 条存储成本高就降低
主动压缩触发轮数10 轮或上下文达 75%响应变慢就提前

评估方法建议用“回忆测试 + 人工打分”:构造一组包含 10 个关键信息点的模拟会话,对话结束后用 5 个追问问题验证模型能否准确回忆,再对比有无记忆系统的准确率。这个测试跑三轮取平均值,基本能反映记忆层的真实效果。我自己实测,接入记忆层后多轮任务成功率提升约 30% 左右,但这数字取决于场景复杂度,仅供参考。强烈建议你在评估时就把“记忆误伤率”也纳入指标:模型有没有因为记忆而改掉用户当前这句话的真实意图?这个指标比命中率更能反映记忆系统的副作用。

6. 避坑指南:那些写论文时不会告诉你的细节

6.1 记忆污染比没有记忆更可怕

我一直强调:记忆系统最大的风险不是“记不住”,而是“记住了不该记的东西”。一旦错误的记忆进入记忆池,它会在后续所有对话里反复被检索到,并以系统提示词的形式注入每次推理,相当于把错误信息“制度化”了。我见过一个案例:某项目里模型把用户随口说的一句“反正我也不常出差”理解成了“用户常出差”,之后每次推荐场景都按“出差多”来推荐,用户纠正了好几次才缓过来。

解决思路是给写入环节加一道“事实确认”:提炼出的记忆如果包含明确事实性断言,可以先向用户确认,确认通过再写入。虽然多了一步交互,但长期看很值得。另外可以在记忆单元里额外加一个“置信度字段”,置信度低的记忆在注入时用“可能”这类限定词修饰,避免模型把不确切的记忆当成硬约束。

6.2 该记住的偏偏检索不到,多半不是模型的问题

记忆检索失败常见原因有三类:一是记忆单元粒度过大或过小,太粗则包含太多无关细节稀释语义,太细则每条记忆覆盖范围太窄,往往检索不到;二是向量模型和领域文本不匹配,通用向量嵌入模型在特定领域效果可能明显下降;三是缺少主题标签,纯粹靠向量相似度,在口语化和多义词密集的对话里很容易失配。

我的经验是给每条记忆加上来源话题标签,检索时先按标签过滤,再做向量排序,命中率会明显提升。如果检索质量还是不行,试试调整记忆单元的粒度:太粗就拆细,太细就适当合并。可以做一个简单的“检索反向测试”,拿一批已入库的记忆单元去反查它们本应命中的查询,看召回率,这样能快速定位是向量问题还是粒度问题。

6.3 记忆注入位置真的影响结果

这个细节一开始我没在意,后来对比测试才发现差异巨大。把记忆单元直接追加到用户最新消息后面,模型容易把记忆内容误认为用户消息,回答时会直接引用记忆原文,产生很不自然的表达。放在系统提示词后面、正式对话之前,模型才会把记忆当成“背景信息”来参考。同时注意记忆单元的排版,用明确的段落分隔,比如“历史记忆:...”,让模型一眼识别出身份。这些小细节对最终效果的影响,往往比调检索参数还大。

注入时的措辞也有讲究。不要写成“用户居住在城市 A”,而是尽量保持与记忆写入时一致的表述:“用户已明确表示长期居住地为城市 A”。后者带有“已明确”的权重暗示,模型对它的信任度会更高。这个细节属于提示词工程层面,调试成本很低但收益直观。

6.4 别把记忆系统的所有判断都交给大模型

理论上让模型自己判断“什么值得记”很优雅,但成本很高:每轮对话都要额外调用一次模型做提炼和打分,次数多了延迟和 token 开销都会明显上升。我的建议是分层决策:规则的归规则,模型的归模型。像话题名称、时间戳、消息长度这些字段直接程序化处理;只有“这条对话里有没有值得长期保存的信息”这种语义判断才交给模型。如果还想省钱,可以用便宜的小模型来写摘要,主模型只在生成回答时被调用一次。这个优化能让记忆层的运行成本降好几个数量级。

更进一步的方案是加“增量判断”:不是每轮都做全量摘要提取,而是先做一个快速的规则判断——如果本轮对话不包含明显的偏好陈述、事实断言或决策变更,就直接跳过记忆写入环节。我自己的经验是,真实客服场景里大约 60% 的对话轮次根本不产生需要长期记忆的信息,用规则先过滤掉这些轮次,大模型调用量直接减少一半以上。

6.5 记忆系统上线后一定要留“遗忘入口”

用户和真实业务形态都会变,用户可能明确要求“别再推荐某个品类了”,业务方可能要求清理某段时间的记忆。如果你在设计阶段没留好删除和遗忘接口,后面就只能从数据库物理层面硬删,牵连面很广。我在设计时通常会加一个“记忆管理命令”:用户说“忘记我说过XXX”时,系统除了删除实体记忆,还会把相关 tag 置为空,并写入一条抑制规则避免同类话题再次被检索。这个简单的机制能让记忆系统的可维护性好很多。

最后说个人层面的体会。Engram 这篇论文最打动我的地方,不在于它提出了某个炫酷的模型结构,而在于它把“记忆”这件事重新拆成了可设计、可迭代的工程问题。大模型的能力边界当然会继续拓宽,但无论模型多强,“记住用户说过的话、别重复犯错、把经验沉淀下来复用”这些需求永远存在。我也在自己项目里按这套简化思路跑了一个多月,最明显的变化不是回答变好了多少,而是系统突然变得“可解释”了——用户之前说过什么、系统记住了什么、哪条记忆被采用了,每一步都能查得到。这种可控感,比单纯指标提升更让我安心。

如果你正在被长对话失忆、Agent 无状态、RAG 效果不佳这些问题困扰,这篇论文值得你花一个下午认认真真读一遍原文,顺便按上面这套架构搭一个最小原型试试。反正以我自己的经验看,方向是对的,效果是能明显感知到的。

需要专业的网站建设服务?

联系我们获取免费的网站建设咨询和方案报价,让我们帮助您实现业务目标

立即咨询