我的 CLAUDE.md 有 582 行:六层结构,以及每一层背后的故障
作者: Anastasiia Butova, ComfyUI 与扩散模型工程师,贝尔格莱德 · 发布于 2026-04-12 · 更新于 2026-09-23
译自英文版: English
每一次新的 Claude Code 对话都从零开始。它不了解项目,不记得一小时前在另一个窗口里讨论过什么,也不知道某台服务器上的某个端口绝对不能碰。这篇文章介绍我为解决这些问题而搭建的 CLAUDE.md:六层结构,每一层对应的具体事故,为什么 hook 能成功而写下来的规则会失败,那一个让被入侵的 npm 包无法进入我机器的设置,以及如果是普通项目我会保留哪些部分。2026 年 4 月 12 日俄文原文发布时,这套配置是 582 行。
CLAUDE.md 本应同时解决两个问题:在会话之间保留上下文,以及阻止代理做出不可逆的事。r/ClaudeAI 每周都有新的恐怖故事。代理删掉了生产数据库。代理把密钥推送到了公开仓库。代理"优化"了一个计费服务,结果每位客户都收到了零元账单。典型的五到十行 CLAUDE.md 两个问题都解决不了。我决定把它当作一项架构任务来对待,而不是一份愿望清单,其中每条规则背后都有一个具体的故事。
最初几条规则背后的三起事故
代理"修好"了一个正常工作的系统。 周日晚上。代理在配置里看到一个外部存储服务的 127.0.0.1,判断之前的会话留下了错误,于是换成了真实 IP。上传随即失败。调试了半小时后才发现,流量是经由本地隧道走 SNI 代理的,而 127.0.0.1 才是正确的值。没有上下文,看似显而易见的修复本身就是破坏。
由此产生的规则是:在没有理解当前配置值为何如此之前,不要修改配置。如果某个值看起来奇怪,先理解,再行动。
fail2ban 把代理当成了暴力破解者。 代理在检查服务器状态,每做一次检查就新开一次 SSH 连接。一分钟内十几次连接看起来像攻击,于是这个 IP 被封禁了半小时。当时那台机器上正在跑训练,我一时连不上它了。
规则:所有操作共用一个 SSH 桥接,每个会话一个客户端,检查、修复、验证不要拆成三个独立脚本,而是合并到一次调用里。
"过滤"被理解成了"删除"。 我要求过滤一个数据集,意思是把不合格的图片挑出去。代理按字面理解,直接删除了文件。不是移动,也不是标记,而是删除。
规则:过滤意味着移动或标记,绝不删除。任何删除操作之前,都要确认用户是否用这些字眼明确要求了删除。
写上"小心一点"没有用,需要的是一套机制。
六层结构,没有一层是事先规划的
每一层都是在某个具体故障之后出现的。
规则,9 个文件。 按场景加载。代理写文章时不需要 SSH 规则,调试代码时也不需要文章写作的规则。Claude Code 可以按任务拉入匹配的规则文件。
记忆,78 个文件。 它出现在代理第三次忘记某台服务器的配置之后。在会话之间,它保存基础设施设置、项目决策、我的偏好以及过去的错误。这些文件之间通过 [[filename]] 相互链接,共 178 处交叉链接,于是普通的 Markdown 变成了一张知识图谱。其中一部分总是加载,其余按主题加载。
交接。 它出现在新对话直接走进上一段对话的死胡同时。会话结束时,代理写一份摘要:做了什么,什么没有奏效(最有价值的部分),以及一个下一步行动。下面是一份真实的交接,从俄文翻译过来:
## Session goal
Colour checker: CNN sweep + diffusion, first visual results.
## Done
- CNN baseline: median 1.99 deg (11M params, 21 MB)
- Sweep on 5 GPUs: crop128 (3.17), bs16 (2.04), lr3e-4 (NaN)
- Diffusion training started: epoch 5/50, loss 0.827
## Did NOT work
- EfficientNet-B0: hash mismatch in the Docker image
- lr=3e-4: NaN after epoch 10-13, no gradient clipping
- CNN, visually: three numbers give stray colour casts
## Next step
Inference script for diffusion + visual sheets with 24 patches
下一个对话读取大约 1,500 个 token,而不必从头分析项目。四天之内积累了 27 份交接,没有一个死胡同被重复走过。它还能跨账号使用:我有三个订阅,两个用于工作,一个用于个人,交接让我可以在另一个订阅中接着干,而无需从头解释。它如何发展成一个供多人同时工作的工具,写在 多个 Claude 共用一个仓库 中。
编年史(chronicle)。 它出现在二十份交接之后:已经搞不清项目是如何走到今天这个状态的。交接回答"接下来做什么";编年史回答"我们是怎么走到这里的"。每个里程碑记录关键决策、转折和死胡同,每个三到七行。
Hook。 它出现在"开工前检查 CLAUDE.md 中的链接"这条规则在会话进行二十分钟后就不再被遵守的时候。下一节专门讲 hook。
技能,16 个。 面向特定工作的打包知识。描述被写成给模型的触发条件,比如"use when: GPU hung, server health check needed"(当 GPU 挂起、需要服务器健康检查时使用),而不是"helps with servers"(帮助处理服务器)。
规则是一种愿望,hook 才是保证
这是那个月里我学到的最不明显的一点。CLAUDE.md 中的规则,是一条放在提示词里的指令。模型可能忘记它,重新解读它,或者在长会话中上下文被其他内容塞满时把它丢掉。我的"开工前检查链接"规则大约只管了十分钟,然后代理就沉浸在任务中了。
hook 是 Claude Code 在某个事件(SessionStart、Stop、PreToolUse)上运行的 Python 脚本。它不会忘记,也不会重新解读。它每次都会运行。下面是一个在长会话结束前要求写交接的 hook:
# remind_handoff.py (Stop hook, simplified)
age = session_age_minutes()
if age < 15:
return # short session, nothing to hand off
if fresh_handoff_exists():
return # already written
print(json.dumps({ # block the close, ask for the handoff
"decision": "block",
"reason": f"Session ran {int(age)} min with no handoff. "
f"Write one into .claude/handoffs/ before exiting."
}))
模型通常自己就知道什么时候该收尾,比如任务完成或上下文快满的时候。hook 负责的是它忘记的那些时刻。
如果某件事每次都必须发生,那它应该是一个 hook,而不是一条规则。
一行配置,抵御供应链攻击
2026 年 3 月 31 日,官方 npm 包 axios(每周约 1 亿次下载)因一位维护者的账号被入侵而遭到污染(Elastic Security Labs)。恶意的 1.14.1 版本在 UTC 00:21 发布,有问题的版本在 npm 上一直保留到 UTC 03:15,大约三个小时(axios 事后复盘)。微软把这次攻击归因于朝鲜国家背景的 Sapphire Sleet(微软安全博客)。
我的 .npmrc 里只有一行:
min-release-age=7
发布不满七天的包不会被安装。大多数恶意包会在一到三天内被发现,所以七天是一个从容的余量。我没有受到影响,而代价只是一行配置。Python 的对应设置放在 uv.toml 中:
exclude-newer = "7 days"
背后的研究:37 篇论文
许多规则并非来自我自己的错误,而是来自学术研究:37 篇 arXiv 论文被改写成了一套原则。其中四篇对我的工作流影响最大。
- 证明循环(Proof loop)。 代理说测试通过了;你去核对,结果并非如此。证明循环禁止代理为自己的工作签字认可。它需要证据:测试输出,以及一个从未见过这项工作过程的新会话中的验证者给出的判定。来源:arXiv 2603.10165。
- 结构化推理(Structured reasoning)。 不要随意地说"也许是这个,也许是那个",而是列出:从代码和日志中确定知道的事实,一步一步的推导,由此得出的结论,以及哪些假设被检验过并被排除。在 Ugare 和 Chandra 的实验中,这种半形式化推理把补丁等价性判断的准确率,在精选样例上从 78% 提升到 88%,在真实的代理生成补丁上提升到 93%(arXiv 2603.01896)。
- 确定性编排(Deterministic orchestration)。 凡是确定性的事情,比如测试、代码检查和格式化,都通过 shell 脚本运行。模型在循环中会数错次数,也会搞混分支条件。脚本不会。
- 红线(Red lines)。 普通规则会被创造性地曲解。红线是没有例外的绝对禁令,每一条都与一起事故相关:未经确认不得删除,不理解就不得修改生产配置。这一模式来自中国的工程团队,即"红线"。
其余的内容,从生成器-评估器、autoresearch 到多代理分解、代码化上下文、代理安全以及文档完整性,都写在仓库中。
数字,以及它失败的地方
78 个记忆文件。178 处交叉链接。四天内 27 份交接。一周内 83 个会话的 KV 缓存命中率为 96.9%。配置会自我维护:每次改动之后,代理都会检查是否有链接失效,而一个 SessionStart hook 会自动验证这些链接。
它是否完美运行?不是。一次审计发现有四个记忆文件已经从索引中脱落。在一个为防止文档漂移而建的系统中,出现了文档漂移。如果没有这个系统,情况会更糟。
我不确定的部分
我不确定每个人都需要全部内容。对大多数项目来说,五条原则可能就够了:确定性编排、结构化推理、供应链防御、代码化上下文和交接。
我也不确定六层是不是最低限度。我可能过度搭建了。但在那个月里,没有任何上下文丢失,也没有一个死胡同重新出现。
其中一条原则,即假设检验,把这一点说得很直白。配置中的每个组件都编码了一个假设:模型自己做不到什么。而模型在不断进步。去掉组件,然后去测量。这里可能已经有某一层是不必要的了。
四月之后的变化
2026 年 9 月更新。这个仓库已从 claude-code-config 更名为 codex-claude-code-config,因为同样的原则、hook 和技能现在也驱动 Codex,以及 Claude 与 Codex 混合的会话,旧名字已经不能描述它了。旧网址仍会重定向。2026 年 9 月 23 日,它包含 30 条原则、58 个技能、35 个规则文件,以及 hooks/ 中的 73 个脚本,在 GitHub 上有 150 个 star 和 24 个 fork。
上文各节中的数字(9 个规则文件、78 个记忆文件、16 个技能、37 篇论文、582 行)描述的是 4 月 12 日时我的配置。它们在当天是真实的,我保留了原样。
从哪里开始
把下面这段贴进 Claude Code 对话:
https://github.com/AnastasiyaW/codex-claude-code-config - study it, pick what fits my work and set up my Claude Code
从小处开始:供应链防御(.npmrc 中的一行)、确定性编排(通过脚本运行测试),以及结构化推理(调试的格式)。其余的等到某次故障提出需求时再添加。全部内容采用 MIT 许可证。
本站的项目页面是 codex-claude-code-config。旁边成长起来的参考资料库,见 785 篇文章,写给代理而不是人。至于我为什么比桌面应用自带的会话历史更信任交接,见 45 MB 的 Claude Code 会话,你从不去看。
俄文原文发表于 Habr。