智能体记忆的核心不是存储位置,而是区分产物(历史记录)与知识(当前真相),将知识视为基于产物的物化视图,并按缓存逻辑决定物化哪些知识——记住比重新发现更便宜的内

DEVIN STEIN(@DEVSTEIN64)教程 · 已翻译 · 约 8 分钟
阅览室 · AI 最佳实践#知识#记忆#智能体#存储原文

在本系列的第一篇文章中,我们将智能体的记忆拆解为四个部分:表示与存储、提取、检索和维护。如果你熟悉数据库,可以大致将它们类比为CRUD操作。知识是如何存储的?如何写入?如何再次找到?又如何保持最新?

这篇文章讨论的是第一个问题:智能体的知识实际上存放在哪里?

显而易见的答案是在数据库中。但这有点操之过急了。在决定把知识放在哪里之前,我们首先需要确定这些知识实际上是什么样子的。

记忆是什么样子的?

在存储这个说法背后,其实藏着两个独立的决策。第一个是表示:知识本身的形态。第二个是物理存储:承载知识的系统。

一段记忆可以是一段Markdown文本、一组事实、一个主题层级结构,或者一张连接实体与关系的图。其中任何一种都可以存放在文件、Postgres、向量数据库或更专门的系统中。这种区分很重要,因为存储相对容易替换,而你选择的表示方式决定了智能体如何理解并交互这些知识。

在光谱的最简单一端,记忆就是纯文本。比如AGENTS.md、CLAUDE.md、之前会话的转录,或提取出的事实列表。在此基础上,你可以开始添加关系:产品有功能,GitHub issue由拉取请求关闭,事实属于某个主题。这些关系可以形成简单的树状结构,或更丰富的图结构。

在实践中,大多数记忆系统最终会结合使用这些方法。没有一种表示方式能在所有场景下都胜出。

文件能带来的惊喜远超想象

存放代理记忆的方式多种多样。你可以将少量信息直接注入上下文窗口,将数据嵌入向量数据库并通过语义搜索检索,在图形数据库中建立关系,或者赋予代理SQLite或Postgres权限,让它用SQL查询自己的记忆。

或者,你也可以把知识放在一个目录里。

最后这个选项听起来简单得几乎不可信,但它已成为代理系统中最实用的模式之一。第一代LLM应用将检索等同于RAG:嵌入一切,存入向量数据库,按语义相似度搜索。

随后,编码代理在bash操作上变得异常娴熟。

它们能浏览目录、运行grep和rg、跟随链接、检查文件名,并并行读取多个文件。文件系统不仅是存储信息的便捷之所,更是当今编码代理已极为熟悉的接口。

因此,如果你从零开始构建代理记忆,文件往往是一个很好的起点。但更棘手的问题不在于文件存放何处,而在于你往里面放什么内容。

区分事实与真相

在Dosu,我们发现将记忆划分为两大类别颇为有用:产物与知识。

产物是所发生事件的记录。一条Slack线程即是一个产物。拉取请求、Linear工单、会议记录、设计文档或代理会话追踪同样如此。它们之所以有价值,在于其高保真度并保留了原始背景,但未必代表真相。

一份设计文档可能描绘了从未实现的架构。一段Slack对话可能解释了一年前某事物的运作方式。一张工单能告诉你功能为何创建,却未必说明该功能如今如何运作。

产物是证据。知识则是你的代理当前应视为真实的内容。

这一区分至关重要,因为有用的记忆几乎总涉及抽象化。我们不希望代理每次理解系统运作原理时,都要重读六个月的Slack记录。我们期望将全部历史转化为简洁且有用的信息。

借用数据库的类比,你可以将知识视为基于产物的物化视图。产物保留了发生之事;知识捕捉了当前重要之事。

关键在于保持两者间的联系。每当你要求LLM总结对话、提取事实或整合多个来源时,你都在进行有损转换。部分信息会消失,这无妨。丢失信息往往正是抽象化之所以有用的原因。

问题在于当你丢弃了源头。相反,知识应指向生成它的产物。多数情况下,代理可采取快捷路径:这是我们当前所相信的。但当具体细节至关重要时,它能深入探究并回答诸如此类的问题:我们为何相信这一点?这一变化何时发生?最初的讨论是什么?

这让你在享受抽象带来的效率的同时,又不失对底层历史的忠实还原。

而一旦知识被规范化,另一个问题便立刻浮现:它可能会过时。

知识需要版本控制

工件是历史性的。一旦某事发生,便已成定局。知识则不同。它代表世界的当前状态,而世界在不断变化。

如果今天你的记忆说认证使用API密钥,而明天团队迁移到OAuth,那么旧记忆就不仅仅是没那么有用了,而是错误的。

这也是Git为何成为知识管理的理想心智模型的原因之一。Git不仅告诉你文件现在长什么样,还告诉你它是如何变化的。你可以查看历史、查看差异,并重建过去某个时间点的真实状态。

但Git中还有一个概念,对智能体记忆而言可能更为重要:分支。

想象一个智能体在功能分支上实现OAuth。组织的当前知识说认证使用API密钥,但任务进行到一半时,智能体已经改变了系统,在其工作分支内,OAuth现已得到支持。这两种说法都是正确的,取决于你观察的是哪个版本的世界。

第二个事实不应成为组织知识,直到功能真正合并。智能体真正需要的是共享的组织知识,加上一个临时的、特定于任务的覆盖层,代表它当前正在操作的世界。

然后,当代码合并时,知识也可以随之合并。

随着智能体承担更长期、更自主的工作,我认为这将成为越来越重要的需求。我们不仅需要更新记忆,还需要分支、合并和调和知识

当然,这听起来意味着需要维护更多的知识,这引出了下一个问题:我们究竟应该存储多少?

知识即缓存

人们很容易想象理想的智能体记忆系统是那种能记住一切的系统。我认为这是错误的目标。

人工制品相对容易保存。一条Slack消息发生了,就存储它。一次智能体会话发生了,就存储它。无需不断更新历史记录。

知识有维护成本。一旦你创建了关于认证系统如何工作的权威解释,你就创造了一个需要与认证系统保持同步的东西。将这个逻辑乘以大型组织中的每个功能、服务、客户工作流、决策、惯例和内部流程,你就构建了一个非常昂贵的维护问题。

思考智能体知识的更好方式,是将其视为缓存。缓存存在是因为某些信息重新计算代价高昂,而智能体知识与此类似。

想象一个智能体花费二十分钟追踪十二个服务之间的调用,以理解你的计费架构如何运作。这是获取成本高昂的上下文。如果接下来的二十个智能体都要重复同样的调查,那就保存结果。

现在想象智能体需要知道某个服务运行在哪个端口上,而答案就在一个显而易见的配置文件中。直接读取文件即可。创建并维护该事实的第二个表示,可能比重新计算它更昂贵。

这为我们提供了一个有用的框架,用于判断什么应放入记忆。有些知识是不可替代的:人类说,“我们不能移除这个行为,因为我们最大的客户依赖它。”这个事实可能在其他任何地方都不存在。如果你不捕捉它,它就消失了。

有些知识重新计算成本高昂:一个代理要搜索二十个文件、三个服务和六段历史讨论才能理解某件事。这正是值得固化的候选对象。而有些知识则频繁被使用。即便单次发现并不特别昂贵,反复重新发现也会造成不必要的成本。

其余一切都可以视为缓存未命中。

目标并非让代理记住所有东西,而是让它们记住那些“记住比重新发现更划算”的内容。

从简单开始

如今审视代理记忆领域,很容易得出结论:你需要图数据库、向量搜索、时间关系、本体论,以及一套新的基础设施,才能起步。

你可能并不需要。

如果今天从零构建一个内部记忆系统,我会从 Git 中的文件开始。代理已经知道如何使用它们,人类也知道如何检查它们。你免费获得历史和差异记录,而且不必在了解真正重要的事项之前预测所有未来需求。

然后观察它在何处失效。如果代理难以找到正确信息,改进检索;如果关系变得重要,增加更多结构;如果代理反复执行相同的昂贵研究,固化结果;如果规范知识变化太快难以手动维护,构建更好的维护系统。

如果你不想考虑这些,直接用 Dosu 就行。这正是我们投入时间解决的问题。

代理记忆行业在这里经历了一个有趣的循环。我们从日益复杂的检索和图架构起步,然后重新发现:把一堆组织良好的 Markdown 文件放进仓库,效果出奇地好。

我不认为这意味着 Markdown 是代理记忆的最终形态。它意味着复杂性应当被赢得,而非预设。

从最简单、能用的表示开始。保留底层产物。将值得维护的知识具体化。让系统中的失败告诉你下一步该增加何种复杂度。

当然,决定知识应该呈现为何种形态、存放在何处,只是问题的一半。无论如何,这些知识首先得被写入那里。

这就是我们接下来要深入探讨的:智能体如何捕获知识并将其写入记忆。

dosu.dev

已读完 · 本文由熊猫易读翻译重排