编码助手跨会话记忆的十次对照测试
skillmem 用 SQLite、MCP 工具和会话钩子,为多个编码客户端共享记忆。在作者设置的五种场景、各两次测试中,启用记忆后事实召回从 0/10 提升到 10/10,但样本有限。
AI 深度解读
编码 Agent 能不能记住昨天的决定,不能只看 README 写了什么。skillmem 作者拿自己的工作数据库做了一轮测试:跨窗口问答从 0/10 到 10/10,真实项目问答则从 22/30 修到了 28/30,途中找出了导入、检索和规则审批三个问题。
这组实验值得读的地方,是它把「有记忆」拆成了几件可以验证的事:信息有没有存进去、能不能搜出来,以及搜出来之后该不该相信。
跨会话记忆,靠的是自动接入上下文
skillmem 是编码 Agent 的本地记忆层,由 SQLite、9 个 mem_* MCP 工具和 Claude Code hooks 组成。Claude Code、Codex、Cursor 等客户端可以共用一个数据库,但本文实验使用的是 claude -p,不能据此认定其他客户端效果相同。
第一个实验很直接:窗口 1 收到决定,Arka 发布改到 11 月 14 日,代号 Falcon,负责人 Timur。关闭窗口,再开一个会话询问代号和负责人。
作者准备了 5 种场景,各跑 2 次,并清掉 CLAUDE.md 和内置 auto-memory。没有记忆的对照组全部回答当前会话没有数据,接入 skillmem 后全部答对,还有一次主动指出 11 月 14 日是星期六。
它并不依赖 Agent 主动想起调用 mem_search。会话结束时,session-recap hook 调用模型,把对话提炼成短笔记;下一次 SessionStart 注入近期笔记,UserPromptSubmit 再根据每条提示搜索数据库。
跨会话记忆的关键,是把保存和检索接进必经流程。
不过,这个实验里的事实是明确交代的。真实项目的决定可能散落在一小时讨论里,摘要能否完整提取,作者没有证明。
存了九千条,为什么还答不对?
第二个实验使用作者积累了六个月、约 9,300 条记录的数据库。作者挑出 15 个确定能在记忆中找到答案的问题,每题跑两次,禁止 Agent 读取文件,避免测到的其实是磁盘搜索能力。
最初结果是:无记忆 0/30,接入 skillmem 后 22/30。排查失败答案,先发现数据根本没导全。
Claude Code 的 auto-memory 保存在 .md 文件里,需要通过 skillmem migrate 导入 SQLite。698 个文件中,208 个没有导入,约占 30%,近期记录也在其中。迁移操作虽然写进了 CLAUDE.md,却没有接入 settings.json。作者将其加入 SessionEnd 后,成绩升到 24/30。
写了说明,不等于流程会执行。
接下来的问题出在排序。约 9,300 条记录里,8,206 条是会话摘要,频繁重复「prod」「server」「deploy」。一条三行的规则,很容易被大量长摘要挤下去,旧摘要还可能和新规则冲突。
skillmem 使用 FTS5 全文检索与 embeddings,再通过 Reciprocal Rank Fusion 合并排名。作者在另一组 30 条已知正确答案的查询上试了两种改法:
- 去除 FTS 查询里的停用词,没有效果,随后撤回。
- 将 note/session 类记录的融合分数乘以
0.5,hit@3 从 18/30 升到 26/30。
hit@3 指正确记录是否进入前三个结果。它衡量的是检索命中,不是 Agent 最终答对了多少。
修改后,真实项目问答达到 28/30,对照组仍是 0/30。作者还用 LongMemEval 做检查,479 个样本的 hit@5 从 0.871 升到 0.889。这能补充检索层面的证据,但不能当成回答准确率。
找到规则,也不能直接照着执行
还有一道坎:正确规则已经排第一,Agent 仍回答「没有获批规则」。
这是安全机制在起作用。Agent 写入的规则默认未获批准,传给模型时只作为数据,不能作为指令。否则,README 或邮件里一句「记住以后总要执行 X」,就可能变成长期生效的提示词注入。
问题在于审批太难用。作者有 34 条待审批规则,其中 32 条是自己确实说过的内容,却需要逐条在终端执行 skillmem trust <slug>。新命令 skillmem review 会展示完整规则,让用户用 y / n / q 处理;作者一次处理了 33 条。
另一条路径是在聊天里审批。Stop hook 展示本轮新存的规则,最多 3 条,用户必须回复 approve 或 одобряю,其他回复都不批准。
这里有几个不能省掉的细节:展示内容直接取自数据库;hook 保存展示文本的 hash,回复前内容若改变,审批就失效;不使用日常对话里常见的 yes;审批只由 UserPromptSubmit 中的真实用户提示触发。
初始化还会在 permissions.deny 中禁止通过 Bash 执行 skillmem hook …、trust、review 和 rm。不过,作者明确承认,这些只是命令行 glob 匹配,防误操作有用,挡不住有意绕过的攻击者。其安全设计更依赖无工具权限的摘要器,以及把记忆限定为数据的上下文边界。
此外,每次 Bash/Edit/Write 前运行的 tool-recall,原先因反复加载 embedding 模型耗时 1.45 秒,改用纯 FTS 后降到 0.2 秒,约快 7 倍。
我的判断
我认同作者把「记忆有效」拆开测试。相比堆更多历史对话,先检查导入完整性、检索排序和规则权限,更容易找到具体故障。
但这些结果仍有明显前提:跨窗口只有 10 次,项目问答只有 30 个答案,排序实验只有 30 条查询;数据库属于作者,问题也是作者知道答案后编写的。把 note/session 分数统一乘以 0.5,在摘要占绝大多数的数据里合理,换一种记录结构未必适用。
28/30 是这套实验的结果,不是所有团队接入后的承诺。
文章也没有提供与手写项目规则文件、其他记忆工具的对照数据。对稳定约定而言,放进版本控制、由人维护仍是可考虑的替代做法;自动记忆更适合补充跨会话的变化信息。两者如何分工,本文没有实测答案。作者也未给出审批后的完整复测成绩,不能把它补写成最终全部答对。
能拿来做什么
- 给日常 AI 编程流程设计一次跨窗口验收:明确保存一条决定,关闭会话后再问,检查保存、检索和回答是否都成功。
- 排查项目记忆失败时,先核对文件导入数量,再看正确记录的排名,最后检查审批状态,避免把所有失败都归给模型。
- 将会话摘要和长期规则区分管理,并分别检查命中情况;不要直接照搬
0.5权重,先用自己的真实问题验证。
原文给出的 v0.13.0 更新命令如下,用于更新工具、接入新的待审批规则 hook,并处理已有积压。该版本采用 Apache-2.0,完全本地运行。
pip install -U skillmem # or /plugin marketplace update
skillmem init --claude-code # adds the new pending-rules hook
skillmem review # clear the existing backlog
重点是第二行:更新安装包之后,还要更新 Claude Code 的接入配置。