Anthropic 拆解 Claude 智能体记忆的组成:笔记、显著性判断与 dreaming
The components of agent memory
Anthropic 发布研究文章,介绍其设计 Claude 智能体记忆的思路与多组评测,包括会话内写记忆笔记、离线 dreaming 整理记忆和 wiki 表示。
Anthropic 结合 Pokémon、CL-Bench 和 wiki 实验拆解了智能体记忆的组件与取舍,dreaming 修正错误笔记的具体案例可迁移到自己的记忆系统设计。
克尔凯郭尔曾写道,生活只能向后理解,却必须向前过。我们在为 AI 智能体设计记忆时,也遇到了类似的困境。
作为人类,我们在日常生活中无时无刻不在编码记忆。海马体在其中扮演核心角色,它把当下的经历捕捉下来,让记忆快速形成、随时可用。但只有部分经历会被巩固为长期知识。
这种巩固大多发生在我们的大脑“离线”时。睡眠期间以及安静的休息时段,海马体会重放近期的经历。人们认为,这一过程会逐渐提炼这些经历并将它们整合到新皮层——我们大脑中储存大部分所谓知识的部分。
智能体记忆也可以采用类似的分工。智能体会把大量工作记录在日志或对话记录中。Letta 和 UC Berkeley 的研究人员提出了睡眠时计算,让模型利用交互之间的空闲时间重新组织已有的上下文。同样的思路可以帮助智能体整理记忆:通过反思日志来修正错误,或生成新的笔记和表征。这一过程常被称为做梦(图 1)。
我们发现,做梦是帮助 Claude 获得有效记忆的一个有用工具。在本文中,我们分享自己对智能体记忆的思考,并介绍我们用来探索智能体记忆的若干评估,包括做梦的用法,以及每个组成部分对记忆组织有何贡献。
记忆笔记
我们所说的“智能体记忆”,是指 Claude 从经验中获得的知识——包括与用户的交互以及被分配的任务——并在会话之间保留下来,保存为日后可读取的上下文。它不包括模型学习或管理上下文的其他方式,例如改动权重(训练时设定的内部参数)、上下文学习(单次对话中获得的知识),以及压缩(Claude 撰写的摘要,用来替换较早的轮次,以便在新的上下文窗口中继续工作)。
在人脑中,经历之前、之中或之后释放的化学信号可以把某段记忆标记为重要。被标记的记忆在离线时段往往比未被标记的记忆更频繁地被重放。这一过程称为重放,有助于稳定记忆并将其整合进长期记忆。
同样,Claude 可以在会话日志中把显著事件实时标记出来,方便日后查找,也可以把它们写入记忆存储,例如一个存放记忆笔记的文件夹(图 2)。但 Claude 如何在当下、在还不知道接下来会发生什么的时候,判断什么才算显著?
记忆可以是对未来需求的预测
记忆有时是一种预测。智能体写下一条规则,就是在预测它所描述的模式日后还会派上用场。例如,写下一条经过验证的事实,就是在预测未来某个会话中的智能体会想直接依赖这条事实,而不必再次核实。随着时间推移,Claude 在这类预测上已经进步了很多。
以 Continual Learning Bench (CL-Bench) 1.0 中的一项任务为例。这个基准用来衡量智能体借助记忆完成长程任务的能力。其中一项任务要求 Claude 通过查询数据库来回答一系列问题。Claude 给出答案后,会被告知正确答案,并且可以写一条记忆,帮助回答之后的问题。
在这里,记忆可以支撑一个学习闭环。如果 Claude 答错了,它可以记录这次失败,提出关于错因的猜想,验证这些猜想,再把验证结果总结成一条今后答题的规则。
我们用 Claude Managed Agents 跑了 CL-Bench 1.0 的这项任务。每道题 Claude 都在全新的会话中开始,只有一个例外:它可以从一个跨会话保留的 memory directory 中读取文件。
不同模型在建立自己的学习闭环上取得的进展各不相同。Claude Sonnet 4.6 只做到了针对答错原因提出猜想。它的记忆目录里散落着若干文件,每个文件都列着几条尚未验证的猜测。
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 应对复杂的长程任务。每次运行开始时,我们给每个模型一个记忆文件夹,它可以在游戏过程中读写其中的文件(图 4)。
我们比较了 Claude Sonnet 3.7 和 Claude Fable 5 各一次运行到约 10,000 步时的记忆文件夹。我们发现的一个关键差异,是每个模型认为什么值得记住。Sonnet 3.7 假定一切都可能有用,不加区分地往记忆里写。它的记忆文件夹里存着一份遭遇记录档案,往往为每一场战斗、捡到的每一件道具、遇到的每一个非玩家角色都单独建一个文件。最终,Sonnet 3.7 在 225 个文件夹里写下了 413 个记忆文件,只拿到一枚徽章(徽章用来标记玩家在游戏中的进度)。
相比之下,Fable 5 只在两个文件夹里写了九个文件,外加一个名为 global.md 的顶层文件,却拿到了四枚徽章。
Sonnet 3.7 的做法之所以出问题,主要是因为《宝可梦》的游戏状态一直在变——Sonnet 3.7 那份详尽的记录不断过时。结果,随着 Claude 不断推进,它不得不把越来越多的时间和资源花在梳理记忆上,而不是玩游戏。比如到第 10000 步左右,Sonnet 3.7 已经用到了第四个“主”记忆文件夹。在接下来的 17 步里,它新建了六个文件、删掉了另外九个,却没在游戏里采取任何行动。
Fable 5 则把记忆用在游戏没有明确告知它的事情上。Sonnet 3.7 写进记忆的某些信息——比如玩家有多少钱、玩家在地图上的位置——每一回合都能从屏幕上读到,存下来纯属多余。相比之下,关于策略、计划和已验证规则的记忆文件,只有 Claude 自己琢磨出来才会存在,不写下来就会消失。
Fable 5 据此整理了它的记忆。它的 global.md 文件相当于一块仪表盘,记录当前目标、一份预先写好的道馆(赢取徽章的挑战)攻略,以及模型自己定的记忆使用规则。locations 文件夹存放特定路线的行进计划,gameplay 文件夹存放基于它对游戏机制的理解而总结出的策略。例如,连续七个精灵球都没能抓住一只鲤鱼王(最容易捕捉的宝可梦之一)之后,Claude 写道:“如果连续 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,右)。对更强的模型来说,让它们自行判断什么重要,比事先定死规则更有效,而那些规则反而可能削弱表现。
我们还注意到,引导对较老的模型帮助最大。例如,Sonnet 4.6 经常不读取记忆目录里的文件,也不去验证自己关于答案为何错误的推测。
在这种情况下,提示 Claude 在回答前先读记忆文件、然后明确验证自己的推测,几乎让它的基准分数翻了一倍(图 5,左)。Sonnet 5 自己就会这么做。在无人提示的情况下,它十次里有九次在回答前读了记忆。相比之下,Sonnet 4.6 这么做的次数不到一半。
对于前沿的 Claude 模型,我们通常只给简单的指引:当有人要求时,或当某件事明显值得记住时,就创建记忆笔记,而这个判断交给 Claude 自己来做。
“做梦”可以修正记忆
Claude 会根据自己判断会话中哪些内容重要来写入记忆,因此一条从一开始就写错、或随着环境变化而逐渐失真的笔记,可能在之后的会话中被 Claude 读到并信任。
“做梦”让 Claude 有办法拿笔记和原始对话记录做对照检验(图 6)。我们见过一个正面例子:Claude 使用 Managed Agents 玩 Pokémon,并挂载了一个目录来存放记忆。
在游戏的某一段,玩家必须穿过月见山——一个入口在地图西侧、出口在东侧的洞穴系统。入口附近有个陷阱:一处单向的悬崖边,会把玩家丢回他来时的路线,而且没有明显的路能爬回去。Claude 把宝可梦中心(山入口处的一栋建筑)当作地标,所以它会不会走下悬崖,取决于它认为宝可梦中心在山的那一侧。
有一次,Claude(错误地)记下宝可梦中心在东侧。它走出宝可梦中心时宣称“月见山在我身后”,并更新笔记:“月见山完成”。但月见山并不在它身后。几个动作之后,Claude 走下了悬崖,落回它来时的路线(图 7)。它的导航工具没有显示这次坠落,于是 Claude 断定“我往西走过头了”,并认为自己一直都在正确的一侧。其实并非如此。
随后我们测试了“做梦”能否帮 Claude 避开这个陷阱。我们对包含错误宝可梦中心位置的记忆文件夹运行了“做梦”:Claude 拿笔记和会话记录核对,发现了自己的错误并改写。会话记录给了 Claude 一个可以用来验证记忆的事实基准。有了修正后的记忆笔记,Claude 径直回到月见山,最终抵达了华蓝市。
在笔记未修正的那次运行中,Claude 三次掉回之前的路线。第三次失败后,Claude 似乎放弃了,写道:“我要停下来,不再循环了。”我们设置的自动回复指示它继续。于是它继续了,一路回到山前的小镇深灰市,希望在那里治疗和补给。那次运行结束时,Claude 始终没能抵达华蓝市。
“做梦”能构建新的记忆表示
借助“做梦”,Claude 可以构建表示来帮助梳理记忆(图 9)。它使用的一种记忆表示叫wiki,即由 Claude 编写和维护的一组页面,汇集 Claude 对某一主题的了解,并链接到其他笔记。这些链接实际上为 Claude 提供了一张地图,让它能翻检记忆,在需要时高效定位。
wiki 这类表示能帮 Claude 遍历其不断增长的知识库。我们用 Stainless(我们今年 5 月收购的一家软件公司)约 35 万个文件、约 4.2 亿 token 的内部文档语料,探索了 wiki 作为记忆表示的好处。我们围绕这份语料建了一套 25 个问题的评测集,并给 Claude 一个搜索工具去探索。我们还指示 Claude 用“做梦”基于这些文件构建一个 wiki。在 128 次会话中,我们提示 Opus 5 智能体探索文件、编写或修正相互链接的 wiki 页面、合并重复项,并对照来源核查说法。
每个会话都建立在智能体此前会话取得的进展之上,并通过共享日志来协调工作。当我们将 dreaming 从两个会话扩展到 128 个会话时,25 个问题上的表现从 13% 提升到了 48% 的评分标准(图 10)。
Claude 会逐步构建自己的 wiki。在创建初始 wiki 之后,它会利用后续几轮 dreaming 来补充、编辑或精简它。在 dreaming 的早期轮次中,Claude 的知识就像一个刚入职的新员工,仅凭 wiki 回答问题的能力有限。dreaming 越多,它的知识图谱就越丰富,就像一位经验丰富的老员工。在测试中我们发现,当我们同时给 Claude 提供搜索工具时,wiki 对它的帮助最大。当它同时使用搜索和 wiki 时,随着 wiki 不断扩充,Claude 的综合得分从 54% 上升到 61%,而仅使用搜索工具时为 53%。当 Claude 只使用 wiki 回答问题时,它的最佳得分为 48%。同时使用搜索和 wiki 还能为每个问题节省约 20,000 个 token。
我们想测试哪些类型的任务能从 Claude 拥有 wiki 中受益。为此,我们使用了 Harvey LAB 基准测试,以及一组关于某次合并的文件。该基准测试给 Claude 一组文件,要求它根据文件内容生成一份法律简报,然后按照一系列标准对简报进行评分。虽然这可能不如宝可梦跑图那么有趣,但这些评估为我们提供了多样化的文件集合,用来构建 wiki。
我们指示 Claude 根据这些文件构建一个 wiki,然后要求它分别借助 wiki 和直接文件搜索来回答(关于此次合并的)问题或生成法律简报(LAB 基准测试)。其中一项测试提出了 24 个关于此次合并的问题(图 11 左),其中超过一半需要 Claude 跨多个文件查找信息,许多问题还需要 Claude 运用判断力或进行数学计算。在这些题目上(红色和橙色线),Claude 查阅 wiki 时得分为 87%,而仅使用搜索时为 73%。
在其他情况下,wiki 的作用就没那么大了。在一项 LAB 任务中(图 11 右),简报的评分标准通常可以通过对单个文件进行文本搜索来检索,而 wiki 相对于搜索并未表现出明显的性能提升。在另一项 LAB 任务中,wiki 变得比文件本身还大(图 12)。就像博尔赫斯那篇一段式短篇小说《论科学的精确性》中的制图师一样,他们绘制的地图精细到与它所代表的帝国一样大,Claude 也制作了一个极其详细的 wiki,实际上没有抽象出任何东西。
Dreaming 可以将笔记提升到记忆层级的上层
Dreaming 还可以把笔记提升到记忆层级的上层,智能体框架可以在每次会话开始时抢先将它们加载到 Claude 的上下文中(图 13)。这意味着 Claude 无需搜索它们,甚至无需知道有东西需要搜索。
把记忆推送到新会话(一种上下文注入)必须谨慎处理。注入的记忆会占用宝贵的 token,一条错误的笔记可能被带进每一个会话。加载笔记也不保证 Claude 会照做:我们关于 Claude Code 的文档就提醒过,指令文件越长,遵循度越低。所以记忆层级的最顶层必须保持相对精简,而 dreaming 在这里的大部分工作就是维持这一点——把一些细节下移到更低层级,只留下链接。
Claude Code 的自动记忆也用同样的方式让注入层保持精简,由 Claude 在会话期间自行维护。Claude 不会把全部自动记忆都加载进每个会话的上下文窗口,只加载 MEMORY.md 的前 200 行或 25 KB。这个头部相当于一份索引,告诉 Claude 它知道什么、去哪里找。
Dreaming 可以让记忆聚焦于特定目标
Dreaming 还能塑造记忆的生长方式。比如 Claude Duet 这类助手,往往受益于围绕它所帮助的人来组织记忆,而 dreaming 可以调校成服务于特定目标来构建记忆。
指导记忆如何生长的指令因任务而异,它们告诉 Claude 哪些信息才真正重要。例如,LAB 基准中的一项任务模拟公司收购,并提供了一组合同。生成的简报按是否正确描述合同条款来评分。
我们最初给生成 wiki 的指令很基础,没有告诉 Claude 如何使用这个 wiki。而这项任务高度依赖合同条款。在构建 wiki 的过程中,多个智能体同时写入一张共享的合同条款表(图 14,左)。
结果生成的 wiki 缺失了关键事实。我们给基于该 wiki 生成的简报评分时,Claude 只写入了 57 条事实中的 41 条(72%)。排查问题后发现,那张共享表对合同条款的总结很糟糕,有些条款甚至完全缺失,因为智能体之间互相覆盖了对方的写入。
合同条款是 wiki 中最重要的部分,但指令里并没有说明这一点。为了找到更好的指令,我们跑了一个循环:Claude 反思自己的失败,提出对指令的修改,然后重建 wiki。这个循环让 Claude 发现遵循合同条款有多重要,并据此改写了构建 wiki 的指令。
每份合同在 wiki 中都有独立页面,由单个智能体撰写,逐字引用条款,而不是把它们汇总进一张共享表。用改进后的 wiki 生成简报再评分,100% 的评分标准都能满足,此前只有 72%。
Dreaming 可以填补会话留下的空白
Claude 写记忆笔记时,只能看到那个特定会话中的上下文。Dreaming 可以跨多个会话搜索,找出常见模式或纠正常见错误。
在为 LAB 基准构建 wiki 时(示例见图 14),Claude 有时会链接到尚未创建的页面。第二轮 dreaming 补上了许多这样的缺口。在一项任务中(图 15),dreaming 发现 wiki 里有九个链接指向一个不存在的页面,于是把它们重新指向同一文档已有的页面。它还新增了三个页面(包括一个索引)来改进 wiki。
回望过去,展望未来
关于如何为智能体设计记忆系统,还有许多开放问题。其中之一是 Claude 应该在什么时候创建记忆。当 Claude 处理任务时,它可以写入记忆存储(例如文件夹、文件或数据库),在源头捕捉重要信息,让关键细节能立即用于后续的轮次或会话。但即时记录笔记不可避免地会让 Claude 的注意力从主任务上转移开。相比之下,做梦可以把记忆创建推到后台,但做梦产生的任何输出可能无法立即被 Claude 访问。
另一个问题是如何让记忆可靠地保持最新。Claude 可能做出错误的预测,或者把从一开始就错误的规则写入记忆。随着环境变化,记忆也可能漂移、变得无关。做梦是修正这些错误的一种方式(图 8),但它需要消耗算力。让 Claude 持续检查所有记忆可能并不实际。更重要的也许是让做梦聚焦于可能发生变化的信息,或者仔细调整做梦的节奏(例如根据记忆被访问的频率)。
把对话记录搜索视为 Claude 记忆的基础,也是合理的。将表示形式(例如 wiki)与搜索结合(图 10)有时会很有效。但 Claude 需要消耗算力来维护记忆表示,并确保它们不会积累错误或幻觉。
尽管 Claude 对重要性的判断已经有所改善,但没有任何模型能真正知道未来轮次会发生什么。做梦让 Claude 有机会回望,用算力来整理记忆、修正错误,并维护表示形式,使未来的会话能更容易地访问记忆。随着 Claude 能力增强,记忆系统也会演进,关于如何设计 Claude 的记忆系统,我们还有很多要学习。
来源:Anthropic:Research · anthropic.com