跳到主要内容

Agent 记忆的组成部分:Claude 如何判断什么值得记住

Anthropic

两个错开的半圆示意图,带有网格图案,一个绿色、一个粉色,隔着一段间隙彼此相对,浅蓝色背景。

Source: https://www.anthropic.com/research/components-of-agent-memory

索伦·克尔凯郭尔(Søren Kierkegaard)曾写道,生活只能向后被理解,却必须向前被度过。在为 AI 智能体设计记忆时,我们也遇到了类似的困境。

作为人类,我们在日常生活中不断地编码记忆。海马体(hippocampus)在其中扮演着核心角色,它在当下捕捉经历,使记忆得以迅速形成,并且可以立即取用。但只有某些经历会被巩固(consolidated)为长期知识。

这种巩固过程中的大部分,似乎发生在我们的大脑处于“离线”状态的时候。在我们睡眠期间,以及在安静的休息期间,海马体会重放我们近期的经历。人们认为,这一过程会逐步提炼这些经历,并把它们整合进新皮层(neocortex)——即我们大脑中储存我们所认为的大部分知识的那一部分。

智能体记忆可以采用类似的分工方式。智能体会把大量工作内容记录在日志或对话记录(transcript)中。Letta 和 UC Berkeley 的研究人员提出了睡眠期计算(sleep-time compute),作为一种让模型利用交互之间的空闲时间来重组其现有上下文的方法。同样的思路也可以帮助智能体组织自己的记忆:通过反思日志来修正错误,或者产出新的笔记与记忆表征。这一过程常被称为做梦(dreaming)(图 1)。

我们发现,“做梦”一直是帮助我们赋予 Claude 有效记忆的一个有用的工具。在本文中,我们分享我们是如何逐步形成对智能体记忆的看法的,并逐一介绍我们用来探索智能体记忆的若干评测,其中也包括对“做梦”这一手段的使用,以及每个组件对记忆组织各自有什么贡献。

一次会话与下一次会话之间记忆层级的示意图。从下到上依次为:对话记录(可检索的事件日志)、Claude 撰写的记忆笔记、诸如 wiki 之类的记忆表征,以及被注入并加载进每一次会话的上下文。在一个标有“Dreaming(做梦)”的方框内,箭头从对话记录向上指向每一个层级,并在相邻的较高层级之间双向延伸。

Claude 可以利用“做梦”来组织记忆。这可以修正错误、创建笔记、构建新的记忆表征,或者塑造哪些内容会被预先加载(preemptively loaded)到未来的会话中。

记忆笔记

所谓“智能体记忆”,我们指的是 Claude 从经验中获得的、并且在会话之间保留下来的知识——这些经验包括与用户的交互以及它被分配的任务——它被保存为日后可以读取的上下文。它不包括模型学习或管理上下文的其他方式,例如对其权重(weights,训练期间设定的内部参数)的更改、上下文内学习(in-context learning,即在单次对话内获得的知识),以及压缩(compaction)(由 Claude 撰写的摘要,用来替换它较早的轮次,以便它能在新的上下文窗口中继续工作)。

在人类大脑中,在某种经历之前、之中或之后释放的化学信号可以标记某个记忆为重要。被标记的记忆在离线时段内往往比未被标记的记忆更频繁地被重放。这一过程被称为重放(replay),它有助于稳定这些记忆,并把它们整合进长期记忆。

同样地,Claude 可以在会话日志中把显著的事件在发生之时就标记出来,以便日后更容易找到,或者把它们写入某个记忆存储,例如一个记忆笔记文件夹(图 2)。但是,Claude 如何在当下、在它尚不知道接下来会发生什么之前,就判断出什么才是显著的(salient)?

同样的记忆层级示意图,其中记忆笔记这一层被高亮显示。一个箭头从会话直接指向记忆笔记,并被描述为由 Claude 撰写的显著观察。

Claude 可以把笔记写入记忆。

记忆可以是对未来需求的一种预测

记忆偶尔也是一种预测。通过写下一条规则,智能体就预测了它所描述的模式将再次具有相关性。例如,写下一条经过验证的事实,就是在预测未来某个会话中的智能体会想要依赖该事实,而无需再次复核。随着时间推移,Claude 在这类预测上已经变得擅长得多。

来看持续学习基准(Continual Learning Bench,CL-Bench)1.0中的一项任务,该基准衡量智能体利用记忆来完成长时程(long-horizon)任务的能力。其中有一项特定的任务,要求 Claude 通过在数据库中查找信息来回答一系列问题。在 Claude 给出答案之后,它会被告知正确的解答,并且可以写下一条记忆,用来帮助回答未来的问题。

在这里,记忆可以支撑起一个学习闭环(learning loop)。如果 Claude 把某道题答错了,它可以记录下这次失败,提出关于出错原因的种种假设,检验这些假设,并把发现的结果转化为一条关于未来该如何作答的规则。

我们使用 Claude Managed Agents 运行了 CL-Bench 1.0 的这项任务。Claude 在全新的会话中开始每一道题,只有一个例外:它可以从一个记忆目录中检索文件,而该目录会从一个会话持续保留到下一个会话。

不同模型在建立自己的学习闭环方面,取得了不同程度的成功。Claude Sonnet 4.6 最多只做到了提出关于某个答案为何错误的假设。它的记忆目录里散落着各种文件,每个文件都列出了若干未经检验的猜测。

左侧:CL-Bench 数据库任务平均得分(mean reward)的柱状图,对比无状态基线(stateless baseline)与记忆存储(memory store)。Opus 5.5:0.655、0.838。Sonnet 5.5:0.644、0.833。Opus 5:0.564、0.828。Opus 4.7:0.383、0.700。Sonnet 5:0.306、0.610。Sonnet 4.6:0.330、0.364。右侧:同一批模型在 30 道题上的滚动平均得分折线图,分别展示有记忆与无记忆的情况。

CL-Bench 数据库任务,在各模型之间对比有记忆与无状态基线的表现。

Claude Opus 4.7 把它的笔记整合成一份单一的参考文档,并开始标记哪些事实已经核实、哪些仍未确认。Claude Sonnet 5 在评分器(grader)检查过之后把每个答案标记为已确认,并在答错时写下一条更正。

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 假设一切都可能重要,于是不加区分地写入记忆。它的记忆文件夹里保存着一份遭遇档案,往往为它打过的每一场战斗、找到的每一件物品,以及遇到的每一个非玩家角色(NPC)各建一个单独文件。最终,Sonnet 3.7 在 225 个文件夹中写出了 413 个记忆文件,并赢得了一枚徽章(badge,徽章标志着玩家在游戏中的进度)。

相比之下,Fable 5 在两个文件夹中写了九个文件,外加一个名为 global.md 的单一顶层文件,并赢得了四枚徽章。

两张同一尺度下的宝可梦记忆目录矩形树图(treemap),其中面积表示记忆的字符数。Claude Sonnet 3.7 的树图很大且拥挤,共有 413 个文件、977,930 个字符,分布在 locations、main、battles 以及若干“consolidated”文件夹中。Claude Fable 5 的树图很小,在 locations、gameplay 和 global.md 中共有 10 个文件、43,406 个字符。

Claude 在玩宝可梦时,Sonnet 3.7 与 Fable 5 各自的记忆目录。

Sonnet 3.7 的做法之所以成为问题,主要因为《宝可梦》的游戏状态在不断变化——Sonnet 3.7 那份详细的记录也在持续变得过时。结果,随着 Claude 不断推进,它不得不把更多的时间和资源花在梳理自己的记忆上,而不是玩游戏。例如,在大约第 10,000 步时,Sonnet 3.7 开启了它的第四个“master”记忆文件文件夹。在接下来的 17 步里,它创建了六个文件、删除了另外九个文件,而在游戏本身中没有采取任何行动。

Fable 5 的做法则是把记忆用于游戏并未明确告知它的事情。Sonnet 3.7 写入记忆的某些信息——例如玩家有多少钱、或者玩家在地图上的位置——每一回合都能从屏幕上读出来,因此把它们存起来是多余的。相比之下,关于策略、计划和经过检验的规则的记忆文件,只有在 Claude 把它们想出来之后才存在,而且除非 Claude 把它们写下来,否则它们就会消失。

Fable 5 相应地组织了自己的记忆。它的 global.md 文件充当一块仪表盘,其中保存着当前目标、预先写好的攻克道馆(gym,即赢得徽章的挑战)的计划,以及模型自己关于如何使用记忆的规则。一个 locations 文件夹保存着在特定路线上导航的计划,而一个 gameplay 文件夹保存着基于它所了解的游戏运作方式而形成的策略。例如,在连续七个精灵球(Poké Ball)都没能抓住一只鲤鱼王(Magikarp,最容易捕捉的宝可梦之一)之后,Claude 写道:“如果连续 3 个以上的球失败,就改变时机(在菜单步骤之间插入额外的‘等待’按键)——这样做之后立刻就抓到了。”

凭借小得多的记忆文件夹,Fable 5 在游戏中的进度远超 Sonnet 3.7。Opus 5.5 采取了类似的做法:它维护一个小文件夹的记忆笔记,用来追踪当前目标与接下来的步骤,在游玩过程中重写这些笔记,并通关了游戏。

引导 Claude 撰写记忆

我们发现,告诉 Claude 记忆是用来做什么的会很有帮助,但如果同时告诉它该怎样去使用记忆,效果就未必如此了。在 CL-Bench 上,我们只是简单地告诉 Claude,有一个记忆文件夹(memory folder)可供它使用。对我们的 Opus 4.7 和 Opus 5 来说,仅仅是这种泛泛的指引就已经足够,使这两个模型都能够有效地使用记忆,并且让它们在表现上都有了明显的提升(图 3)。

我们还测试了给模型制定具体的规则,明确地规定它们应该往记忆里写入什么样的内容,并且每一项测试只使用其中的一条规则。我们把每个模型在应用某条规则时从记忆中获得的增益(gain),与它在没有应用这条规则时从记忆中获得的增益做了比较,看看两者究竟相差多少。当我们把这条规则设为“只记录失败”时,Opus 5 和 Opus 4.7 都失去了记忆原本带给它们的表现提升中的一大部分(图 5 右侧)。对更强的模型来说,让它们自由地判断哪些内容具有显著性(salience),比事先为它们设定固定的规则更有效;而那些固定下来的规则最终可能会削弱模型原本的表现。

左图:Sonnet 4.6 在 CL-Bench 数据库任务上的平均奖励(mean reward)条形图(bar chart):基线为 0.330,使用记忆时为 0.364,使用记忆并配合改进后的指令时为 0.641。图中的参考线标出 Opus 4.7 使用记忆为 0.700,Opus 5 使用记忆为 0.828。右图:当模型被告知只记录失败时,记忆增益所发生的变化:Opus 5 为 −0.234;Opus 4.7 为 −0.150;Sonnet 4.6 为 −0.020。

左图:Sonnet 4.6 在 CL-Bench 数据库任务上的表现,对比了有提示引导它使用记忆,与没有这样的提示这两种情况。右图:当模型被告知只记录失败时,每个模型从记忆中获得的增益究竟发生了多大的变化。

我们还注意到,这种引导(steering)对较老的模型帮助最大。举例来说,Sonnet 4.6 常常不去读取自己记忆目录(memory directory)中的那些文件,也不会去检验它关于某个答案为何出错的那些推测。

在这种情况下,如果提示 Claude 在回答之前先读取自己的记忆文件,然后再明确地检验自己提出的那些推测,Sonnet 4.6 在基准测试(benchmark)上的分数几乎翻了一倍(图 5 左侧)。Sonnet 5 会自己主动这样做:在没有人提示它的前提下,它在 10 次中有 9 次都会在回答之前先读取自己的记忆。相比之下,Sonnet 4.6 这样做的次数还不到一半。

对于前沿的 Claude 模型,我们通常只给出一些简单的指引:当有人要求它们记住某些内容时,或者当某件事情明显值得记住时,就去创建记忆笔记(memory note),而把这一判断本身交给 Claude 自己来做决定。

Dreaming 可以纠正记忆

由于 Claude 是根据自己在会话中所判断的重要程度来写入记忆的,一条从一开始就是错误的笔记,或者一条随着环境变化而逐渐偏移的笔记,可能会在之后的某一次会话中被 Claude 读取,并且被它当成可靠的信息来信任。

Dreaming 给 Claude 提供了一种方法,让它能够把自己的笔记与原始对话记录(transcript)相互对照检验(图 6)。当 Claude 使用 Managed Agents,并通过一个挂载的目录来保存自己的记忆、以此玩 Pokémon 时,我们就看到了一个这方面的正面例子。

带 dreaming 的记忆层级图,图中突出显示了一条从对话记录层一直向上指向记忆笔记层的箭头,表示 dreaming 会依据对话记录来纠正笔记。

Dreaming 可以纠正记忆中的错误。

在游戏的其中一个部分里,玩家必须穿过月见山(Mt. Moon),这是一个洞穴系统(cave system),它的入口位于地图西侧,出口位于地图东侧。在入口附近设置了一个陷阱:一处单向的崖边(one-way ledge),会把玩家丢落到他们来时的路线上,而且没有任何明显可见的路径可以再爬回去。Claude 当时把宝可梦中心(PokéCenter)当作自己辨认方向的地标(landmark)来使用,那是位于这座山入口处的一栋建筑,因此它是否会从那处崖边走落下去,取决于它认为自己当时究竟位于山的哪一侧。

在某一个时刻,Claude(错误地)写下宝可梦中心位于东侧。当它走出宝可梦中心时,它宣布“月见山在我身后”,并更新了自己的笔记:“月见山 已完成”。但月见山其实并不在它身后。几次操作之后,Claude 走下那道崖边,落回到了它来时的路线上(图 7)。由于它的导航工具(navigation tool)没有显示出这次跌落,Claude 便得出了“我向西走过头太远了”的结论,并认为自己其实一直待在正确的那一侧。实际上并非如此。

两幅 Pokémon 地图面板,智能体位于一处崖边的附近。左图为“原始记忆”,其中存储的笔记是错误的:一个箭头显示智能体正朝着下一座城市前进。右图为“记忆 + dreaming”,其中一次离线处理(offline pass)纠正了这条笔记:一个箭头显示智能体正返回洞穴的入口。

一条经过纠正的记忆笔记改变了 Pokémon 中的结果。在使用未纠正笔记的情况下,Claude 说“月见山在我身后”,朝着下一座城市前进,结果又回到了它来时的路线上。而在笔记被 dreaming 纠正之后,它改口说“现在我需要找到月见山的洞穴入口,才能重新进入”,然后就走回了洞穴之中。

随后我们测试了 dreaming 是否能够帮助 Claude 避开这个陷阱。我们在包含错误宝可梦中心位置的记忆文件夹上运行了 dreaming:Claude 把这条笔记和会话记录(transcript)对照检查,发现了自己的错误,并重写了这条笔记。而这批完整的会话记录为 Claude 提供了一个可以用于校验自身记忆的真实基准(ground truth)。有了纠正后的记忆笔记,Claude 直接回到了月见山中,并最终抵达了华蓝市(Cerulean City)。

在笔记未被纠正的那次运行(run)中,Claude 先后三次掉回到那条更早的路线上。第三次失败之后,Claude 似乎放弃了,它写道:“我要停下来了,而不是继续这样反复打转。”而我们的设置自动回复了一条消息,指示它继续下去。于是它就继续了,一路回到了尼比市(Pewter City),也就是位于这座山之前的那个小镇,它希望能在那里恢复体力并补充所需的物资。那次运行结束时,Claude 始终没能抵达华蓝市。

折线图(line chart):朝向华蓝市的推进情况,横轴为累计的操作次数,共计 3,000 次。记忆 + dreaming 的那次运行在第 1,935 次操作时抵达华蓝市。原始记忆的那次运行从崖边跌落,并折返回尼比市。而没有记忆的那次运行则从未抵达华蓝市。

Dreaming 纠正了记忆,于是 Claude 回到洞穴之中,并抵达了下一座城市。使用未纠正笔记(“原始记忆”)的那次运行始终没能越过这座山,而没有记忆的那次运行同样如此。

Dreaming 可以构建新的记忆表征

借助 dreaming,Claude 可以构建表征来帮助自己在记忆中导航(图 9)。它所使用的一种记忆表征(representation)被称为wiki,这是由 Claude 撰写和维护的一组页面(page),它汇集了 Claude 关于某一个主题所知道的内容,并将这些内容与其他的笔记链接起来。这些链接实际上相当于为 Claude 提供了一张地图(map):借助这张地图,Claude 可以系统地梳理自己的记忆,并在需要的时候高效地定位到相关的那部分记忆。

带 dreaming 的记忆层级图,图中突出显示了从对话记录以及从记忆笔记一同向上指向记忆表征层(例如 wiki)的箭头。

Dreaming 可以构建记忆表征。

像 wiki 这样的表征可以帮助 Claude 遍历它不断增长的知识库(knowledge base)。我们借助一个内部的文档语料库(corpus),探讨了 wiki 作为一种记忆表征所带来的益处——这个语料库来自我们于五月收购的软件公司 Stainless,大约有 350,000 个文件,约 420M 个 token。我们围绕这个语料库设计了一组包含 25 个问题的评估集(evaluation set),并给 Claude 提供了一个搜索工具(search tool),让它自己去探索这个语料库。我们还指示 Claude 使用 dreaming 基于这些文件构建一个 wiki。在 128 个会话的过程中,我们提示 Opus 5 智能体(agent)去探索这些文件、撰写或修正相互链接的 wiki 页面、合并重复的页面,并对照来源核查其中提到的各项说法。

每个会话(session)都建立在智能体于之前会话中已经取得的进展之上,并使用一个共享日志(shared log)来协调彼此的工作。当我们将 dreaming 从两个会话扩展到 128 个会话时,这 25 个问题上的表现从 13% 提升到了 48%(以受评标准,即 graded criteria 的达成比例计算)(图 10)。

Claude 会逐步地构建它的 wiki。在创建出初版 wiki(initial wiki)之后,它会利用后续轮次的 dreaming 来对它进行补充、编辑或删减。在 dreaming 的早期轮次中,Claude 的知识就像一名新入职员工的知识,因此它仅凭 wiki 来回答问题的能力也还比较有限。它 dream 的轮次越多,它的知识地图(knowledge map)就会变得越丰富,就像一名经验丰富的资深员工那样。在我们的测试中,我们发现,当我们同时给 Claude 提供一个搜索工具时,wiki 对它的帮助是最大的。当它同时使用搜索和 wiki 时,随着这个 wiki 不断增长,Claude 的总分(aggregate score)从 54% 上升到了 61%;而如果它只能访问搜索工具、没有 wiki 可用,得分则为 53%。当 Claude 只使用 wiki 来回答问题时,它的最佳得分为 48%。同时使用搜索和 wiki,还为每个问题平均节省了大约 20,000 个 token。

中间:折线图,展示随着 wiki 的生成量从 2M 增长到 128M 个 dreaming token,各项受评标准的达成情况。wiki 加搜索工具从 54% 上升到 61%,仅使用 wiki 从 13% 上升到 48%,而没有 wiki 的搜索工具则一直平稳保持在 53%。左右两侧:一个示例 wiki 的网络图(network graph),2 个会话之后为 103 个页面、766 条链接,128 个会话之后为 222 个页面、12,893 条链接。

中间:随着 Claude 在连续多个会话中构建 wiki,它在这个来自某家公司的文档语料库的 25 个问题上的得分。左右两侧:同一个示例 wiki 在两个会话和 128 个会话之后的样子;其中每个点代表一个 wiki 页面,而连线连接着相互链接的页面。

我们想测试究竟哪些类型的任务能够从 Claude 拥有一个 wiki 中获益。为此,我们使用了 Harvey LAB 基准测试(benchmark),以及一组关于一次并购(merger)的文档。这个基准会给 Claude 一组文档,并要求 Claude 基于这些文档的内容生成一份法律摘要(legal brief)。随后,基准会按照一份标准清单(checklist)为这份摘要评分。虽然这些评估(evaluation)也许不如一场 Pokémon(宝可梦)游玩那样有趣,但它们为我们提供了多样化的文档集合,让我们有素材可以据此构建 wiki。

我们指示 Claude 基于这些文档构建一个 wiki。然后,我们要求 Claude 分别依据 wiki 和通过直接文件搜索这两种方式,来回答(关于这次并购的)问题,或者生成法律摘要(LAB 基准测试)。其中一项测试提出了 24 个关于这次并购的问题(图 11 左侧),其中超过一半的问题需要 Claude 跨越多份文档去查找信息,而许多问题还需要 Claude 运用自己的判断力(judgment)或者进行算术(arithmetic)。在这些条目上(红色和橙色线条),Claude 查阅 wiki 时的得分为 87%,相比之下仅使用搜索时为 73%。

两幅图,将评分标准与源文档关联起来。左侧是 wiki 带来了更多益处的任务:24 条标准中的大多数都与 10 份文档中的两份或更多相连接,其中九条需要判断或算术。右侧是 wiki 带来的益处较少的任务:57 条标准中的大多数都可以通过对单份文档的文本搜索找到,通常是在交易概述备忘录(deal overview memo)中。

每个面板都列出了被评的内容(左侧,即评分标准),以及满足每一项要求所需的源文档(右侧)。左侧:24 个关于一次并购的问题,这些问题可以通过查阅大多为公开的申报文件(filings)来回答。超过一半的评分标准需要把多份文档中的信息结合起来。右侧:一项 LAB 任务,其中 wiki 没有带来明显的增益。大多数标准都可以从单份文档中得到满足。

在其他一些情况下,wiki 的用处就没那么大了。在一项 LAB 任务中(图 11 右侧),摘要的评分标准常常只要对单份文档做一次文本搜索就能检索到,而 wiki 相对于搜索而言,在表现上并没有带来明显的增益。在另一项 LAB 任务中,wiki 甚至变得比文档本身还要大(图 12)。就像博尔赫斯那段一页篇幅的短篇故事《论精确性科学》中的制图师一样——他们绘制出的地图精细到了与它所代表的帝国一样大的程度——Claude 也做出了一个极其详细的 wiki,却实际上没有从中抽象出任何东西。

wiki 构建过程与第二轮处理的示意图。左侧,一个圆圈容纳着语料库:10 份文档,共 115 KB 文本。一个箭头指向一个更大的圆圈,其中容纳着由它构建出的 wiki:68 个页面、255 条链接、203 KB,即语料库的 1.77 倍。这个 wiki 中有一些页面没有任何链接。

这个 wiki 变得比原始文件还要大。

Dreaming 可以把笔记提升到记忆层级的上层

Dreaming 还可以把笔记浮到记忆层级的最上层,而 agent harness 可以在每次会话开始时,抢先一步把它们加载进 Claude 的上下文(图 13)。这意味着 Claude 既不需要去搜索它们,甚至不需要知道有什么东西值得搜索。

把记忆提升进新的会话(这是一种上下文注入)必须谨慎进行。被注入的记忆会占用宝贵的 token,而一条错误的笔记可能会被带进每一次会话。加载一条笔记也并不保证 Claude 会照着它行动:我们关于 Claude Code 的文档提醒说,指令文件越长,遵循度就越低。所以记忆层级的最上层必须保持相对较小,而 dreaming 在这里的许多工作正是维持这一点——把一些细节向下移动,只留下链接。

Claude Code 的自动记忆也用同样的方式让它被注入的那一层保持精简,由 Claude 在会话期间自行维护。Claude 并不会把它的全部自动记忆都载入每次会话的上下文窗口,而是只加载 MEMORY.md 的前 200 行或 25 KB。这个头部充当索引,向 Claude 显示它知道什么,以及到哪里去找。

带有 dreaming 的记忆层级,高亮标出从会话记录和从记忆表征指向顶部被注入的上下文层的箭头,这一层会供给下一次会话。

Dreaming 可以写入记忆层级的最上层。被注入的上下文会在每次会话中加载,而它下方的各层则在 Claude 需要时被读取或搜索。

Dreaming 可以让记忆聚焦于某个特定目标

Dreaming 还可以塑造记忆如何生长。举例来说,像 Claude Duet 这样的助手,常常从围绕它正在帮助的那个人来组织记忆当中获益,而 dreaming 可以被调整成服务于某个特定目标来构建记忆。

指导记忆如何生长的指令因任务而异,它们告诉 Claude 究竟哪些信息才是重要的。举例来说,LAB 基准中的一个任务模拟了一次公司收购,并提供了一组合同。简报的评分取决于它是否正确地描述了合同条款。

我们起初使用的是一套基础的维基生成指令,它并没有告诉 Claude 该怎样使用这个维基。而这个任务高度依赖合同条款。在维基被构建的过程中,好几个 agent 同时写入一张共享的合同条款表(图 14 左)。

两张示意图。之前:四个 agent 写入同一个共享页面 provisions.md,其中一个 agent 的保存抹掉了另一个 agent 写入的行;57 条受评事实中有 41 条留存下来。之后:四个 agent 各自编写自己那份合同的页面,条款逐字照抄;57 条受评事实全部 57 条留存下来。

在指令修改前后,有多少条受评的合同事实进入了维基。左图:多个 agent 写入同一个共享页面;57 条事实中有 41 条留存下来。右图:每份合同一个 agent,各自编写自己的页面并逐字引用条款;57 条事实中 57 条全部留存下来。

结果得到的维基缺失了关键事实。当我们对根据该维基生成的简报进行评分时,Claude 只纳入了 57 条事实中的 41 条(72%)。当我们查看究竟出了什么问题时,我们发现那张共享表格对合同条款的概括很糟糕,而且因为各个 agent 互相覆盖了对方的工作,有些条款完全不见了。

合同条款是这座维基中最重要的部分,但指令并没有这样说。为了找到更好的指令,我们运行了一个循环:Claude 在其中反思自己的失败,提出对指令的修改,然后重建维基。这个循环让 Claude 发现遵循合同条款有多么重要,于是它相应地重写了构建维基的指令。

每份合同在维基中都有自己的页面,由单个 agent 撰写,逐字引用条款,而不是把它们概括进一张共享表格。当我们对根据这座改进后的维基生成的简报进行评分时,100% 的评判标准都能被满足,高于此前的 72%。

Dreaming 可以填补一次会话遗留的缺口

当 Claude 撰写记忆笔记时,它只能看到那一次特定会话中的上下文。Dreaming 则可以跨许多会话进行搜索,找出共同的模式或纠正共同的错误。

在构建 LAB 基准所需的维基时(作为一个例子,见图 14),Claude 有时会链接到尚未创建的页面。第二轮 dreaming 补上了其中许多缺口。在某个任务中(图 15),dreaming 发现维基中有九个链接指向一个并不存在的页面,并把它们重新指向了同一份文档已有的页面。它还新增了三个页面,其中包括一个索引页,以改进这座维基。

两张维基的网络图。第二轮之前:38 个条目、225 条链接,其中来自六个页面的九条链接指向并不存在的页面“escrow-agreement”。之后:41 个条目、278 条链接,九条链接全部指向“buyer-form-escrow-agreement”,并新增了三个页面:index、instructions email 和 escalations。

第二轮 dreaming 前后的维基。

回望过去,也展望前方

关于如何为 agent 设计记忆系统,还有许多未解的问题。其中之一是 Claude 应该在什么时候创建记忆。当 Claude 处理某个任务时,它可以写入一个记忆存储(例如一个文件夹、文件或数据库),在源头捕捉重要性,并让重要细节立刻可供后续的回合或会话使用。但当下记录笔记,不可避免地会把 Claude 的注意力从主任务上引开。相比之下,dreaming 可以把记忆创建推到后台,但 dreaming 的任何产出可能无法立刻被 Claude 取用。

另一个问题是,如何让记忆可靠地保持最新。Claude 可能做出错误的预测,或者把从一开始就错误的规则写进记忆。随着环境变化,记忆也可能漂移、变得无关紧要。Dreaming 是修正这些错误的一种方式(图 8),但它需要消耗算力。让 Claude 持续检查它的全部记忆也许并不实际。相反,把 dreaming 聚焦在那些很可能发生变化的信息上,或者仔细调校 dreaming 的节奏(例如根据记忆被访问的频率来决定),可能才是重要的。

把会话记录搜索视为 Claude 记忆的基础,也是合理的。把表征(例如维基)与搜索结合起来(图 10),有时会很有效。但 Claude 需要使用算力来维护记忆表征,并确保它们不会累积错误或幻觉。

尽管 Claude 对重要性的判断已经有所改善,但没有任何模型能真正知道未来的回合中会发生什么。Dreaming 给了 Claude 一个回望的机会,用算力来组织它的记忆、修正错误,并维护那些能让未来会话更容易取用记忆的表征。随着 Claude 变得更有能力,记忆系统也会不断演进,而关于如何设计 Claude 的记忆系统,我们仍有许多东西要学。

关于上手 dreaming 和知识维基,请参阅我们的 cookbook。

评论