给编码代理一份由你拥有的记忆

我在多台机器上工作,并按任务切换编码代理。每个代理接触我的项目时都像陌生人。“上周二”的推理在会话结束后消失。每个新代理,在每台新主机上,都从零开始。

今年早些时候,《Software Forgets: Agent Traces Are the Memory》提出,编码代理已经生成了我们不断丢失的记录。它们搜索代码库、尝试方案、遇到错误、阅读文档并改变方向时,留下了密集的记录,说明的不只是改了什么,还有为什么要改。

这个诊断是正确的,但轨迹仅是潜在的记忆。代理的会话日志仍只是档案。面对一万轮对话,你不能靠 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    # or: codex, pi, hermes

这一个 add 命令会建立首次索引,为代理提供 recall 和 get 工具,并安装对每个已完成轮次进行索引的自动化。索引是增量的:新的运行添加新的轮次,不必再次对全部历史生成嵌入。年代更早、内容更深入的记录可以分成有界步骤逐步补齐。

接下来照常工作即可。任务涉及以往的决策、理由或发现时,代理可以自行使用 recall。你不必记住旧会话,也不必把上下文粘贴到新会话里。

接入 funes 后,回忆发生在对话内部。代理自行查询记忆,并说明答案背后的会话。

recall 返回原始文本而非摘要,并准确显示出处,包括代理、时间戳、会话及轮次。每个结果都附有 get 命令,可打开完整轮次及其周边上下文。

底层由一条确定性管道,将所有支持的轨迹解析成相同的轮次与块结构,分块,用固定版本的本地模型生成嵌入,再写入本地 Lance 数据集。查询结合向量搜索与 BM25 搜索,融合排序结果,用交叉编码器重排候选,再按新近程度调整权重,并附加相邻块。

这种设计使 funes 具备三个重要性质:

  • **跨代理的同一份记忆:**Claude Code、Codex、pi 和 Hermes 都写入相同结构。recall 搜索它们的历史,每个命中结果都说明来自哪个代理。
  • **保留原始证据:**写入时不会把内容提炼成某条事实。任何结果都可以追溯到生成它的轮次。
  • **默认本地检索:**不需要账户或 Hub 仓库。索引时没有托管模型处理你的会话;嵌入和重排在本机运行,由编码代理进行推理。

在一台机器上,代理像陌生人的问题已经得到解决。但当下一个代理运行在别处时,记忆会变得更有用。

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

要让记忆跟随你的工作,可以在添加 funes 时绑定一份记忆:

funes add codex acme/funes-memory

绑定会把当前记忆发布到那里。随后 funes 持续更新:本地索引每轮对话,在会话边界发布。代理始终可以从中检索。在另一台机器运行同一命令,记忆也会跟随过去。

底层的本地记忆是 Lance 数据集,共享记忆则是你拥有的 Hugging Face 数据集,默认私有。

在任何内容到达 Hub 前,索引过程已经遮蔽凭据。发布时还会再次扫描每个块,暂不发布任何看起来仍像秘密的内容。其扫描器的能力及未覆盖的范围,记录在项目的 SECURITY.md 中。

代理读取远端记忆时,funes 会在本地缓存数据集文件,因此预热后的查询恢复到本地速度。Hub 提供其为其他数据集已有的所有权、访问控制、版本管理与分发能力。你的记忆不会变成另一家记忆服务中的账户,也不必通过 API 把它租回来。

先提问,再接入

recall 面向代理设计。要自己向记忆提问,可使用 ask,默认读取本地记忆:

funes ask claude "what did we decide about the streaming parser"

也可以指定共享记忆。我们发布了 funes 开发过程的记忆,因此你不必先创建自己的记忆,也能询问 funes 为什么这样工作:

funes ask claude "why is funes append-only" --memory huggingface/funes-memory

funes ask 是 funes add 的只读、单问题版本。它检索相关段落,交给编码代理,再返回注明来源、有依据的答案。它不安装集成,也不改变代理的持久设置。

检索落空不会被掩饰。如果段落不足以支持答案,代理会说明。你可以换一种问法,或把 funes 接入代理,使其在日常工作中迭代搜索记忆。

切换代理而不丢失线索

共享记忆不绑定生成它的代理或模型。在 Claude Code 中开始任务,下周在 Codex 中继续,第二个代理就能检索第一个代理的推理。可以使用 pi 配合本地模型,或通过 Hugging Face 路由器提供的模型,再返回 Claude。

Claude 作出决定;钩子将其索引;Codex 在另一会话中检索。演示中较早的命中来自同一实验的早期录制:只追加的记忆连彩排也记住了。

这在几个不同范围内都有意义:

  • **跨机器:**把每个代理绑定到同一份记忆,无论在哪台主机上,都可以检索历史。
  • **跨团队:**新同事的代理在第一天就能检索数月的决策,包括没有写进拉取请求的死路与理由。
  • **伴随开源项目:**维护者可以发布某个版本背后的会话,在推送时注明它们。可以把它想象成可搜索的 CLAUDE.md,保存项目为何成为现在样子的历史,而不是一页必须不断重写的文字。任何人都可以用 --memory 读取公开记忆。

发布的记忆带有数据集卡片与 funes 标签,便于在 Hub 识别和发现。Hub 已经托管开放权重与数据集,funes 增添开放的工作记忆。它保存项目背后的决策、失败方法与理由,其他代理可以查询,并追溯到产生它们的会话。

走出长会话的最低成本方式

漫长的调查会使会话膨胀,直到每轮携带上下文的成本超过完成工作的成本。通常的解决办法是让代理压缩上下文继续工作,或编写交接记录后重新开始。检索是第三种方式,因此我们在 handoff-vs-recall 基准中比较三者:其中两个任务的答案,如果没有会话中的先验知识,就无法重建。

压缩是大多数代理的默认做法,也是三种方式中唯一在两个任务上结果分化的方式:一个任务得到答案,另一个始终未得到。失败时,摘要把重要发现压平了。检索返回段落本身,因此发现不必经受摘要过程。

在两个任务上,检索都是三者中最便宜的方式:一个任务的成本为书面交接的八分之一,另一个为四分之一。

原图中,每根条形较浅的部分表示准备渠道、交接或压缩的一次性费用,在首次提问之前产生,并且只计入一次。叉号表示始终没有得到答案的渠道,因此没有每次成功的成本。

不要再从零开始

“思考就是忘记差异、概括、进行抽象。”——豪尔赫·路易斯·博尔赫斯,《博闻强记的富内斯》

代理已经写下记录。funes 距离把记录变为下一位代理能够读取的记忆,只差一条命令,无论你恰好在哪台机器工作。

建立在开源之上

funes 很少重新发明这些基础能力。它依赖足够优秀、能够本地运行的开源嵌入模型,依赖 Lance 支持低成本增量写入的只追加数据集,以及 Hub 对数据集的缓存和内容去重。工作重点在于把这些组件组合成代理真正能使用的记忆。

funes 本身也是开源的。从安装故障、检索遗漏,到希望支持的代理,任何问题都可以到项目提出 issue。

来源与版权

原文:Give Your Coding Agents a Memory You Own,作者 David Corvoysier,2026年9月3日。文章涉及数据集 dacorvo/funes-handoff-recall-benchmark。本文转载依据为用户对冻结批次的明确授权声明;正文页面未明示独立文章许可,不能将软件开源许可自动视为文章许可。命令保持原文,未安装或执行;性能结论仅限原文两个基准任务。原文内嵌演示与基准图尚待取得并核验,当前稿件不应直接发布。

© 版权声明
THE END
喜欢就支持一下吧
点赞0 分享
评论 抢沙发

请登录后发表评论

    暂无评论内容