MemoryLake
返回全部文章
News2026 年 9 月 4 日·12 分钟阅读

索引会话日志召回的是你曾说过的话,而非依然正确的事实 (2026)

你的编程智能体几个月来一直在详细记录你的项目。每一次搜索、每一个死胡同、每一次推翻重来、每一次“其实,我们别用那种方法了”——所有这些都保存在你电脑里的会话日志中,却毫无用处。

2026年9月3日,Hugging Face 发布了 funes,这是一个开源工具,可以将这些日志转化为智能体可以查询的内容。它支持 Claude Code、Codex、pi 和 Hermes,在本地运行,并且每个智能体只需一条命令即可完成设置。这个想法很好,执行也十分周到。

它还做出了一个设计选择,该项目明确将其列为一项特性,而理解这一选择正是本文的核心所在:

"原始证据保持完整: 在写入时不会将任何内容提炼为事实。结果总是可以追溯到产生它的那一轮对话。"

没有进行任何提炼。这为你提供了完美的溯源——但也意味着没有任何内容得到修正。你的归档忠实地保存了你在三月份推翻的决定,以及取而代之的新决定。你具体需要这两者中的哪一个,取决于你所问的问题,而这两个问题看起来几乎一模一样。

在开始之前,先划定一个界限。这并不是 RAG 与记忆(memory)之争——那是关于检索文档的,为什么 RAG 不是记忆一文已经对此进行了探讨。这里讨论的是检索你自己的对话,这是一个不同的对象,有着不同的失效模式。

聊天记录索引究竟做了什么

诊断是正确的,而且该项目自己最先指出了这一点

funes 在开头引用了先前的论点并对其进行了限定,这比大多数工具的开端都要好:

"虽然诊断是正确的,但追踪记录只是潜在的记忆。智能体的会话日志仍然只是一个归档。你无法通过 grep 在一万轮对话中找出‘我们为什么要放弃流式解析器?’。为了让智能体在工作时使用这些追踪记录,它们需要索引、检索、排序和精确的溯源。"

其中的每一句话都是对的。归档不是记忆。Grep 无法扩展到一万轮对话。而它提到的四件事——索引、检索、排序、溯源——正是将一堆日志转化为可用之物的关键。

文档中描述的机制

写入路径是确定性的:“一个确定性的管道将每个支持的追踪记录解析为相同的‘轮次与块’(turn-and-block)形状,对其进行分块,使用固定的本地模型进行嵌入,并将其写入本地 Lance 数据集。”

读取路径是混合的:“查询结合了向量和 BM25 检索,融合它们的排序,使用交叉编码器(cross-encoder)对候选结果进行重排序,根据时间近度(recency)重新计算权重,并附带邻近的分块。”

设置只需每个智能体一条命令,即可“构建第一个索引,为智能体提供 recall 和 get 工具,并安装自动对每个完成的轮次进行索引的自动化程序。”索引是增量式的——“新运行添加新轮次,而不是重新嵌入整个历史记录”——较旧的内容能够“在有限的步骤内进行回填”。

返回的内容是未经处理的:“recall 返回的是原始文本,而不是摘要,并准确显示其来源(智能体、时间戳、会话和轮次)。”

值得肯定的三个特性

该项目列出了三个特性,且这三个特性都是真实存在的。

跨智能体覆盖。 “Claude Code、Codex、pi 和 Hermes 都写入相同的形状。recall 跨越它们的历史记录,每次命中都会说明是由哪个智能体产生的。”在四个智能体之间采用统一的标准化形状确实非常有用,这与跨智能体记忆这一类别的初衷是一致的。

默认本地。 “不需要账号或 Hub 仓库。托管模型不会为了索引而处理你的会话;嵌入和重排序在你的机器上运行,而你的编程智能体负责推理。”对于任何无法将聊天记录发送给第三方的人来说,这不仅是一种偏好,而是一项硬性要求。

所有权。 将记忆绑定到数据集,然后“在另一台机器上运行相同的命令,记忆就会随你迁移到那里”,Hub 则提供“它已经为其他数据集提供的所有权、访问控制、版本控制和分发功能”。

还有一个专门描述的凭证处理步骤:“在任何内容到达 Hub 之前,凭证在索引期间就已经被脱敏。发布时会再次扫描每个分块,并扣留任何看起来仍像机密的内容。”该项目指向其自身的 SECURITY.md 以说明“它涵盖和不涵盖的内容”,这是记录扫描器的正确方式。

这改变了什么,又没有改变什么

它确实彻底解决了一个问题。 “关于流式解析器我们说了什么?”现在可以在几秒钟内得到解答,而不是根本无法回答。如果你的问题是关于记录的——讨论了什么、何时讨论、由哪个智能体讨论、用了什么词——那么索引归档就是正确的工具,且无可替代。

它无法回答一个看起来几乎相同的问题。 “我们对解析器的约定是什么?”是一个不同的查询。归档包含了任何人针对解析器发表过的每一条言论,包括你已经放弃的、曾热烈探讨了三个小时的方法。相关性排序不知道其中哪一个是目前有效的,因为在写入时没有任何记录表明一个决定已经取代了另一个。

时间近度重加权有所帮助,但无法解决问题。 管道“根据时间近度重新计算权重”,这是一个正确的启发式方法,但只是部分解决。在四条简短的消息中被推翻的决定,其文本权重低于之前冗长、详细但错误的讨论。时间近度只是微调,而文本量依然占据主导。

It does not distinguish a decision from a musing. 聊天记录以相同的忠实度记录了“也许我们应该切换到 X”和“我们正在切换到 X”。两者都是对话轮次。两者都被索引。两者都没有被标记。

它确实改变了整理工作的发生位置,而不是改变了是否需要整理。 由于没有写入时的提炼,决议——这是当前的,那是被替代的——必须在读取时、在智能体的推理中、在每一次查询时发生。这行得通,但这也是在无限重复工作,而不是一劳永逸。

它对自己的适用范围很诚实。 “‘智能体如同陌生人’的问题在单台机器上已经解决。但当下一个智能体在其他地方运行时,记忆会变得更加有用。”这是对本地层涵盖和未涵盖内容的准确描述。

人们会从中得出什么误解,以及为什么不应该

“我的日志本来就是我的记忆,我只需要对它们进行索引。” 只对了一半,项目本身比这更谨慎:“追踪记录只是潜在的记忆。”索引使归档可查询,但并不能使其具有权威性。

“溯源意味着我可以信任答案。” 溯源意味着你可以验证某个说法的来源,这很有价值,但性质不同。一个完美溯源的、关于你后来推翻的决定的引用,虽然溯源完美,但对今天来说却是错误的。

“没有提炼意味着没有信息损失。” 没有证据的损失,但也没有捕获判断。一个陈述取代了另一个陈述的这一认知也是信息,而写入时的提炼通常就是记录这种信息的地方。

“用数据集代替服务就解决问题了。” 该项目明确了这一主张——“你的记忆不会变成独立记忆服务中的一个账户,你也不需要租回它”——这是一种合理的设计立场。但它回答的是关于所有权的问题,而不是关于时效性的问题。你可以完全拥有一个归档,但仍然不知道其中相互矛盾的内容哪一个是有效的。

“所以整理后的记忆只是归档的有损压缩。” 这种对比是双向的,这才是公平的理解方式。归档保留了一切,却什么也没有解决。整理后的存储解决了问题,但其决议可能会出错。成熟的答案是,它们是互补的层,而不是竞争的层——这大致就是 RAG 与存储之争最终得出的结论,正如 AI 记忆对比 RAG 所阐述的那样。

“仅限本地意味着无需考虑任何问题。” 本地化避免了将聊天记录发送给第三方。但它无法避免聊天记录中包含屏幕上出现的任何内容这一事实。凭证脱敏加上发布时扫描是切实可行的缓解措施,但有其记录在案的局限性,而了解这些局限性是采用此类工具的一部分——这也是 AI 记忆安全背后的担忧。

解决方案:将归档用于证据,将存储用于当前答案

第一步:在整理工具之前,先整理你的问题

花十分钟写下你实际上会向智能体询问的关于你自己项目的问题,然后给每个问题贴上标签。

证据类问题是关于记录的。“我们什么时候决定这个的?”“谁提出了反对意见?”“我们上次遇到的错误是什么?”“给我看看我们尝试这个的那一轮对话。”这些问题需要带有溯源的原始文本,索引归档是正确的答案。

状态类问题是关于当下的。“我们这里的约定是什么?”“哪个服务拥有这个?”“那个临时解决方案还需要吗?”这些问题需要一个当前的答案,而归档只会给你一个包含所有曾说过的话的排序列表。

大多数团队的问题大致各占一半,而几乎没有人注意到它们属于两个不同的类别。

第二步:阅读 recall 针对一个状态类问题返回的内容

这是看清这种区别最省钱的方法,而不用光听我的一家之言。

选择一个你们团队确实推翻过的决定。向归档询问该主题——不是询问该决定,而是询问该主题,就像你在实际工作中那样。阅读最上面的结果。

你通常会得到两种立场,按文本相关性排序,并带有时间近度的微调。这正是该工具完全按照设计运行的结果。但这也是一个转折点,在未来的每一次查询中,智能体在面对这两者时,必须从没有明确说明的证据中,决定你到底指的是哪一个。

注意什么能解决这个问题:在某处写上单行说明,指出哪种约定有效以及何时发生了改变。这行字并不在归档中,因为在写入时没有任何机制被要求生成它。

第三步:将决议写下来一次,其余的一切保留在归档中

回答状态类问题的层很小。它不是你聊天记录的副本,也不应该是。

它保存着决议:当前的约定、取代了早期决定的新决定、已废弃的事物仍然存在的原因、内部术语的含义、哪个团队拥有哪个界面。对于大多数项目来说,只需 10 到 50 行,它就不再具有歧义,因为这是由人决定的,而不是由检索猜测的。

保留归档用于证据。当决议需要证明时,带有溯源的聊天记录正是最适合指向的内容——而决议则是你的智能体在周一早上读取的内容。MemoryLake 只需三个步骤即可设置完成。

第一步:创建 API 密钥

登录并在你的仪表板中生成一个 API 密钥。该存储在设计上很小且易读,这正是下一步如此简短的原因。

创建 MemoryLake API 密钥,以便将确定的决议保存在与聊天记录归档分开的地方
创建 MemoryLake API 密钥,以便将确定的决议保存在与聊天记录归档分开的地方

第二步:上传你的第一批记忆

编写决议,而不是历史:当前的约定、标记为已被取代的旧决定、领域词汇、所有权、带有原因的约束条件。

将状态类问题的当前答案一次性上传到 MemoryLake
将状态类问题的当前答案一次性上传到 MemoryLake

别管聊天记录。对它们进行索引是一项独立且值得做的工作,而这一层并不试图取代它。

第三步:连接你的 AI 和智能体

将你的智能体指向该存储。状态类问题得到一个当前的答案,证据类问题转到归档,两者都不需要做对方的工作——这就是为什么长上下文不是记忆中这一论点在更高一层抽象上的版本。

通过 MCP 和 API 将编写这些聊天记录的智能体连接到 MemoryLake
通过 MCP 和 API 将编写这些聊天记录的智能体连接到 MemoryLake

这在实践中改变了什么

第一个改变是,“智能体建议了我们已经停止做的事情”变得可以解释了。这并不是检索失败。归档中包含了这两个答案,并且没有任何内容将其中一个标记为已被替代。

第二个改变是,对你的日志进行索引显然变得非常值得,因为你不再对其抱有错误的期望。一个能够很好地回答证据类问题的归档是一笔真正的资产。

第三个改变是,决议层保持足够小以供审查。一个人可以阅读并纠正 50 行当前的约定;但一万轮对话却无法做到,这就是为什么在智能体记忆中保留更少的内容通常优于保留更多内容的原因。

使用索引会话归档的最佳实践

  • 标记你的问题。 证据类问题需要记录;状态类问题需要一个答案。
  • 预期结果中会出现矛盾,而不是决议。 由于在写入时没有提炼任何内容,推翻前后的两面都会被同等索引。
  • 不要仅仅依赖时间近度。 它只是重新计算权重,并不进行裁决,简短的决定在文本量上会输给冗长的探索。
  • 将溯源用于其擅长的地方。 验证某个说法的来源,而不是确定它是否依然有效。
  • 阅读安全文档。 凭证脱敏和发布时扫描是真实存在的,且有记录在案的覆盖范围限制。
  • 单独写下决议。 被取代的决定应该在产生它的聊天记录之外的某个地方进行说明。
  • 保持决议层简短。 如果它长到没有人去审查,它就会像归档一样发生漂移。
  • 将这两层视为互补。 证据和当前状态是不同的工作,一个工具如果两者都做,就两边都做不好。

结论

对你的会话日志进行索引是一个好主意,而且构建它的团队对这一论点的阐述比大多数相关报道都要更为谨慎。归档不是记忆;索引、检索、排序和溯源使其变得有用。

但它们无法使其保持最新。“在写入时不会将任何内容提炼为事实”是对真实权衡的诚实描述:你得到了你曾说过每一个字,却没有记录哪些字依然有效。保留归档用于证据,将你的决议写在足够小、易于阅读的地方,不要再让其中任何一个去做另一个的工作。

常见问题

我的智能体会话日志本身就是记忆吗?

它们本身并不是。正如 funes 所说,“追踪记录只是潜在的记忆。智能体的会话日志仍然只是一个归档”,在工作中使用它们“需要索引、检索、排序和精确的溯源”。索引使归档可查询,但并不能使其内容保持最新。

“写入时不提炼任何内容”实际上让我付出了什么代价?

判断力。这一特性被宣称为一项优势——“原始证据保持完整:在写入时不会将任何内容提炼为事实”——而代价是,没有任何步骤记录两个相互冲突的陈述中哪一个取代了另一个。这种决议被转移到了读取时,发生在每一次查询中。

按时间近度排序不能解决过时决定的问题吗?

只能部分解决。查询管道“根据时间近度重新计算权重”,这是一个正确的启发式方法。但它无法战胜文本量:在几条简短消息中被推翻的决定,其携带的文本信号少于对它所替代的方法的冗长讨论。

本地索引比托管记忆服务更安全吗?

它消除了一类泄露风险——“嵌入和重排序在你的机器上运行”,且没有托管模型处理你的会话。但它无法消除聊天记录中包含屏幕上出现的任何内容这一事实。索引期间的凭证脱敏加上发布时扫描是记录在案的缓解措施,且有记录在案的局限性。

我应该对日志进行索引,还是整理一个记忆存储?

两者都需要,用于不同的问题。索引用于证据:说了什么、何时说、由哪个智能体说、用了什么词。整理用于状态:现在什么是正确的。它们是不同的对象,这种区别与 AI 记忆对比向量数据库中划定的区别相同。

整理层需要有多大?

比人们预期的要小。它保存的是决议而不是历史——当前的约定、标记为已被取代的旧决定、词汇表、所有权、带有原因的约束条件。对于大多数项目来说,这只有几十行,而保持简短正是使其可审查的关键。