跳转到内容
主站 新闻 控制台

让你的编码智能体拥有一份由你掌控的记忆

· Hugging Face
教程模型卡

我会在多台机器之间切换,并根据任务选择不同的编码代理。

它们中的每一个面对我的项目时都像个陌生人。“上周二”的推理过程会在会话结束时消失。每台新主机上的每个新代理,都只能从零开始。

今年早些时候,《软件会遗忘:代理轨迹就是记忆》一文提出,编码代理已经在生成我们不断丢失的记录。当它们搜索代码库、尝试不同方案、遇到错误、阅读文档并改变方向时,会留下关于“不仅改了什么,而且为什么这样改”的详尽记录。

虽然这个判断是正确的,但轨迹只是潜在的记忆。代理的会话日志仍然只是一个档案。面对一万个交互轮次,你不可能仅靠 grep 找到“我们为什么放弃了流式解析器?”这个问题的答案。要让代理在工作时使用这些轨迹,就需要索引、检索、排序以及精确的来源追踪。

这正是 funes 所提供的功能。它是面向代理的持久化记忆层,支持 Claude Code、Codex、pi 和 Hermes。它基于已经存在于你机器上的会话构建,完全在本地运行,并且只需一条命令,就能成为代理日常工作流的一部分。如果你愿意,它还可以同步到由你拥有的 Hugging Face 数据集,默认保持私有。

为你已经在使用的代理添加记忆

funes 是一个单文件二进制程序。它的默认推理后端不依赖机器学习运行时,嵌入和重排序都在你的机器上完成。安装:

Terminal window
curl -fsSL https://huggingface.co/buckets/huggingface/funes/resolve/install.sh | sh

然后将它添加到代理:

Terminal window
funes add claude # 或:codex、pi、hermes

这个 add 命令会建立首个索引,为代理提供 recall 和 get 工具,并安装自动化机制,对每个已完成的交互轮次建立索引。索引过程是增量式的:新运行只会添加新的交互轮次,而不是重新嵌入整个历史记录。较早且更深层的内容可以分批、受控地补充索引。

从这之后,你只需正常工作。当任务涉及过去的决策、理由或发现时,代理可以自行调用 recall。你不需要记住旧会话,也不需要把旧会话的上下文粘贴到新会话中。

编码代理自行调用 funes,回忆起之前的决策,并基于检索到的会话给出答案

添加 funes 后,回忆过程会发生在对话内部。代理会自行调用记忆,并指出其答案所依据的会话。

recall 返回的是原始文本,而不是摘要,并会准确显示其来源(代理、时间戳、会话和交互轮次)。每条结果都包含一个 get 命令,可打开完整交互轮次及其周边上下文。

在底层,一个确定性的流水线会将所有受支持的轨迹解析为统一的“轮次—区块”结构,对其进行分块,使用固定版本的本地模型生成嵌入,并将其写入本地 Lance 数据集。查询会结合向量搜索和 BM25 搜索,融合二者的排序结果,使用交叉编码器对候选结果进行重排序,根据时间新近度重新加权,并附加相邻区块。

这种设计让 funes 具备三个重要特性:

  • 跨代理共享同一份记忆: Claude Code、Codex、pi 和 Hermes 都会写入同一种结构。recall 可以跨越它们的历史记录进行检索,并且每条命中结果都会说明是哪个代理生成的。

  • 原始证据保持完整: 写入时不会将内容提炼成事实。结果始终可以追溯到生成它的交互轮次。

  • recall 默认在本地运行: 无需账户或 Hub 仓库。托管模型不会处理你的会话来建立索引;嵌入和重排序在你的机器上运行,推理则由你的编码代理完成。

在一台机器上,“代理像个陌生人”这一问题已经解决。但当下一个代理运行在其他地方时,记忆会变得更加有用。

记忆是数据集,而不是服务

要让记忆伴随你的工作,在将 funes 添加到代理时绑定一个记忆:

Terminal window
funes add codex acme/funes-memory

绑定操作会将当前记忆发布到该位置。之后,funes 会在本地为每个交互轮次建立索引,并在会话边界发布更新,从而持续保持记忆最新。代理会一直从中进行回忆。在另一台机器上运行相同的命令,记忆就会跟随你过去。

在底层,本地记忆是一个 Lance 数据集,共享记忆则是一个由你拥有的 Hugging Face 数据集(默认保持私有)。

在任何内容到达 Hub 之前,凭据就已经在索引过程中被脱敏。发布时还会再次扫描每个区块,并拦截任何仍然看起来像机密信息的内容。其背后的扫描器记录在 SECURITY.md 中,其中说明了它覆盖和不覆盖的内容。

当代理读取远程记忆时,funes 会在本地缓存数据集文件,因此缓存预热后的查询速度可以回到本地水平。Hub 提供了它在其他数据集上已有的所有权、访问控制、版本管理和分发能力。你的记忆不会变成某个独立记忆服务中的账户,也不需要通过 API 租回它。

先提问,之后再接入

recall 是专为代理设计的。当你想亲自向记忆提问时,可以使用 ask。默认情况下,它会读取本地记忆:

Terminal window
funes ask claude "我们对流式解析器做了什么决定"

或者,也可以让它指向共享记忆。我们发布了一份关于 funes 开发的记忆,因此你无需创建自己的记忆,就可以询问 funes 为什么采用现在的工作方式:

Terminal window
funes ask claude "为什么 funes 采用仅追加模式" --memory huggingface/funes-memory

询问已发布的 funes 记忆为什么采用仅追加模式;funes 检索相关会话,并由编码代理基于这些会话作答

funes ask 是 funes add 的只读、单问题版本。它会检索相关段落,将这些段落交给编码代理,并返回一个基于证据的答案,同时指出答案来源。它不会安装集成,也不会改变代理的持久化设置。

检索未命中不会被掩盖。如果检索到的段落不足以支持答案,代理会明确说明。你可以改写问题,或者将 funes 添加到代理中,让它在正常工作期间迭代搜索记忆。

切换代理而不丢失上下文

共享记忆并不绑定于创建它的代理或模型。在 Claude Code 中开始一项任务,下周在 Codex 中继续,第二个代理就可以回忆起第一个代理的推理过程。你可以使用本地模型运行 pi,也可以使用由 Hugging Face 路由器提供的模型,然后再回到 Claude。

Claude Code 选择了一个嵌入模型,随后 Codex 在另一个会话中回忆起这一决定

Claude 做出决策;一个钩子将其建立索引;Codex 在另一个会话中回忆起该决策。演示中较早的命中结果,是同一实验更早的记录:仅追加的记忆也记住了此前的演练过程。

这在几个不同的范围内都很重要:

  • 跨机器: 将每个代理绑定到同一份记忆,并从你当前使用的任意主机上检索历史记录。

  • 跨团队: 新团队成员的代理从第一天起就可以检索数月以来的决策,包括 deta