我会在多台机器之间切换,并根据任务选择不同的编码代理。
它们中的每一个面对我的项目时都像个陌生人。“上周二”的推理过程会在会话结束时消失。每台新主机上的每个新代理,都只能从零开始。
今年早些时候,《软件会遗忘:代理轨迹就是记忆》一文提出,编码代理已经在生成我们不断丢失的记录。当它们搜索代码库、尝试不同方案、遇到错误、阅读文档并改变方向时,会留下关于“不仅改了什么,而且为什么这样改”的详尽记录。
虽然这个判断是正确的,但轨迹只是潜在的记忆。代理的会话日志仍然只是一个档案。面对一万个交互轮次,你不可能仅靠 grep 找到“我们为什么放弃了流式解析器?”这个问题的答案。要让代理在工作时使用这些轨迹,就需要索引、检索、排序以及精确的来源追踪。
这正是 funes 所提供的功能。它是面向代理的持久化记忆层,支持 Claude Code、Codex、pi 和 Hermes。它基于已经存在于你机器上的会话构建,完全在本地运行,并且只需一条命令,就能成为代理日常工作流的一部分。如果你愿意,它还可以同步到由你拥有的 Hugging Face 数据集,默认保持私有。
为你已经在使用的代理添加记忆
funes 是一个单文件二进制程序。它的默认推理后端不依赖机器学习运行时,嵌入和重排序都在你的机器上完成。安装:
curl -fsSL https://huggingface.co/buckets/huggingface/funes/resolve/install.sh | sh然后将它添加到代理:
funes add claude # 或:codex、pi、hermes这个 add 命令会建立首个索引,为代理提供 recall 和 get 工具,并安装自动化机制,对每个已完成的交互轮次建立索引。索引过程是增量式的:新运行只会添加新的交互轮次,而不是重新嵌入整个历史记录。较早且更深层的内容可以分批、受控地补充索引。
从这之后,你只需正常工作。当任务涉及过去的决策、理由或发现时,代理可以自行调用 recall。你不需要记住旧会话,也不需要把旧会话的上下文粘贴到新会话中。
添加 funes 后,回忆过程会发生在对话内部。代理会自行调用记忆,并指出其答案所依据的会话。
recall返回的是原始文本,而不是摘要,并会准确显示其来源(代理、时间戳、会话和交互轮次)。每条结果都包含一个get命令,可打开完整交互轮次及其周边上下文。
在底层,一个确定性的流水线会将所有受支持的轨迹解析为统一的“轮次—区块”结构,对其进行分块,使用固定版本的本地模型生成嵌入,并将其写入本地 Lance 数据集。查询会结合向量搜索和 BM25 搜索,融合二者的排序结果,使用交叉编码器对候选结果进行重排序,根据时间新近度重新加权,并附加相邻区块。
这种设计让 funes 具备三个重要特性:
-
跨代理共享同一份记忆: Claude Code、Codex、pi 和 Hermes 都会写入同一种结构。
recall可以跨越它们的历史记录进行检索,并且每条命中结果都会说明是哪个代理生成的。 -
原始证据保持完整: 写入时不会将内容提炼成事实。结果始终可以追溯到生成它的交互轮次。
-
recall默认在本地运行: 无需账户或 Hub 仓库。托管模型不会处理你的会话来建立索引;嵌入和重排序在你的机器上运行,推理则由你的编码代理完成。
在一台机器上,“代理像个陌生人”这一问题已经解决。但当下一个代理运行在其他地方时,记忆会变得更加有用。
记忆是数据集,而不是服务
要让记忆伴随你的工作,在将 funes 添加到代理时绑定一个记忆:
funes add codex acme/funes-memory绑定操作会将当前记忆发布到该位置。之后,funes 会在本地为每个交互轮次建立索引,并在会话边界发布更新,从而持续保持记忆最新。代理会一直从中进行回忆。在另一台机器上运行相同的命令,记忆就会跟随你过去。
在底层,本地记忆是一个 Lance 数据集,共享记忆则是一个由你拥有的 Hugging Face 数据集(默认保持私有)。
在任何内容到达 Hub 之前,凭据就已经在索引过程中被脱敏。发布时还会再次扫描每个区块,并拦截任何仍然看起来像机密信息的内容。其背后的扫描器记录在 SECURITY.md 中,其中说明了它覆盖和不覆盖的内容。
当代理读取远程记忆时,funes 会在本地缓存数据集文件,因此缓存预热后的查询速度可以回到本地水平。Hub 提供了它在其他数据集上已有的所有权、访问控制、版本管理和分发能力。你的记忆不会变成某个独立记忆服务中的账户,也不需要通过 API 租回它。
先提问,之后再接入
recall 是专为代理设计的。当你想亲自向记忆提问时,可以使用 ask。默认情况下,它会读取本地记忆:
funes ask claude "我们对流式解析器做了什么决定"或者,也可以让它指向共享记忆。我们发布了一份关于 funes 开发的记忆,因此你无需创建自己的记忆,就可以询问 funes 为什么采用现在的工作方式:
funes ask claude "为什么 funes 采用仅追加模式" --memory huggingface/funes-memory
funes ask是funes add的只读、单问题版本。它会检索相关段落,将这些段落交给编码代理,并返回一个基于证据的答案,同时指出答案来源。它不会安装集成,也不会改变代理的持久化设置。检索未命中不会被掩盖。如果检索到的段落不足以支持答案,代理会明确说明。你可以改写问题,或者将 funes 添加到代理中,让它在正常工作期间迭代搜索记忆。
切换代理而不丢失上下文
共享记忆并不绑定于创建它的代理或模型。在 Claude Code 中开始一项任务,下周在 Codex 中继续,第二个代理就可以回忆起第一个代理的推理过程。你可以使用本地模型运行 pi,也可以使用由 Hugging Face 路由器提供的模型,然后再回到 Claude。
Claude 做出决策;一个钩子将其建立索引;Codex 在另一个会话中回忆起该决策。演示中较早的命中结果,是同一实验更早的记录:仅追加的记忆也记住了此前的演练过程。
这在几个不同的范围内都很重要:
-
跨机器: 将每个代理绑定到同一份记忆,并从你当前使用的任意主机上检索历史记录。
-
跨团队: 新团队成员的代理从第一天起就可以检索数月以来的决策,包括 deta


