首页 / 文章

AI智能体记忆并非数据库:应当保留、检索与遗忘什么内容。

为何智能体记忆属于相关性问题:上下文、记忆、状态与RAG有何不同,应存储什么内容,如何界定范围,如何管理其时效性并进行审计,以及为何遗忘也是一种特性。

发布者:REACTAPP.TOP阅读约 11 分钟2536 词

来源: AI Agent Memory Is Not a Database

人工智能智能体的记忆功能通常被宣传为能使其变得更聪明的特性:记住过往的对话、用户偏好、之前的工作流程步骤、上次有效的操作方式以及文档中的事实。理想中的智能体应该是知晓其所见过的一切的。但问题就在这里出现了,因为智能体并不需要记住所有内容,而且记忆与数据存储并非同一概念。

数据库可以保存数百万条记录,而这些记录完全不必存储在智能体的记忆中。此时需要考虑的是工程层面的问题:应该记住什么?记住多久?信息存储在哪里?何时获取?何时删除?它真的属于记忆范畴吗?从这个角度看,记忆更多是一个相关性问题,而非存储问题。

为何“记住一切”行不通

想象一个正在执行长期任务的智能体。在第一步中,它会了解用户的目标、选定的文档、提取出的若干数值、工具的运行结果、临时的决策以及验证结果。接着是下一步,再下一步,相关数据量不断累积。

最简单的实现方式是全部保留:将每条消息都追加下来,存储每个工具的运行结果,并在下次调用时重新发送所有内容。这种方式能暂时解决问题。但随后上下文量会激增,响应速度变慢,成本上升,过时的信息开始影响新的决策,而那些已不再重要的输出仍会保留在提示词中。实际上这就相当于要求模型在五十项内容中判断哪些是当前重要的,此时内存早已变成了无用信息。

容易混淆的四个术语

这些概念解决的是不同的问题,将它们区分开来后,智能体的设计就能得到改进。

上下文是指模型当前需要了解的信息:当前的请求、选定的证据、之前的一些决策、相关的工具输出。它是临时的,用于当前的推理步骤。

记忆则是系统日后可能再次需要的信息,比如用户的偏好、某人确认的决策、有用的总结或之前任务的结果。它的存在时间可以超过一次模型调用。

状态用于说明工作流程的当前进展。它可以是QUEUED、RUNNING、WAITING_FOR_TOOL、RETRYING或COMPLETED这样的状态,也可以是document_extracted = true、analysis_completed = true和report_generated = false这样的更细粒度的标志。状态让系统能够继续运行,但它并非知识。

RAG指的是在需要时从外部来源获取知识:文档、数据库、政策文件、报告、内部维基以及向量存储。这些信息本来就存在于其他地方,智能体无需永久记住它们,只需在需要时找到即可,这是另一个问题。

短期记忆

短期记忆即工作集。解决问题时,人们会在脑海中保留某些事实,完成后则丢弃大部分,智能体也有同样的需求。在某个工作流程中,智能体可能会使用当前请求、选定的文档、最近的工具输出结果、中间计算结果、先前的决策以及任务进展情况。这些信息在当下很重要,但到了明天可能就几乎毫无价值了。一个恰当的定义是:继续完成当前任务所需的最小信息集,而非自任务开始以来发生的所有事情。

长期记忆需要经过筛选才能留存

长期记忆指的是那些你刻意保存下来的信息,因为它们可能在未来派上用场。例如“更喜欢简洁的报告”这样的明确偏好、“未来分析都使用这种报告格式”这样的既定业务决策,或是“该项目将系统A视为事实来源”这样的既定事实。

这里的标准应该更高。在存储任何信息之前,先思考它是否有助于未来做出更好的决策。如果不能,就将其排除,因为长期记忆除了存储成本之外还有其他代价:每个存储的信息都可能被系统日后检索、依赖、维护,甚至出错。

RAG并非长期记忆

假设向量索引中包含20,000份内部文档,智能体能够检索这些文档。但这并非智能体的记忆。这些文档属于知识范畴,而RAG则是获取这些知识的方法。智能体无需将所有文档都存储在内存中,只需知道如何找到正确的文档即可。正常的流程是:智能体需要信息时,会搜索知识源,获取相关证据并加以利用;而不正常的流程则是将所有知识都复制到内存中。知识的量可能极其庞大,而工作记忆的容量却必须保持较小。

状态往往比记忆更重要

所谓智能体记忆,其实大多只是工作流状态。假设某个智能体已经完成文档提取、证据检索与分析,但报告尚未生成。如果在报告完成前系统崩溃,就必须知道从何处继续。这就是状态。由于应用程序本身已知晓分析步骤已完成,模型无需再回忆这一事实。

任务状态、重试次数、检查点、作业ID、已完成步骤以及待办操作通常应属于确定性应用程序的状态,而非大语言模型对话的内容。一个好的原则是:如果软件能够精确知晓某件事,就让软件将其准确存储下来。模型不应承担记住工作流真实情况的职责。

并非所有发生的事情都需要被记录

想象一下,某个工具返回了500行的JSON数据。下一步真的需要这500行吗?很可能只需要一两个字段,比如account_status = ACTIVE、total_balance = 120000或document_found = true。原始输出可以保存在日志或存储中,而内存只需存放关键部分即可。

对话处理也是如此。如果用户和客服通过十条消息才确定需求,那么一条简短的记录,如“用户希望按类别分组并按严重程度排序报告”,比每次都重复整个对话更有用。

哪些内容值得记住

没有一种方案适用于所有系统,但通常以下几类内容是不错的选择:

  • 稳定的偏好设置:输出格式、语言、报告风格。
  • 明确确认的决策:选定的配置、获批的工作流程选项、确定的真实数据来源。
  • 有用的历史结果:行之有效的策略、已确认的分类、经过验证的映射关系。即便如此,也需检查其相关性。
  • 简洁的任务摘要:对于复杂工作,一句“已分析文档A,收入确认为X,仍有两处不一致问题未解决”比三十条之前的模型回复更能帮助记忆。
  • 需谨慎存储的内容

    • 每个模型的回复。大多数中间推理过程日后并无用处。
    • 所有工具的输出,这些内容可能体积庞大、已经过时或仅适用于特定时刻。
    • 临时性错误。昨天的超时问题不应成为明天的参考依据。
  • 未经验证的模型假设,是所有问题中最危险的。如果模型称某份文档“似乎提及了公司A”,而无人对此进行验证,将其存储下来就会把一个不确定的猜测变成日后会被不断依据的既定事实。
  • 没有明确理由却仍被保留的敏感数据。内存使用应当有明确目的。
  • 内存也可能出错

    这是长期记忆存在的最大问题之一。系统记录下某客户的报告货币为美元,但六个月后该客户的选择发生了变化,旧记录却依然存在。此时应以哪个为准?内存需要具备时效性概念。有些事实数年有效,有些则仅几分钟有效,一个良好的系统能够区分二者。

    需有生命周期管理,而非简单存储后遗忘

    内存不应永远遵循存储并保留的路径。更现实的循环包括捕获、验证、存储、检索、使用,然后是更新、过期或删除。为此,每个条目可能需要记录创建时间、来源、已确认/未确认标志、最后使用时间、过期规则,以及指向取代它的最新值的链接。写入只是其中一半工作,维护则是另一半。

    数据来源很重要

    假设存在两条记忆记录。一条表明用户偏好的格式是PDF,且用户昨日已明确确认过这一点;另一条则称偏好格式可能是Excel,这是大型语言模型在六个月前推断出的结果。这两条记录不应被赋予同等权重,正因如此,记忆记录最好能标注其来源:是由用户提供、系统生成、模型推断、从文档中提取、工具返回,还是从其他地方复制而来?这样的背景信息能帮助系统判断应对其信任到何种程度。

    置信度也很重要

    “合同似乎在六月到期”与从结构化字段中读取的“合同到期日:2027年6月30日”属于不同类型的表述。前者可视为高可信度信息,而后者则需要进一步验证,因此不能让模糊的结论悄悄变成既定事实。有用的长期记录往往不仅仅包含数值,还可能包含来源、可信度、时间戳、范围和状态等信息,这能让后续检索更加可靠。

    摘要属于解读

    摘要是保持工作记忆容量较小的最佳方法之一。只需存储“用户需要附带示例的简明技术解释”而非完整对话内容,或记录“三项结论已确认,一项尚未解决”而非每一步分析过程。但需要注意的是,摘要属于解读性质,可能会遗漏重要细节。对于重要的工作流程,应将摘要与原始证据链接一起使用。这样既能让智能体高效运作,又能在需要核实时查阅到原始资料。

    不要创建第二个事实来源

    如果客户信息已经存储在主客户数据库中,将其复制到代理的长期记忆中通常是个错误。很快这两个版本的信息就会出现差异,而没人知道哪个才是正确的。更好的做法是将权威系统视为需要时检索信息的来源,并将结果输入到代理的上下文中。除非有非常明确的理由,否则不要重复建立记录系统。判断标准是:这些信息能否从源头可靠地获取,而非依赖记忆。如果可以,那么检索可能比记忆更有效。

    范围

    当多个用户、组织或工作流共享同一代理基础设施时,内存使用就需要有明确的边界。一个用户的内存数据不应出现在另一个用户的上下文中,一个组织也不应获取另一个组织的数据,而且一个工作流通常不需要另一个工作流的中间结果。内存一般需要明确的范围界定,比如全局、组织、用户、对话、工作流或任务。范围越窄,无关信息渗入到不相关决策中的可能性就越小。

    检索内存是一个搜索问题

    由于有500条存储的记忆,没人应该在每个提示中都使用全部。这又回到了上下文问题,因此记忆检索需要独立的流程:先分析当前任务,确定哪种类型的记忆相关,再根据用户、工作流程和组织结构进行筛选,随后进行搜索、排序、选择,并将符合条件的记忆加入工作上下文中。这就是为什么记忆工程与上下文工程如此紧密相关——记忆决定了日后可以使用什么,而上下文工程则决定了当下应使用什么。

    少输入,更高效检索

    不要去想还能存储什么,而应思考哪些信息具有足够的未来价值值得存储。不要纠结提示中能容纳多少记忆,而应考虑哪种记忆与当前决策相关。一个良好的记忆架构通常会让智能体看到更少的内容,因为无关的记忆本质上只是无用的上下文而已。

    可观测性

    假设智能体给出了一个奇怪的答案。检索到的文档看似正常,工具调用也成功了,但答案却有误,最终有人发现是旧记忆影响了决策。如果没有对记忆检索过程的可见性,就很难进行调试。对于每次运行,记录下调用了哪些记忆及其原因、它们的来源和年龄、确认状态、是否被纳入最终上下文以及是否改变了输出结果,这些都有助于解决问题。这样就能将原本隐藏的记忆行为转化为可检查的内容。

    更现实的架构

    不必让所有信息都先进入记忆系统再传递给智能体,可以这样设想:有用户或任务到来后,系统会查询工作流状态,然后决定需要哪些信息。之后它会从不同的来源获取信息:

    • 用于记录当前所需信息的上下文,如当前的请求、最新的工具结果以及目前的决策。
    • 用于存储该工作流程中所需信息的短期记忆,如任务摘要、阶段性发现以及近期的决策。
    • 用于存储可能对未来工作流程有帮助的长期记忆,如稳定的偏好设置、已确认的事实或历史结果。
    • 用于获取来自其他来源的信息的知识与RAG系统,这些信息包括文档、政策、报告和数据库等。
    • 用于记录确定性信息的应用状态,如任务状态、检查点、重试次数以及已完成步骤。

    之后要对这些信息进行过滤、排序和整合,形成当前的上下文,再让智能体进行推理。若将这一切统称为“记忆”,就会掩盖其实际结构。

    在添加记忆功能之前需要考虑的问题

    • 这能帮助未来的任务吗?如果不能,就不要存储它。
  • 能否从权威系统获取该信息?如果可以,使用RAG或普通查询可能更合适。
  • 这是工作流状态吗?应将其置于LLM之外。
  • 它已经过验证了吗?不要将模型的猜测当作永久事实。
  • 它的有效期限是多久?某些记忆需要设置过期时间。
  • 当它发生变化时该怎么办?需明确更新和替换规则。
  • 谁有权限获取它?记忆系统需要设定访问范围和权限。
  • 能否解释为什么它会出现在智能体的上下文中?如果无法解释,调试将会很困难。
  • 模型需要原始数据还是仅总结信息?应保持处理的数据量较小。
  • 通常,这些问题的答案比选择何种记忆数据库更为重要。

    遗忘也是一种特性

    良好的记忆力并不意味着能记住所有事情。一个实用的智能体应当遗忘许多内容:临时的细节、旧的工具运行结果、未经验证的假设、过时的事实,以及那些已不再重要的推理。更多的内存并不会自动让系统变得更聪明,有时反而只会给模型更多将错误信息关联起来的机会。实际上这意味着:只存储日后会有用的事物,用简单的确定性代码来保存工作流程状态,从知识所在的地方获取信息,只让相关的记忆进入提示词中,记录每条记忆的来源,并随着事实的变化更新或删除相关条目。

    数据库的存在是为了存储数据。而智能体的记忆另有用途:在需要时将正确的事实呈现给模型,同时防止旧有的杂乱信息固化成后来的既定事实。