Claude Code 三种记忆方案实测
作者用相同的 30 条设计决策比较 CLAUDE.md、自动记忆和 LLM Wiki,并提供复现实验脚本与决策文本。三者在该规模下均能正确召回,CLAUDE.md 最快且成本最低,决策变更后的冲突处理则存在差异。
完整中文译文
把团队昨天做过的决定交给 Claude Code,放在 CLAUDE.md、内置 auto-memory,还是仓库里的 LLM wiki?作者用同一组 30 条决策做了测试:三种方案都答对了回忆问题,CLAUDE.md 最快、最便宜;真正拉开差距的是决策变更后,旧理由能否保留,相关约束能否一起更新。
这组实验值得看,因为它测到了日常 AI 编程里更隐蔽的问题:模型记住了新数字,却可能留下与之冲突的旧规则。不过,实验由维护 wiki 插件的 Claude Code agent 完成,规模也小,结论需要带着边界读。
30 条决策都能记住,为什么还要比较
实验针对 pallets/itsdangerous 的 commit 672971d,复制四份目录,分别测试无记忆和三种记忆方案。主实验使用 Claude Code 2.1.288,每一步都通过 claude -p 开新会话,避免上一轮对话直接提供答案。
决策属于一个虚构应用,源码里查不到。例如:保留 3 把签名密钥,每 30 天轮换一次;remember-me cookie 有效期为 45 天;任何签名令牌的 max_age 不得超过 60 天。
为什么是 60 天?令牌可能在旧密钥退出签发窗口前一刻生成。此后即使还保留这把密钥用于验证,也只保证再验证 (3-1) × 30 = 60 天。令牌声明的有效期再长,密钥被移出验证列表后也没用。
没有记忆时,模型被问到「保留几把密钥」会承认不知道应用策略;但面对「90 天 cookie 能否设置 max_age=90 days」这种实际问题,却先回答了 Yes。三种记忆方案都能指出原策略下的 60 天限制。
代码能告诉模型库支持什么,团队记忆才能告诉它项目允许什么。
记录 30 条决策后,三种方案的九次问答都找到了正确事实。CLAUDE.md 每次只需一轮,因为全文已经进入上下文;auto-memory 读取一两个主题文件;wiki 则读取索引、页面和保存的对话,并逐条引用来源。
成本差异来自这些读取动作。作者没有证明 wiki 的普通问答更准,只证明这次它花了更多轮次做溯源。
CLAUDE.md 此时约 6 KB、66 行、约 1,500 tokens。作者用只回复 OK 的会话测加载成本,但无记忆会话本身就出现了 23,091 与 21,216 tokens 的波动。因此只能说,这个规模下没测出稳定的额外开销,不能推导为文件继续增长也没有成本。
决策改了以后,谁能发现连带问题
随后,产品把 remember-me cookie 从 45 天改成 75 天。密钥增加到 4 把,仍每 30 天轮换,保证验证窗口变为 (4-1) × 30 = 90 天。
CLAUDE.md 正确改成了 4 把密钥和 90 天上限,也注明替代旧策略。但它删掉了当初拒绝 2 把密钥的理由,并留下另一条旧决策:计划在 Q1 2027 切换 SHA-256,两个 serializer 并行运行 45 天。
这就冲突了。仍有效的 75 天 cookie,可能在旧 serializer 停止验证时提前失效。CLAUDE.md 方案在后续回答时发现了这个问题,但文件里没有留下提醒。
auto-memory 更新密钥策略时,用一行 Earlier: ... 保留旧理由,并主动在迁移文件里记录:45 天重叠期与新的 75 天 cookie 冲突,尚未决定如何处理。
wiki 也发现了这个冲突,还找出了另一处:退订链接虽然不传 max_age,仍然使用轮换密钥签名。密钥退出验证列表后,链接照样失效。新策略下,它实际只能存活 90 至 120 天,「永不过期」从一开始就不成立。
下面这段记录展示了 wiki 如何把当前约束、来源和未解决问题放在一起:
## 2026-10-03 max_age must be at most 90 days (supersedes the 60-day limit)
- **Rule:** No signed token in our app may use a `max_age` above 90 days.
Source: `raw/conversations/signing-key-rotation.md:9`.
- **Why:** With 4 keys rotated every 30 days ([[signing-keys]]), a token signed on
the last day of a key's signing window still verifies for (4-1) × 30 = 90 more days.
- **Known violation:** Unsubscribe links still have no `max_age` ([[token-types]]);
they now stop verifying 90–120 days after signing. Unresolved.
## 2026-10-03 ~~max_age must be at most 60 days~~ (superseded)
要看的是 Known violation 那一行:记忆除了保存答案,还保存了答案暂时无法覆盖的例外。wiki 又核对了 signer.py:227-242,确认库只尝试当前密钥列表。
代价也明确:wiki 写入成本约为另外两种方案的三倍。作者提到每批约 $0.50 的取舍,额外工作包括分配页面、添加引用、交叉检查已有决策。发现冲突的价值,正来自最后一步。
auto-memory 的边界,比选型口号更实用
auto-memory 默认位于 ~/.claude/projects/<path>/memory/,不随仓库提交。每个会话加载 MEMORY.md 索引,细节文件按需读取。
路径规则容易踩坑。项目路径会先解析符号链接,再把非字母数字字符替换为 -。macOS 的 /tmp/x/a 因而对应 ~/.claude/projects/-private-tmp-x-a/memory/。
autoMemoryDirectory 会直接替换整个存储路径,不再自动追加项目子目录。两个仓库配置同一路径,就会共用一个 MEMORY.md。这能用于主动共享,也可能混入另一个项目的事实;作者只测了文件落点,没有测混用后的回忆质量。
在 2.1.306 的检查中,Git 仓库使用顶层目录确定记忆位置,深层子目录和该仓库的 worktree 共用主检出目录的记忆。会话记录却按启动目录存放,不能看到某个 transcripts 目录,就认定那里也有记忆。
索引还有硬上限:前 200 行,或能完整装入 25,000 个计数单位的整行,先到哪个就停。截断不会切断一行,但后面的事实也不会进入上下文。
作者从 2.1.296 追测到 2.1.306,逐步修正了「字符」的含义:2.1.302 的中文测试排除了按 UTF-8 字节计数,2.1.303 的 emoji 测试进一步指向 JavaScript string.length,即 UTF-16 代码单元。一个 😀 计两单位。
因此,中文索引超过磁盘上的 25 KB,仍可能完整加载。控制台警告里的 KB 也不能直接当成文件字节数。
关闭开关同样有优先级。"autoMemoryEnabled": false 会停止加载索引,但显式环境变量 CLAUDE_CODE_DISABLE_AUTO_MEMORY 优先:设为 0 可以覆盖关闭设置,设为 1 可以覆盖开启设置。排查 CI 或本机行为时,需要同时检查 shell 环境。
我的判断
我认可这篇最有用的区分:常驻规则、个人记忆、团队决策,适合不同的维护方式。尤其是「为什么拒绝另一个方案」以及「新决定影响哪些旧约束」,往往比最终选项更值得留下。
但这里证明的是一套具体 wiki 工作流的表现。作者使用自己维护的 vellumlabs/llm-wiki-kit,通过 /llm-wiki:init 和 /llm-wiki:capture 写入;引用来源、保留历史、交叉检查,都来自这套工作流的要求。Markdown 文件夹不会自动获得这些能力。
同样,CLAUDE.md 这次丢了理由,不足以证明它必然丢理由。团队也可以用 ADR 记录决策历史,让 CLAUDE.md 只保存入口。原文没有与这种做法比较,不能替 wiki 宣布胜出。
数据也需要降温:一个库、一个虚构应用、30 条决策,每个单元格只跑一次。相同 wiki 构建提示曾生成 21 页,另一次只有 17 页。费用来自订阅 OAuth 会话的 CLI 报告,并不等于 API 账单。
作者没有测试数百条决策、多人同时编辑或 MCP memory servers。提供的附录在第 26 条处截断,29 条后续决策并未完整展示,也限制了按当前文本复现。性能排名应当视为小样本观察。
能拿来做什么
- 把每次任务都需要的测试命令、代码规范和提交约束放进 CLAUDE.md。针对小规模规则集,原文没有提供必须提前拆库的证据。
- 把个人工作偏好放进 auto-memory,并让
MEMORY.md每条只占一个短行,详细内容进入主题文件。多人项目需要共享的约束,应另有仓库内来源。 - 修改 cookie 时长、密钥轮换或兼容窗口时,要求 agent 同时列出旧理由、关联约束和未解决冲突。可以使用 wiki 或 ADR,关键是把检查动作写进流程。
- 用
claude -p做内部评估时,每次开新会话,并通过--output-format json记录num_turns、total_cost_usd和usage。除了测试能否答对,还要测试决策变化后能否发现过期规则。