本文为翻译转载。
- 原文标题:The components of agent memory
- 作者:Lance Martin(Anthropic)
- 原文链接:https://www.anthropic.com/research/components-of-agent-memory
- 发布方与日期:Anthropic Engineering,2026 年 11 月 6 日
克尔凯郭尔(Søren Kierkegaard)写道,生活只能向后理解,却必须向前去过。在为 AI Agent 设计记忆时,我们也遇到了类似的困境。
人类在生活中时时刻刻都在编码记忆。海马体在其中扮演核心角色,它在当下捕获经历,让记忆迅速形成并立即可用。但只有一部分经历会被巩固为长期知识。
这种巩固大多似乎发生在大脑"离线"的时候。在睡眠和安静休息时,海马体会重放我们近期的经历。人们认为,这一过程会逐渐提炼这些经历,并把它们整合进新皮层——也就是存储我们通常所说的"知识"的那部分大脑。
Agent 的记忆也可以采用类似的分工。Agent 会把大部分工作记录在日志或对话记录(transcript)中。Letta 和加州大学伯克利分校的研究者提出了睡眠时计算(sleep-time compute),让模型利用交互之间的空闲时间重新组织已有上下文。同样的思路也能帮助 Agent 组织记忆:通过回顾日志来修正错误,或产出新的笔记和表示。这个过程通常被称为做梦(dreaming)(图 1)。
我们发现,做梦是帮助 Claude 拥有有效记忆的一个有用工具。在这篇文章中,我们会分享我们如何看待 Agent 记忆,并介绍我们用来探索 Agent 记忆的几项评测,包括对做梦的使用,以及每个组成部分对记忆组织各有什么贡献。
图 1:Claude 可以通过做梦来组织记忆。这可以纠正错误、创建笔记、构建新的记忆表示,或者决定预先加载到未来会话中的内容。
记忆笔记
我们所说的"Agent 记忆",是指 Claude 从经验中获得的知识——包括与用户的交互和被分配的任务——并在会话之间保留下来,以可供日后读取的上下文形式保存。它不包括模型学习或管理上下文的其他方式,例如权重(训练中设定的内部参数)的变化、上下文学习(in-context learning)(在单次对话中获得的知识),以及压缩(compaction)(由 Claude 撰写、用来替换较早轮次的摘要,以便它能在新的上下文窗口中继续工作)。
在人脑中,在一段经历之前、之中或之后释放的化学信号可以把一段记忆标记为重要。被标记的记忆在离线期间往往比未被标记的记忆重放得更频繁。这个被称为*重放(replay)*的过程,有助于让它们稳定下来并整合进长期记忆。
类似地,Claude 可以在会话日志中实时标记显著(salient)事件,让它们日后更容易被找到;也可以把它们写入记忆存储,比如一个存放记忆笔记的文件夹(图 2)。但在还不知道接下来会发生什么的时候,Claude 怎么能判断当下什么是显著的呢?
图 2:Claude 可以把笔记写入记忆。
记忆可以是对未来需要什么的预测
记忆有时就是一种预测。Agent 写下一条规则,就是在预测它所描述的模式会再次派上用场。比如,写下一条经过验证的事实,就是预测未来某次会话中的 Agent 会想要直接依赖这条事实而无需再次核对。随着时间推移,Claude 在做这类预测方面已经进步了很多。
来看 Continual Learning Bench(CL-Bench)1.0 中的一项任务。这个基准衡量 Agent 利用记忆完成长周期任务的能力。其中一项任务要求 Claude 通过查询数据库来回答一系列问题。Claude 每给出一个答案,就会被告知正确答案,并且可以写下一条记忆来帮助回答后续问题。
在这里,记忆可以支撑一个学习循环。如果 Claude 答错了,它可以记录这次失败,提出关于错因的理论,检验这些理论,再把发现转化为一条关于以后如何作答的规则。
我们使用 Claude Managed Agents 运行了 CL-Bench 1.0 任务。Claude 回答每个问题时都从一个全新的会话开始,只有一个例外:它可以从一个在会话之间持久保留的记忆目录中读取文件。
不同模型在建立自身学习循环上取得的成功程度不同。Claude Sonnet 4.6 做到了针对答错的原因提出理论。它的记忆目录里散落着一些文件,每个文件都列着几条未经检验的猜测。
图 3:CL-Bench 数据库任务,在各模型上对比使用记忆与无状态基线。
Claude Opus 4.7 把笔记整合进一份参考文档,并开始标注哪些事实已核实、哪些尚未确认。Claude Sonnet 5 会在评分器核对后把每个答案标记为已确认,并在答错时写下更正。
Claude Opus 5 是这些模型中第一个闭合这个循环的。它的大部分条目都包含一条规则(以及它如何得知这条规则成立)、之前问题的答案,以及它一路上发现的陷阱的明确警告(图 3)。
和 Opus 5 一样,Claude Opus 5.5 和 Claude Sonnet 5.5 也都闭合了循环,用记忆记录经过验证的、关于如何更好地回答后续问题的规则。使用记忆时,二者的得分与 Opus 5 大致相当,不过它们在不使用记忆时的基线表现略高一些。
Claude 学会了判断显著性
我们还评估了 Claude 玩《宝可梦 红》(Pokémon Red)的能力。这个游戏要求 Claude 应对复杂的长周期任务,我们用它来检验 Claude 在该往记忆里存什么上的判断力。每次运行开始时,我们都给模型一个记忆文件夹,它在游戏过程中可以读写这个文件夹(图 4)。
我们比较了 Claude Sonnet 3.7 和 Claude Fable 5 各一次运行中的记忆文件夹,当时两者都进行到游戏的大约第 10,000 步。我们注意到一个关键差异:两个模型认为值得记住的东西不同。Sonnet 3.7 认为一切都可能有用,不加区分地往记忆里写。它的记忆文件夹里是一份遭遇档案,常常为它打过的每一场战斗、找到的每一件道具、遇到的每一个非玩家角色单独建一个文件。最终,Sonnet 3.7 在 225 个文件夹中写下了 413 个记忆文件,获得了一枚徽章(徽章标志着玩家在游戏中的进度)。
相比之下,Fable 5 在两个文件夹中写了九个文件,外加一个名为 global.md 的顶层文件,获得了四枚徽章。
图 4:玩宝可梦时,Sonnet 3.7 与 Fable 5 的记忆目录对比。
Sonnet 3.7 的做法之所以成问题,主要是因为宝可梦的游戏状态一直在变——Sonnet 3.7 的详细记录不断过时。结果,随着游戏推进,Claude 不得不把更多时间和资源花在翻找记忆上,而不是玩游戏。比如在第 10,000 步左右,Sonnet 3.7 开始建立第四个"主"记忆文件夹。在接下来的 17 步中,它创建了六个文件,删除了九个,而在游戏里一个动作都没做。
Fable 5 则用记忆来记那些游戏没有明确告诉它的东西。Sonnet 3.7 写入记忆的某些信息——比如玩家有多少钱、玩家在地图上的位置——每回合都可以直接从屏幕上读到,存下来是多余的。相反,关于策略、计划和经过检验的规则的记忆文件,只有 Claude 自己推导出来才会存在,而且除非 Claude 把它们写下来,否则就会消失。
Fable 5 也据此组织记忆。它的 global.md 文件相当于一个仪表盘,存放着当前目标、一份预先写好的挑战道馆(赢取徽章的关卡)计划,以及模型自己制定的记忆使用规则。locations 文件夹存放特定路线的导航计划,gameplay 文件夹存放基于它对游戏机制理解的策略。例如,在连续七个精灵球都没能捕获一只鲤鱼王(最容易捕获的宝可梦之一)之后,Claude 写道:“If 3+ balls fail in a row, VARY the timing (insert extra ‘wait’ presses between menu steps) - the catch landed right after doing this."(如果连续 3 个以上精灵球失败,就改变时机(在菜单步骤之间插入额外的"等待"按键)——这样做之后马上就抓到了。)
凭借小得多的记忆文件夹,Fable 5 在游戏中的进展远远超过了 Sonnet 3.7。Opus 5.5 采取了类似的做法:它维护一个小小的记忆笔记文件夹,记录当前目标和下一步,在游戏过程中不断改写,最终通关了游戏。
引导 Claude 写记忆
我们发现,告诉 Claude 记忆是用来做什么的会有帮助,但不要告诉它怎么用。在 CL-Bench 上,我们只是告诉 Claude 有一个记忆文件夹可用。这种笼统的指引就足以让 Opus 4.7 和 Opus 5 有效地使用记忆,并让二者的表现都有明显提升(图 3)。
我们还测试了给模型设定具体规则,规定它们应该往记忆里写什么,每次测试一条规则。我们比较了每个模型在有该规则和无该规则时从记忆中获得的增益。当我们设定"只记录失败"这条规则时,Opus 5 和 Opus 4.7 都失去了记忆带来的大部分性能提升(图 5 右)。对于更强的模型,让它们自由判断显著性,比事先设定固定规则更有效,而那些规则最终可能反而削弱表现。
图 5:左:Sonnet 4.6 在 CL-Bench 数据库任务上,有无提示词引导记忆使用的对比。右:被要求只记录失败时,每个模型从记忆中获得的增益发生了多大变化。
我们还注意到,引导对较老的模型帮助最大。例如,Sonnet 4.6 常常不读取记忆目录里的文件,也没有去检验它关于答错原因的理论。
在这种情况下,提示 Claude 在作答前先读记忆文件——然后明确检验自己的理论——几乎让它的基准分数翻了一番(图 5 左)。Sonnet 5 会自发这样做。在没有提示的情况下,它在 10 次中有 9 次会在作答前读取记忆。相比之下,Sonnet 4.6 这样做的比例不到一半。
对于前沿 Claude 模型,我们通常只给出简单的指引:在用户要求时,或在某件事明显值得记住时创建记忆笔记,而把判断留给 Claude。
做梦可以纠正记忆
由于 Claude 是根据会话中自己判断为显著的内容来写记忆的,一条从一开始就错了、或者随着环境变化而逐渐失准的笔记,可能会在之后的会话中被 Claude 读到并信以为真。
做梦为 Claude 提供了一种方式,让它对照原始对话记录来检验自己的笔记(图 6)。我们在 Claude 使用 Managed Agents、挂载一个记忆目录来玩宝可梦时,看到了一个正面例子。
图 6:做梦可以纠正记忆中的错误。
在游戏的某一段,玩家需要穿过月见山(Mt. Moon),这是一个洞穴系统,入口在地图西侧,出口在东侧。入口附近有一个陷阱:一道单向的台阶,会把玩家摔回来时的那条道路,而且没有明显的办法爬回去。Claude 把山口处的一座建筑——宝可梦中心——当作地标,因此它会不会走下台阶,取决于它认为宝可梦中心在山的哪一侧。
某一时刻,Claude(错误地)记下宝可梦中心在东侧。当它走出宝可梦中心时,它宣布"Mt Moon is behind me”(月见山已经在我身后了),并更新了笔记:“Mt Moon DONE”(月见山已完成)。但月见山并不在它身后。几个动作之后,Claude 走下了台阶,落回到它来时的道路上(图 7)。它的导航工具没有显示这个落差,于是 Claude 得出结论"I overshot far west"(我往西走过头了很多),并认为自己一直都在正确的一侧。其实并没有。
图 7:一条被纠正的记忆笔记改变了宝可梦中的结局。使用未纠正的笔记时,Claude 说 “Mt Moon is behind me”,朝下一座城市走去,结果回到了来时的道路上。使用经做梦纠正的笔记时,它说 “Now I need to find the Mt Moon cave entrance to re-enter”(现在我需要找到月见山洞穴入口重新进去),并返回了洞穴。
接着我们测试了做梦能否帮助 Claude 避开这个陷阱。我们对那个记着错误宝可梦中心位置的记忆文件夹运行了做梦:Claude 对照会话记录检查这条笔记,发现了自己的错误并改写了它。对话记录为 Claude 提供了验证记忆的事实依据(ground truth)。有了纠正后的记忆笔记,Claude 径直回到了月见山,最终抵达了华蓝市(Cerulean City)。
在使用未纠正笔记的那次运行中,Claude 三次摔回到之前那条道路上。第三次失败后,Claude 似乎放弃了,写道:“I’m going to stop rather than keep looping."(我要停下来,而不是继续兜圈子。)我们实验设置中的自动回复指示它继续。于是它继续了,一路退回到山前的那座城镇——尼比市(Pewter City),希望在那里回复体力、补充物资。这次运行结束时,Claude 始终没能到达华蓝市。
图 8:做梦纠正了记忆,Claude 返回洞穴并抵达下一座城市。使用未纠正笔记的运行(“原始记忆”)始终没能越过这座山,无记忆的运行也没有。
做梦可以构建新的记忆表示
借助做梦,Claude 可以构建帮助导航记忆的表示(图 9)。它使用的一种记忆表示叫作 wiki:一组由 Claude 撰写和维护的页面,汇集 Claude 对某个主题的了解,并链接到其他笔记。这些链接实际上为 Claude 提供了一张地图,让它可以在记忆中筛选,并在需要时高效地定位记忆。
图 9:做梦可以构建记忆表示。
wiki 这样的表示可以帮助 Claude 遍历它不断增长的知识库。我们使用一个内部文档语料库探索了 wiki 作为记忆表示的好处——这些文档来自我们在 5 月收购的软件公司 Stainless,约 350,000 个文件,大约 4.2 亿 token。我们针对这个语料库建立了一个包含 25 个问题的评测集,并给 Claude 一个搜索工具来探索它。我们还指示 Claude 通过做梦基于这些文件构建一个 wiki。在 128 次会话中,我们提示 Opus 5 Agent 探索文件、撰写或修正相互链接的 wiki 页面、合并重复内容,并对照来源核查各项陈述。
每次会话都建立在之前会话中 Agent 取得的进展之上,并通过一个共享日志来协调工作。当我们把做梦从 2 次会话扩展到 128 次时,在这 25 个问题上的表现从满足 13% 的评分标准提升到了 48%(图 10)。
Claude 是增量地构建 wiki 的。在创建初始 wiki 之后,它会在后续轮次的做梦中对其进行补充、编辑或删减。在做梦的早期轮次,Claude 的知识就像一名新员工,仅凭 wiki 回答问题的能力有限。它做梦越多,它的知识地图就越丰富,就像一名资深员工。在我们的测试中,我们发现当同时给 Claude 一个搜索工具时,wiki 对它的帮助最大。当同时使用搜索和 wiki 时,随着 wiki 的增长,Claude 的总分从 54% 上升到 61%,而只使用搜索工具时为 53%。只用 wiki 回答问题时,Claude 的最好成绩是 48%。同时使用搜索和 wiki 还让每个问题节省了约 20,000 个 token。
图 10:中:随着 Claude 在连续会话中构建 wiki,在关于某公司文档语料库的 25 个问题上的得分。左右两侧:一个示例 wiki 在 2 次和 128 次会话后的样子;每个点是一个页面,连线连接互相链接的页面。
我们想测试哪些类型的任务能从 Claude 拥有 wiki 中受益。为此,我们使用了 Harvey LAB 基准以及一组关于一起并购的文档。该基准给 Claude 一组文档,要求 Claude 根据其内容撰写一份法律简报(brief),然后按照一份标准清单为简报评分。也许这比宝可梦通关少了那么一点趣味,但这些评测为我们提供了多样化的文档集合来构建 wiki。
我们指示 Claude 根据这些文档构建 wiki。然后,我们让 Claude 分别基于 wiki 和直接文件搜索来回答问题(关于这起并购)或生成法律简报(LAB 基准)。其中一项测试就这起并购提出了 24 个问题(图 11 左),其中超过一半需要 Claude 跨多份文档查找信息,很多还需要 Claude 进行判断或计算。在这些题目上(红线和橙线),Claude 参考 wiki 时得分 87%,只用搜索时为 73%。
图 11:每个面板左侧列出评分项,右侧列出满足每一项所需的来源文档。左:关于一起并购的 24 个问题,主要可以通过查看公开文件来回答。超过一半的标准需要综合多份文档的信息。右:一项 wiki 没有显示出明显收益的 LAB 任务。大多数标准都能从单份文档中满足。
在其他情况下,wiki 的用处没那么大。在一项 LAB 任务中(图 11 右),简报的评分标准往往可以通过文本搜索从单份文档中找到,与搜索相比,wiki 没有带来明显的性能提升。在另一项 LAB 任务中,wiki 变得比文档本身还要大(图 12)。就像博尔赫斯(Borges)的一段式短篇小说《论科学的精确性》(“On Exactitude in Science”)中的制图师——他们绘制的地图详细到与它所代表的帝国一样大——Claude 做出了一个极其详细、实际上什么也没有抽象出来的 wiki。
图 12:wiki 变得比原始文件还大。
做梦可以把笔记提升到记忆层级的上层
做梦还可以把笔记浮升到记忆层级的顶端,Agent 运行框架(harness)可以在每次会话开始时把它们预先加载进 Claude 的上下文中(图 13)。这意味着 Claude 不需要去搜索它们,甚至不需要知道有东西可搜。
把记忆提升到新会话中(一种上下文注入(context injection))必须谨慎。注入的记忆会占用宝贵的 token,而一条错误的笔记可能被带进每一次会话。加载一条笔记也不能保证 Claude 会按它行事:我们关于 Claude Code 的文档提醒,更长的指令文件会降低遵循度。因此,记忆层级的顶层必须保持相对较小,而做梦在这里的大部分工作就是维持这一点——把一些细节下移到层级的下方,并在原处留下链接。
Claude Code 的自动记忆(auto memory)也以同样的方式保持注入层的精简,只不过是由 Claude 在会话期间维护的。Claude 不会把它全部的自动记忆加载到每次会话的上下文窗口中。它只加载 MEMORY.md 的前 200 行或前 25 KB。这个开头部分充当索引,向 Claude 展示它知道什么以及在哪里可以找到。
图 13:做梦可以写入记忆层级的顶层。注入上下文会被加载到每一次会话中,而下面的各层则在 Claude 需要时被读取或搜索。
做梦可以让记忆聚焦于特定目标
做梦还能塑造记忆增长的方式。例如,像 Claude Duet 这样的助手,往往受益于围绕它所帮助的人来组织记忆,而做梦可以被调校为服务于某个特定目标来构建记忆。
指导记忆如何增长的指令因任务而异,它们告诉 Claude 哪些信息真正重要。例如,LAB 基准中的一项任务模拟了一次公司收购,并提供了一组合同。简报的评分依据是它是否正确描述了合同条款。
我们一开始使用的是生成 wiki 的基础指令,并没有告诉 Claude 如何使用 wiki。这项任务高度依赖合同条款。在构建 wiki 的过程中,多个 Agent 同时向一张共享的合同条款表写入内容(图 14 左)。
图 14:指令修改前后,有多少条被评分的合同事实进入了 wiki。左:多个 Agent 写入同一个共享页面;57 条事实保留下来 41 条。右:每份合同一个 Agent,各自写自己的页面并逐字引用条款;57 条事实全部保留。
结果得到的 wiki 缺失了关键事实。当我们为基于这个 wiki 生成的简报评分时,Claude 只纳入了 57 条事实中的 41 条(72%)。检查问题出在哪里时,我们发现那张共享表格对合同条款的概括很差,有些条款甚至完全缺失,原因是 Agent 们相互覆盖了彼此的工作。
合同条款是这个 wiki 中最重要的部分,但指令里没有说明这一点。为了找到更好的指令,我们运行了一个循环:Claude 反思自己的失败,提出对指令的修改,然后重新构建 wiki。这个循环让 Claude 发现了严格依照合同条款有多么重要,并相应地改写了构建 wiki 的指令。
每份合同在 wiki 中都有了自己的页面,由单个 Agent 撰写,逐字引用条款,而不是把它们概括进一张共享表格。当我们为基于改进后 wiki 生成的简报评分时,100% 的标准都能被满足,高于之前的 72%。
做梦可以填补单次会话留下的空白
Claude 写记忆笔记时,它只能看到那一次会话的上下文。做梦可以跨越多次会话进行搜索,找出共同模式或纠正常见错误。
在为 LAB 基准构建 wiki 时(示例见图 14),Claude 有时会链接到尚未创建的页面。第二轮做梦弥补了许多这样的空缺。在一项任务中(图 15),做梦发现 wiki 中有九个链接指向一个不存在的页面,并把它们重新指向了同一文档的一个已有页面。它还新增了三个页面,包括一个索引,以改进这个 wiki。
图 15:第二轮做梦前后的 wiki。
向后思考,向前展望
关于如何为 Agent 设计记忆系统,还有许多悬而未决的问题。其一是 Claude 应该在什么时候创建记忆。当 Claude 处理任务时,它可以写入记忆存储(例如文件夹、文件或数据库),在源头捕获显著性,让重要细节在后续轮次或会话中立即可用。但当场记录笔记不可避免地会分散 Claude 对主任务的注意力。相比之下,做梦可以把记忆的创建推到后台进行,但做梦的产出可能无法立即被 Claude 访问。
另一个问题是如何让记忆可靠地保持最新。Claude 可能做出错误的预测,或者把从一开始就错误的规则写进记忆。随着环境变化,记忆也可能失准、变得无关。做梦是修正这些错误的一种方式(图 8),但它需要算力。指示 Claude 持续检查它的所有记忆可能并不现实。更重要的或许是让做梦聚焦于可能发生变化的信息,或者仔细调整做梦的频率(例如根据记忆被访问的频率)。
把对话记录搜索作为 Claude 记忆的基础,也是一个合理的考虑。把表示(例如 wiki)与搜索结合起来(图 10)有时会很有效。但 Claude 需要投入算力来维护记忆表示,并确保其中不会累积错误或幻觉。
尽管 Claude 对显著性的判断已经有所提升,但没有任何模型能真正知道未来的轮次中会发生什么。做梦给了 Claude 一个向后看的机会,让它用算力来组织记忆、纠正错误,并维护那些能让未来会话更方便地访问记忆的表示。记忆系统会随着 Claude 能力的提升而演进,而在设计 Claude 的记忆系统方面,我们还有很多需要学习的地方。
参见我们的 cookbook:开始使用做梦和知识 wiki。
致谢
本文由 Lance Martin 撰写,Caitlin Love、Tom Chivers、Rebecca Hiscott、Jake Eaton 和 Blake Wilson 提供编辑指导。感谢 Barry Zhang、Theodora Chu、Daliang Li、Mahesh Murag、Jake Noble、Ravi Trivedi、Tina Vachovsky、Brad Abrams、Henry de Valence、Jeremy Fox、Matt Bell、Allen Li、Chris Gorgolewski、Eugene Yan、Artur Renault、Wei Zhang 和 Kevin Chen 提供的有益讨论与贡献,感谢 David Hershey 的 Claude Plays Pokémon 项目。插图由 Monika Tuchowska 绘制。
关于
关注我获取更多资讯