funes:让编码 Agent 拥有可迁移、可追溯的长期记忆
funes 把 Claude Code、Codex、pi、Hermes 等 Agent 已产生的会话记录,转为本地可检索的记忆数据集。它不在写入阶段用 LLM 提炼“事实”,而是保存带来源定位的原始片段;需要时由 Agent 主动调用 recall 找回证据,再用 get 回看完整上下文。
它解决什么问题
一次会话中的判断、失败路径与设计理由,往往在会话结束、换机器或切换 Agent 后消失。
会话天然易失
上下文窗口耗尽、压缩或新开会话后,Agent 很难继续理解“当时为什么这样做”。
交接依赖人工
手写 handoff 容易遗漏,摘要还可能抹平关键条件、反例与已经证伪的方案。
工具与设备割裂
昨天在 Claude Code 做出的选择,今天切到 Codex 或另一台机器时通常无法被直接利用。
关键转变:从“会话日志”到“可验证的工作记忆”
会话文件本身只是档案。要让 Agent 真正使用它们,需要统一结构、增量索引、混合召回、排序,以及能精确回到原始 turn 的出处。funes 将这些能力打包为一个本地记忆层。
整体架构:写入保真,读取做判断
系统把“记录”与“理解”解耦:索引阶段确定且可复现,使用阶段才由当前 Agent 综合证据。
get 定位索引与存储:把会话变成可增量计算的数据集
所有支持的来源先映射为统一结构,后续 chunk、向量化和查询逻辑便不再依赖具体 Agent。
确定性管线:相同会话重复索引,会生成相同的 chunk ID,不会重复嵌入。
| 优先级 | 索引内容 | 为什么这样排 | 实际效果 |
|---|---|---|---|
| L1 | 用户/助手文本、thinking | 最接近决策、理由与结论 | 先让“为什么”可被召回 |
| L2 | tool_use | 补充“做过什么操作” | 后续提供行动上下文 |
| L3 | tool_result | 通常最庞大、单位价值较低 | 分批回填,避免首次长时间阻塞 |
增量性来自稳定的 chunk 标识
chunk ID 从 (session, turn, block, split) 派生。一段已完成 turn 无论在会话中途、会话结束后或第二次扫描时进入索引,都会得到相同身份;因此“每 turn 扫一次”与“最后统一扫一次”在数据结果上等价。
# 默认可扫描已知 Agent 的会话目录;也可限定某一来源 funes index --harness codex # 也接受一个 trace 目录、单个 parquet 或 Hub 上的 trace 数据集 funes index ./some/session/tree
检索与证据:找回原话,而不是二次摘要
召回链路将“词面精确匹配”和“语义相近匹配”结合,再让更强的排序模型缩小结果。
为什么需要混合检索
向量检索擅长找同义表达,例如“放弃 parser”的原因可能写成“流式方案不稳定”;BM25则对类名、报错、参数、精确术语更可靠。RRF(Reciprocal Rank Fusion)将两路排序融合,再交给 cross-encoder 判断“问题与片段是否真正相关”。
为什么还要看相邻片段
单独一个 chunk 可能只包含结论。funes 在每个命中旁附带序列相邻的片段,并给出可直接执行的 get 范围,让 Agent 能回到完整 turn,避免只依据断章取义的检索片段行动。
新近度不是删除旧知识,而是改变排序
默认半衰期为 30 天:更近的记录有更高权重,--half-life 0 可关闭该效果。这个选择适合“当前工程决策通常比旧决策更有效”的场景,但追溯历史设计、旧故障或长期项目时,应主动扩大候选量并关闭或减弱衰减。
funes recall "为什么换掉 streaming parser" --half-life 0 --neighbors 1 funes get <session_id> --from 37 --to 43
接入 Agent:工具负责读取,Hook 负责持续写入
一次 funes add 将读工具和自动化安装到对应 Agent;工作流本身无需额外记忆操作。
funes add codex 建立首次文本优先的索引,并向 Agent 暴露 recall 与 get。
当前 Agent 遇到历史决策、设计理由或既有结论时,主动发起 recall;命中结果携带原始片段与会话定位。
per-turn hook 触发增量 index。Hook 快速返回,把实际工作放入分离 worker,尽量不阻塞对话。
如绑定远程记忆,边界 hook 会先确保最后的 turn 已纳入本地索引,再执行 push。
对 Codex 的接入要点
funes 将自己的 hook 写入 ~/.codex/hooks.json,并安装一个本地 skill,让 Codex 在工具加载前识别记忆能力;它以自身脚本为键合并或替换,不应覆盖用户已有 hook。安装后仍需要在 Codex 中通过 /hooks 查看并信任相关 hook,否则它们不会执行。
# 为 Codex 接入本地记忆 funes add codex # 接入并绑定到自己的 HF 数据集,用于跨机器同步 funes add codex <user-or-org>/funes-memory # 用于检查集成与版本状态 funes status
面向 Agent 开发的落地方式
它最适合保存难以沉淀进 README、但会反复影响开发质量的过程性知识。
先接入一台主力开发机
先只绑定 Codex 或你最常使用的编码 Agent,观察 recall 是否能找到近期的架构判断、调试结论与失败方案;不要一开始就把所有设备同时接入。
让任务过程留下高质量“可检索锚点”
在完成关键选择时写清楚背景、候选方案、取舍、验证依据与后续限制。funes 保存原文,输入质量直接影响未来能否被准确找回。
把 recall 放进复杂任务的开始阶段
例如重构前问“此前为什么不用方案 X”、线上故障前问“这个模块有哪些已知边界”。先找到原始证据,再让当前模型判断是否仍然适用。
稳定后再绑定团队/跨机 Dataset
统一命名一个组织级 memory,并明确哪些项目、哪些会话允许发布。对只有阅读需求的机器或成员分配只读 token。
取舍与边界:它选择了什么,也放弃了什么
funes 的差异重点在写入语义、数据所有权和来源可验证性,不是声称拥有独特的检索算法。
- 追加式事件日志:旧内容不被覆盖,时间衰减在读取时影响排序。
- 无 LLM 写入:解析、切块、嵌入可复现;命中可回溯到原话。
- 按需拉取:不在每轮盲目注入记忆,避免持续占用上下文。
- 本地优先:共享时是自己拥有的 Dataset,而非另租一层记忆服务。
- 不主动综合:不会自动维护一份跨会话的“最新事实表”。
- 依赖查询能力:Agent 是否在恰当时机调用 recall,仍会影响收益。
- 存在索引与存储成本:会话越多,首轮建立与本地空间需求越大。
- 新近度可能压低旧证据:回溯历史时需要调整
--half-life等参数。
参考资料
- Hugging Face Blog — Give Your Coding Agents a Memory You Own:产品定位、数据集同步与 handoff/recall 背景。
- huggingface/funes README:支持的 Agent、命令、运行时与构建信息。
- docs/index.md:来源解析、分层索引、增量 chunk 身份与本地存储。
- docs/recall.md:混合检索、重排、新近度权重与
get。 - docs/automation.md:hook 自动化与 Codex 接入方式。
- SECURITY.md:脱敏、发布门禁、token 最小权限与第三方记忆风险。