一句话

CLAUDE.md 不止一份——它有三个位置(全局 / 项目 / 组件),加载时机各不相同,搞清楚”哪一份在哪一刻生效”,才能避免规则不生效或互相打架。


记忆层级地图

CCBP(Claude Code Best Practice)原文确认的三个层级:

  • 全局级 · ~/.claude/CLAUDE.md

    • 对你这台电脑上所有项目生效
    • 适合:个人偏好、到处都用的命令习惯、你在所有项目里的禁区
    • 只有你自己能看到,不进 git
  • 项目根级 · <项目目录>/CLAUDE.md

    • 对这个项目生效,进 git,团队共享
    • 适合:这个项目的编码规范、架构禁区、常用命令、不能碰的文件
  • 组件级 · <项目目录>/<子目录>/CLAUDE.md(Monorepo 常见)

    • 对某个子模块(frontend / backend / api)生效
    • 不在启动时加载——只有 Claude 在那次 session 里读到那个子目录的文件时,才临时载入

另附一个隐形的”第 0 层”:

  • 本机私有项目级 · <项目目录>/CLAUDE.local.md
    • 作用域 = 这个项目,但不进 git(靠 .gitignore 屏蔽)
    • 适合:你在本机的个人测试配置、密钥 path、不想让队友看到的私人偏好

加载时机与优先级

CCBP 原文对 monorepo 加载机制的描述:

“Claude Code uses two distinct mechanisms for loading CLAUDE.md files: Ancestor Loading (UP the directory tree) — walks upward from your current working directory toward the filesystem root and loads every CLAUDE.md it finds. These files are loaded immediately at startup. Descendant Loading (DOWN the directory tree) — CLAUDE.md files in subdirectories below your current working directory are NOT loaded at launch. They are only included when Claude reads files in those subdirectories. This is known as lazy loading.”

翻译成人话:

位置关系加载时机例子
当前目录及其所有祖先目录启动时立即加载frontend/ 启动 → frontend/CLAUDE.md 和根目录 CLAUDE.md 都立刻进上下文
当前目录的子目录(后代)懒加载(用到才加载)从根目录启动 → frontend/CLAUDE.md 要等 Claude 读了 frontend 下的文件才载入
当前目录的兄弟目录永不自动加载frontend/ 工作时,backend/CLAUDE.md 根本不会出现
~/.claude/CLAUDE.md所有 session 启动时全局生效,最先加载

优先级:局部覆盖全局——规则冲突时,范围越小的 CLAUDE.md 说了算。


import 语法(@path 机制)

CLAUDE.md 支持用 @ 符号引入外部文件,把长文档拆分管理。写法:

@./docs/coding-standards.md
@~/.claude/shared/team-rules.md

效果:Claude Code 读到 @路径 时,会把那个文件的内容展开插入,效果等同于直接写在 CLAUDE.md 里。

用处:

  • 把大段技术细节(如 API 规范、测试指南)放进独立 md,CLAUDE.md 只留精华
  • 多个项目共享同一份规则文件,改一处处处生效

本项目(AIBuilder)的全局 CLAUDE.md 就用了 @~/.claude/shared/systems-registry.md 来拉全局系统注册表——这是 import 机制的典型用法。


常见坑

坑 1:以为”写了就生效”

在子目录下新建了 CLAUDE.md,但从根目录启动,那份文件不会在启动时读入——它要等 Claude 在那次 session 里真正读到那个子目录的文件才会触发懒加载。解法:从那个子目录启动,或者把关键规则提到根目录的 CLAUDE.md 里。

坑 2:兄弟目录的规则互相不可见

frontend/CLAUDE.md 里写了”禁止直接改 API schema”,以为 backend/ 也能遵守。但 Claude 在 backend 子目录工作时,frontend 的规则根本没被加载。解法:把跨组件的共识规则放到根目录 CLAUDE.md

坑 3:全局和项目级写了矛盾的规则

~/.claude/CLAUDE.md 写”默认用 TypeScript”,某项目的 CLAUDE.md 写”这个项目只用 Python”。结果是项目级覆盖全局,Python 生效——但如果你忘了自己在全局写过 TypeScript 规则,debug 时会绕很久。解法:全局只写”任何项目都成立”的东西,项目级写”这个项目独有”的要求。

坑 4:把 CLAUDE.local.md 忘记加进 .gitignore

本机私有的 key path、临时偏好写进了 CLAUDE.local.md,但没把它加进 .gitignore,一次 git push 就把私人配置推上去了。解法:建 CLAUDE.local.md 的第一件事就是确认 .gitignore 里有它。


和 Monorepo 的关系

CCBP 原文总结的 3 条核心洞察:

“1. Ancestors always load at startup — Claude walks UP the directory tree and loads all CLAUDE.md files it finds. 2. Descendants load lazily — Subdirectory CLAUDE.md files only load when you interact with files in those subdirectories. 3. Siblings never load — If you’re working in frontend/, you won’t get backend/CLAUDE.md or api/CLAUDE.md loaded into context.”

这个机制的好处:几百个子模块的 monorepo,启动时不会把所有规则一口气塞进上下文;Claude 只在真正碰到那个模块时才加载对应的指导,避免上下文被无关规则撑爆。


关联术语

  • [[CLAUDE.md(项目说明书)]]:本页是它的记忆机制详解补充
  • [[22 份真实 CLAUDE.md 共同结构]]:实证看真实团队怎么写

来源:/Users/chenbin/Documents/Personal Kingdom/知识库/素材_AI使用/项目样本/claude-code-best-practice/github-mirror/claude-code-best-practice/best-practice/claude-memory.md(CCBP 原文 · Boris Cherny + 官方文档 · 2025)