三层不是技术选型,是按寿命切出来的。切错位置的代价,比模型选错还大。
问一个客服 Agent:"我上次说的那个退款,到哪了?"它答不上来。不是模型不行。是上一次会话的上下文,在窗口滑出去的那一刻就没了。
大多数团队第一次搭 Agent 时都会踩这个坑:以为上下文窗口变大了,记忆问题就解决了。于是把历史对话、用户档案、产品文档全塞进去。跑到第三周,账单先炸,然后效果开始飘——该记的没记住,不该记的占着位置。
2023 年 MemGPT 给的解法很干脆:把 LLM 当操作系统看。上下文窗口是内存,外部存储是硬盘,中间做虚拟上下文管理。这个类比一出来,三层结构就自然浮出来了——主上下文(main context)、召回存储(recall storage)、档案存储(archival storage)。内存里只放正在算的东西,历史和知识按需从硬盘换页进来。论文发在 arXiv,是后来 Letta 的理论源头。
同期还有一条线,来自认知科学。CoALA(Cognitive Architectures for Language Agents)把语言 Agent 的记忆拆成工作记忆加长期记忆,长期记忆又分成情景(episodic,发生过什么)、语义(semantic,世界是什么样)、程序(procedural,怎么做)三类。这个三分法直接借自 Tulving 的经典记忆理论,现在基本是行业公共语言。
这两条线指向同一件事:记忆不该是一个库,而是按"它要活多久"切成层。那问题就变成了——到底切几层,每层放什么?
先看一个数字,感受下不切的代价。LongMemEval 这个专门测长期记忆的基准,给商业聊天助手和长上下文模型出了一份 500 题的卷子,考五项能力:信息抽取、多会话推理、时序推理、知识更新、弃答。在持续交互里,模型的准确率大约掉 30%。不是不能答,是越聊越糊。
所以接下来三章,一层一层拆。判据只有两条:这个东西要活多久?出了事谁负责改?
它只该活几秒到几分钟。放错了,钱和效果一起烧。
第一层就是上下文窗口本身。MemGPT 管它叫 main context,LangGraph 管它叫 thread state,CoALA 管它叫工作记忆——当前决策周期的符号状态。三个名字,一件事:正在算的东西。
它的特点是三个"最":最快、最贵、最不经用。
快,是因为不用检索,直接在注意力里。贵,是因为按 token 计费,每轮都重算一遍。不经用,是因为注意力本身有衰减。长上下文评测里反复出现过同一个现象:放在中间位置的信息,最容易被忽略——开头和结尾反而更牢。这不是玄学,是有专门论文测过的。
那第一层该放什么?三样东西:
不该放什么?全部历史对话,和全部用户档案。这两样都是典型的"看起来该放,其实该沉下去"。一个用户有 200 条历史偏好,每轮都塞进上下文,其中 195 条跟当前问题无关——它们不出力,只出钱。
还有一件事值得单独说:第一层是唯一可以直接被"攻击"的一层。用户输入、网页内容、工具返回的结果,都从这里进来。一条藏在网页里的注入指令,第一步就是污染这一层。后面两层的污染,几乎都是从这一层漏下去的。
它以"天"为单位活着。关键词是快照和压缩。
第一层会滑出去,但用户的预期不会跟着滑。他心里认的是"这次对话里我说过的,你应该记得"。这就是第二层要接的活。
MemGPT 把这一层叫 recall storage——存的是对话历史,可以检索回来。LangGraph 的做法更工程化:checkpointer。官方文档把两类记忆分得很清楚:checkpointer 存的是"图状态快照",作用域是单个 thread;Store 存的是应用自定义的键值数据,跨 thread。前者是短期的、线程级的,后者是长期的、跨线程的。
checkpointer 能干四件事,官方列得很直白:对话连续性、human-in-the-loop、时间旅行、容错。最后两个才是它真正的价值。
设想一个场景。你的 Agent 跑到一半,进程被 kill 了。重启之后,用同一个 thread_id 再问一句——它接着上次的话头往下说,中间的审批节点还在原地等你点确认。这就是"快照"的意思:它不是聊天记录,是可以在任意一步回滚和续跑的状态机。落地实现也很朴素:本地用 SqliteSaver,生产上 Postgres。
这一层最关键的动作叫压缩。对话一定会超出窗口,那就得决定:哪些轮次原样保留,哪些摘要成一段,哪些直接丢。压得太狠,第二层就没用了;压得太松,它跟第一层没区别。
它还承担一个容易被忽略的职责:承上启下。第二层是第三层唯一的原料来源。一次会话里冒出来的新事实、新偏好、新的失败尝试,都得先在这里被记下来、被判断,才可能升到第三层去。跳过第二层直接写第三层,等于让长期记忆去猜。
它以月、年为单位活着。也是三层里唯一会"腐烂"的一层。
第三层要回答的问题是:这个用户是谁,这个世界是什么样,这类活我以前怎么干成的。CoALA 的三分法正好对上:
程序记忆有个很有意思的落地形态。Voyager 在 Minecraft 里让 Agent 学会的技能,是存成可以被直接调用的 JavaScript 函数,再用自然语言描述建索引。也就是说,程序记忆的载体不是一段文字,是一块能跑的代码。这个设计思路后来被大量复用。
底层存哪儿?现在主流分成三派。
| 流派 | 典型代表 | 优势 | 代价 |
|---|---|---|---|
| 向量库 | 常规 RAG、Mem0 | 接入快、成本低、生态成熟 | 关系查询靠相似度,容易"语义漂移" |
| 时序知识图谱 | Zep / Graphiti | 保留时间与关系演化,可解释 | 实现复杂、写入更贵 |
| 事件日志 | 原始会话/工具调用流 | 信息无损、可回溯 | 检索能力弱,需要额外索引层 |
效果差多少,有几组公开数字可以直接看。
Mem0 那篇论文(arXiv:2504.19413)报的是:在 LOCOMO 基准上,相对 OpenAI 内置记忆有约 26% 的相对提升;相对"把全部上下文一次塞进去"的方案,p95 延迟降低 91%,token 成本节省超过 90%。它 2026 年的新一代算法又报了一组:LoCoMo 92.5、LongMemEval 94.4、BEAM(1M)64.1,平均每查询约 6.7k token。
Zep 走的是图这条路。它的核心组件 Graphiti 是时间感知的知识图谱,把记忆维护成情景、语义、社区三层结构。官方给的数字是:在 LongMemEval 上准确率最高提升 18.5%,延迟降低 90%。具体到 gpt-4o——准确率从 60.2% 提到 71.2%,平均延迟从 28.9 秒降到 2.58 秒,只用了约 1.6k token。
图这么贵,为什么还有人用?因为它查的是关系,不是相似度。"这个人的直属上级的部门预算是多少"——这种问题走图遍历是一条明确路径,走向量相似度就是猜。结构化查询上,图的可靠性更强,代价是工程成本。
层切得再对,流动没设计好,三层会互相拖累。
三个动作:写入(往上还是往下)、巩固(层内转化)、唤醒(取回)。
先说巩固。认知科学里有个概念叫记忆巩固:情景记忆会慢慢变成语义记忆——丢掉具体的时间戳,留下抽象出来的知识。周一你在会话里说"我下周三出差",这是情景;三次会话里你都说了类似的话,于是"这个用户经常出差、关心移动端体验"变成语义。前者会过期,后者的保质期长得多。
这个转化过程可以交给模型在后台做。Letta 在 2025 年 4 月提出的 sleep-time compute 就是这个思路:主 Agent 负责实时交互,不编辑记忆;另有一个"睡眠 Agent"在用户空闲时异步跑,整理和重写共享的 memory blocks——抽象模式、消解互相矛盾的事实、预计算可能的关联。因为不在交互路径上,它对延迟不敏感,可以用更大的模型慢慢算。
这个"主 Agent 不写记忆"的约束值得琢磨。它把"用"和"改"分开了。实时路径上模型正忙着答话,此时让它顺手改记忆,既容易写错,也容易被注入影响。挪到后台,多了一层审核的机会。
再说写入的判据。常见做法是给记忆打分,反复出现的事实才升级。粗糙但有效的版本:
最后是唤醒。取回时的核心矛盾是:取少了不够用,取多了等于没分层的白花钱。所以检索一般不会只看向量相似度,还要叠时间衰减——同样是"用户喜欢简洁回复",三天前说的,权重就该比三个月前的高。能被删掉的记忆,比能被存下来的记忆更值钱。
每一层的失败模式都不一样,不能用同一个方案治。
第一层:挤爆和被劫持。挤爆好理解——上下文塞满,关键信息被挤到中间,然后被忽略。被劫持更麻烦:用户输入、网页、工具返回都在这一层进来,一条藏在文档里的注入指令,第一步就是改这一层。它不持久,但每次都能重来。
第二层:串味和带毒持久化。串味是工程事故——thread 隔离没做好,A 用户的会话状态漏给了 B。带毒持久化更值得警惕。有研究(arXiv:2506.17318)专门指出,Web Agent 的记忆可以被篡改,而现实里可行的入口相当平常:没有加密也没有访问控制的客户端存储、第三方云上下文存储、被攻陷的浏览器扩展。
第三层:投毒。这是最需要认真对待的一类。攻击面已经被反复验证:
再回头看 LongMemEval 为什么专门设了两项能力:"知识更新"和"弃答"。因为这两件事最容易崩。知识更新考的是旧事实过期后,Agent 肯不肯用新的——大部分系统的答案是"不肯",旧记忆检索权重更高,两句话在库里并存,模型每次随机挑一句。弃答考的是记忆里没有时,Agent 会不会编——检索失败时硬答,是比检索不到更糟的结局。
切层的判据只有两个,但大多数团队两个都没问。
回到最开始那个问题:Agent 的记忆该存在哪三层?
答案是按寿命切——第一层装正在算的(秒级),第二层装这次对话的(天级),第三层装跨会话的知识(月年级)。分界线不是技术,是"这个东西要活多久"。
但只有寿命这一个维度还不够,还得加第二个:出了事谁负责改。第一层随时可弃,改错了不影响明天;第二层可以回滚到任意快照;第三层写错了会一直待在那里,被系统当成事实用。所以第三层的写入必须最慢、最保守,宁可少记,不可错记。
三层里最反直觉的一点是:第三层的价值不在于能存多少,而在于敢删多少。一个不设过期、不做过期校验的长期记忆库,用半年之后,检索出来的内容会比不用还糟——它会把半年前的正确结论和三个月前的错误结论一起端上来。
留一个实在的问题:你的 Agent 答错的时候,你能说清是这三层里哪一层出的问题吗?说不清,说明边界还没划出来。