跳到主要内容

生产级 AI Agent 的记忆架构

· 阅读需 12 分钟
Tian Pan
Software Engineer

大多数团队都是事后才给他们的智能体添加记忆功能——通常是在用户抱怨智能体忘记了三轮对话前明确告知的信息之后。那时,解决方案似乎显而易见:把对话存储起来,以后再检索。但这种直觉往往导致系统在演示中表现出色,而在生产环境中却一塌糊涂。一个仅仅存储信息的记忆系统,与一个能在正确的时间可靠地呈现正确信息的系统之间存在巨大鸿沟,大多数智能体项目正是悄然失败于此。

记忆架构并非次要问题。对于任何处理多轮交互的智能体——无论是客户支持、编码助手、研究工具还是语音界面——记忆都是区分有状态助手和昂贵自动补全的关键。如果处理不当,智能体不会崩溃;但它会让人感觉有些不对劲,自相矛盾,或者自信地重复着用户两周前纠正过的过时信息。

你真正需要的四种记忆类型

在寻求向量数据库之前,最好先精确定义“记忆”的含义。生产级智能体至少需要三种独立的记忆系统,而大多数团队会将其合并成一个——这也是检索质量受损的原因。

工作记忆是智能体活跃的上下文窗口。模型在单次推理调用中进行推理的所有信息都存在于此。它快速、零延迟,但容量有限。一旦对话结束,除非明确持久化,否则工作记忆就会消失。

情景记忆存储发生了什么——特定事件、过去的交互、做出的决策、遇到的错误。它按时间和上下文索引:“这个用户在入职引导环节说了什么?”情景检索回答历史问题,让智能体无需每次都从头学习,从而适应个体用户。

语义记忆存储智能体知道什么——事实、领域知识、用户偏好、积累的泛化知识。它回答的是“关于这个用户或领域,什么是真实的?”,而不是“具体发生了什么?” 用户对简洁回复的偏好属于语义记忆;而他们表达这种偏好的对话则属于情景记忆。

程序记忆捕获如何做事——工作流程、决策启发式方法、成功的解决方案模式。这是最不常实现但随着智能体被期望能随时间改进而变得越来越重要的记忆类型。一个智能体如果能学习哪种调试方法适用于特定的代码库,它就是在利用程序记忆。

大多数团队只构建情景存储(对话历史)就认为大功告成。结果是智能体只能引用过去的对话,却无法从中进行泛化。

生产中的准确性/延迟陷阱

向量相似度搜索是记忆检索的标准方法,它创造了一个诱人的陷阱:你总是可以通过存储更多上下文和检索更多块来提高准确性。LOCOMO 基准测试标准化了不同竞争方法之间的记忆评估,用具体数据说明了为什么这在实践中会失败。

全上下文检索——即将所有存储的历史信息塞入上下文窗口——在基准测试中达到了 72.9% 的准确率。选择性记忆流水线达到了 66.9% 的准确率。6 个百分点的差距看起来像是全上下文方法的明显胜利,直到你查看延迟数据:全上下文方法在 P95 达到 17.12 秒,而选择性检索为 1.44 秒。这是 12 倍的延迟差异。

对于语音智能体,用户无法回溯并期望接近实时的响应,无论其准确率多高,全上下文检索都不是一个可行的选择。对于任何面向客户的界面,17 秒的响应时间会在更高准确性变得明显之前就赶走用户。

实用的经验是:记忆检索必须同时从至少两个维度进行评估——质量和延迟。只优化一个而忽视另一个会产生在基准测试中表现良好但部署效果差的系统。

为什么仅凭向量搜索还不够

普通的向量相似度检索在生产中持续出现三种常见的失败模式:

有相关性但缺乏精确性。 语义搜索返回的是主题相关但并非特别相关于当前查询的块。用户询问“我昨天遇到的错误是什么?”,结果检索到所有提及错误的信息,而不是上一次会话中的特定异常。添加一个重排序层——一个在完整查询的上下文下重新评估检索到的候选结果的第二遍模型——能显著提高精确性,并且现在已成为生产级记忆系统中的标准做法。

缺乏时间上下文。 向量数据库本身不理解信息何时存储或其有多旧。关于用户两年前工作的信息会与上周的信息以相同的置信度被检索出来,即使用户已经改变了职位。如果没有显式的时间戳元数据和过滤,陈旧性是不可见的。

身份碎片化。 大多数记忆系统假设用户 ID 稳定不变。真实用户会从多个设备进行交互,在认证会话和匿名会话之间切换,偶尔还会创建重复账户。当同一个用户有三个相互独立的记忆存储时,个性化体验就会悄然下降。这是基础设施层面的未解决问题——目前处理它的团队都是通过在其之上附加的应用层身份解析逻辑来实现的。

生产级检索结合了稠密向量搜索、稀疏关键词检索 (BM25)、基于时间范围和作用域的元数据过滤以及重排序步骤。每个组件都解决一种不同的失败模式;移除其中任何一个都会留下空白。

图记忆:当关系至关重要时

过去一年,图增强记忆已从研究兴趣走向生产可行性,与向量记忆的区别值得我们精确理解。

向量存储可以告诉你:“这个用户提到了 Python。”图存储可以告诉你:“这个用户使用 Python,特别是用于数据管道,他使用 pandas,在一家运行 dbt 的公司工作,该公司有一个六人的数据工程团队,其中两人最近刚加入。”

向量相似性检索的是语义相关的事实。图检索则追踪实体之间的关系——人、工具、项目、组织以及它们之间的连接。对于这些关系至关重要的领域——医疗保健(患者-病情-药物图)、软件(项目-依赖-团队层级)、客户管理(联系人-公司-交易链)——图记忆能产生质量更高的推理。

代价是延迟。对于复杂的多次跳转查询,图增强检索的 p95 延迟约为 2.59 秒,而纯向量方法为 1.44 秒。实用建议是:当领域存在有意义的实体关系且多次跳转推理能提高回答质量时,启用图记忆;对于向量检索就足够使用的、基于偏好的简单个性化,则无需启用。

异步写入作为默认模式

生产团队达成共识的一个架构决策是:记忆写入绝不应阻塞智能体的响应。

简单的实现是同步写入记忆——智能体完成响应,写入记忆存储,然后返回给用户。这会在每次对话中增加可测量的延迟,即使是在没有说过值得记忆内容的回合。它还会导致一种局部故障模式,即缓慢的记忆写入会延迟用户正在等待的响应。

正确的模式是异步写入记忆。智能体响应返回后,一个后台进程处理抽取、去重和存储。用户从不等待记忆写入。如果写入暂时失败,可以重试,不影响交互。

这意味着:在任何给定时刻,智能体的状态可能不反映最近的对话,如果该写入尚未完成的话。对于大多数用例,这种最终一致性是可以接受的。对于最新对话状态必须立即可用的用例——例如人工交接系统、合规日志——可能需要同步写入,但这应该是一个明确的决策,而非默认行为。

多智能体记忆:归因问题

单智能体记忆相对容易处理。多智能体记忆引入了一个大多数团队后期才发现的问题:当多个智能体共同参与一个共享对话时,谁的推断应该被存储为事实?

设想一个编排智能体,它将任务委托给一个研究智能体,后者返回一个摘要。如果该摘要在没有归因的情况下存储在记忆中,记忆系统会将一个推断——可能是幻觉——视为事实真相。当未来的智能体检索到它时,它会像用户陈述了一个事实一样进行推理。

解决此问题的模式是:用其源行为者标记存储的记忆。用户陈述、智能体推断、工具结果和外部数据检索,它们各自带有不同的置信水平和不同的刷新要求。在做出下游决策时,标记为“用户陈述”的记忆应与标记为“智能体推断”的记忆区别对待。

这听起来像是显而易见的工程规范,但大多数记忆框架默认不实现它。结果是,记忆存储中存储事实的出处是不可见的,这使得在不重新运行原始来源的情况下,无法推理其置信度或时效性。

陈旧性问题尚无干净利落的解决方案

长期记忆最困难的操作挑战是陈旧性——记忆在存储时是准确的,但此后变得错误。与智能体根本不知道的缺失信息不同,陈旧信息更糟:智能体自信地应用过时的事实。

常见的暴露此问题的情形:

  • 用户的雇主、团队或角色发生变化,而智能体仍然引用旧的上下文
  • 用户的偏好发生变化,而智能体仍然应用旧的默认设置
  • 智能体学到的领域知识被新的发展所取代

当前的所有方法都涉及权衡。基于时间的过期机制按计划删除旧记忆,这会丢弃有用的信息。置信度衰减降低旧记忆的检索权重,这有所帮助但未能根除问题。矛盾检测——使用辅助过程识别新信息与存储事实冲突时——能捕获明确的更正,但会错过渐进的漂移。

目前还没有健壮的自动化解决方案。实践中有效的方法是:设计你的记忆图式以包含时间戳和新近度信号,对用户陈述的偏好设置比领域事实更短的 TTL(存活时间),并通过明确的界面向用户暴露记忆状态,以便他们可以纠正错误,而不是疑惑智能体为何一直犯同样的错误。

实现记忆:决策框架

在选择工具之前,先确定你究竟要解决什么记忆问题:

如果你的代理处理的是单会话任务,且没有跨会话的连续性要求,那么你根本不需要记忆层。仔细的上下文窗口管理就足够了。

如果你需要跨会话的个性化功能——记住用户偏好、过往决策和交互模式——那么从情景记忆和语义记忆开始。使用带有重排的向量检索,从一开始就添加元数据过滤,并异步写入。

如果你的领域涉及对推理很重要的复杂实体关系(例如医疗保健、账户管理、软件依赖图),那么添加图记忆,但前提是验证仅使用向量检索确实不足以满足需求。

如果你正在构建多代理系统,请在系统投入生产之前实现代理感知的记忆标记。事后补救要困难得多。

一个值得内化的基准测试结果是:一个实现 72.9% 准确率但 p95 延迟为 17 秒的系统,并不比一个实现 66.9% 准确率但 p95 延迟为 1.4 秒的系统更好——这是一种不同的权衡,对于大多数生产环境来说是错误的。记忆架构是一个工程问题,而不是一个基准优化问题。正确的设计取决于你的延迟预算、查询模式、领域结构和容错能力。这些答案来自于理解部署环境,而不是在笔记本电脑上运行 LOCOMO。

基础设施是怎样的

在稳定状态下,生产代理的记忆基础设施包括:

  • 一个用于语义搜索的向量存储(Pinecone、Weaviate、pgvector,或任何适合你现有技术栈的——目前没有绝对的赢家)
  • 一个重排模型(交叉编码器或基于 RRF 的)以提高检索精度
  • 一个元数据层,用于时间戳、代理归属和范围过滤
  • 异步写入管道,使记忆持久化脱离关键路径
  • 可选的图层,用于处理具有实体关系的领域

趋势是走向统一的基础设施,通过单一系统处理短期和长期记忆,而不是为每种记忆类型使用单独的数据库。这降低了操作复杂性,并支持跨记忆类型的协调检索,而无需向多个系统发出多个查询。

记忆就是基础设施。它需要像设计数据存储选择一样精心设计,而不是从手边最近的检索组件拼凑而成。做得好的团队从一开始就将其视为一流的架构问题,而不是在代理发布后才附加的功能。

References:Let's stay in touch and Follow me for more thoughts and updates