你为仓库精心写了一份 CLAUDE.md —— 编码规范、测试命令、部署说明,事无巨细。Claude Code 一开新会话立刻违反了一半:用错包管理器、跑错测试命令、改了你明确标注为生成产物的文件。问题不在于 Claude 在”无视”指令,而是这份文件根本没进上下文。项目级 CLAUDE.md 加载失败有几种不太明显的形式:文件名大小写错、文件位于 CLI 当前工作目录无法回溯到的子目录、用户级 CLAUDE.md 把它盖住、或者会话残留旧缓存需要重新加载。
常见原因
按真实场景中出现频率排序。
1. 从错误的工作目录启动
Claude Code 从当前目录向上一级一级找 CLAUDE.md,一直找到家目录。如果你在 ~/projects 而不是 ~/projects/myrepo 里启动,项目级文件根本看不到,只会读到全局那一份。
怎么判断:启动 claude 前 pwd 的结果跟 CLAUDE.md 所在目录对不上;或者你同时开着多个仓库,然后在父目录里跑了 claude。
2. 文件名或大小写错误
文件必须恰好叫 CLAUDE.md —— 全大写,扩展名也不能换。Claude.md、claude.md、CLAUDE.MD、CLAUDE.markdown 在区分大小写的文件系统上(Linux、大多数 CI)都会被忽略。macOS 默认 HFS+/APFS 不区分大小写,所以本地能跑,CI 一上就挂。
怎么判断:ls -la CLAUDE.md 没结果,但 ls -la | grep -i claude 显示文件存在,只是大小写不一样。
3. 用户级 CLAUDE.md 把项目级压住
全局 ~/.claude/CLAUDE.md 也会被加载,某些版本中它会跟项目级指令合并,甚至在冲突时把项目级覆盖掉。全局文件里一句”始终使用 yarn”就能压过项目里的”使用 pnpm”。
怎么判断:两个文件都存在,模型行为跟全局文件一致而非项目文件,通常冲突点是包管理器或提交风格。
4. 文件超过容量上限被静默截断
CLAUDE.md 有一个软上限(常见是 10-15k token)。超过这个量,尾部会在注入前被截掉。如果你把关键规则放在底部,它们就直接消失了。
怎么判断:CLAUDE.md 顶部的规则被遵守,底部的规则没被遵守。wc -c CLAUDE.md 超过 40000 字节。
5. @path 引入失败
CLAUDE.md 支持 @./docs/conventions.md 这种引用导入。如果目标文件不存在、被 .gitignore 忽略,或者超出项目根目录,这条引入会静默失败,该块为空。
怎么判断:你的 CLAUDE.md 很短,只有几条 @ 引入;模型只知道 CLAUDE.md 字面内容,完全不知道被引入的文件。
6. 子代理 / Task 工具产生的会话未携带 CLAUDE.md
主代理通过 Task 工具产生子代理时,子代理拿到的是全新上下文。部分配置不会自动把 CLAUDE.md 透传给子代理,因此子代理跑的时候无视项目规则,即便主代理在遵守。
怎么判断:直接给 Claude Code 发的提示遵守 CLAUDE.md;明确派发子代理的提示(“派一个 Task 调研 X”)就不遵守。
开始前
- 确认你启动 Claude Code 时的 cwd。
- 记录问题出在主代理、子代理,还是两者都有。
- 抓一条 CLAUDE.md 里被违反的具体指令 —— 需要一个可复现的测试用例。
- 检查文件是否纳入版本控制(
git ls-files CLAUDE.md)。
需要收集的信息
- 会话启动时的
pwd。 ls -la CLAUDE.md和wc -c CLAUDE.md。~/.claude/CLAUDE.md(全局文件)是否存在及其内容。- CLAUDE.md 里的
@引入及目标文件是否存在。 - Claude Code 版本(
claude --version)。 - 当前系统:macOS(默认不区分大小写)还是 Linux / CI(区分大小写)。
一步步修复
按”哪个最常是真正的根因”排序。
第 1 步:先确认文件是否被找到
直接问 Claude:
请把你当前加载的项目 CLAUDE.md 前 200 个字符原样输出,不要改写。
如果输出跟你的文件对不上,或者它说”没有看到项目 CLAUDE.md”,问题就在加载,不在规则。
第 2 步:修正 cwd 后重启
退出,cd 到仓库根目录,再启动:
cd ~/projects/myrepo
ls CLAUDE.md # 必须存在于此
claude
如果是通过外壳包装器启动(tmux、VS Code task),要确认那个包装器的 cwd,不是你终端的 cwd。
第 3 步:统一文件名
mv claude.md CLAUDE.md 2>/dev/null
mv Claude.md CLAUDE.md 2>/dev/null
git mv claude.md CLAUDE.md
提交这次重命名。macOS 上 git mv 因为大小写不敏感可能要加 --force。
第 4 步:解决全局与项目级冲突
打开 ~/.claude/CLAUDE.md,把那些应该归属项目的指令删掉或注释掉。全局文件只保留真正跨项目的偏好(语气、语言)。
一份安全的全局文件大致是这样:
# Global preferences
- Prefer concise commit messages.
- Default response language: English.
- Always read the project CLAUDE.md first; project-level instructions override these.
第 5 步:精简 CLAUDE.md 或拆成 import
超过 10k token 就把章节拆出去:
# CLAUDE.md
@./docs/coding-conventions.md
@./docs/test-and-deploy.md
@./docs/architecture-notes.md
## Hard rules (must read)
- Package manager: pnpm. Never yarn or npm.
- Lint: pnpm run lint:fix before any commit.
CLAUDE.md 顶部留给最强约束。验证每个 @ 目标都存在且没被 gitignore。
第 6 步:子代理强制透传
派 Task 子代理时,把规则内联进任务提示:
Task: Research the auth module.
Constraints (from project CLAUDE.md):
- Do not run any package install.
- Test command: pnpm test --filter auth.
- Coding style: see @./docs/coding-conventions.md before suggesting changes.
这样不管子代理继承机制是否正常,规则都会被遵守。
第 7 步:会话中编辑后强制重新加载
CLAUDE.md 在会话开始时读取。如果你在会话进行中改了它,Claude 用的还是旧副本。要么重启会话,要么把更新后的章节贴进对话里,说一句”这段替代 CLAUDE.md 对应章节,本会话剩余时间生效”。
验证
- 重启后请 Claude 复述 CLAUDE.md 前 200 个字符 —— 必须完全一致。
- 跑一个依赖某条具体规则的提示(比如”装一个新依赖”),确认 Claude 用的是正确命令。
- 派一个子代理,验证它也遵守同一条规则。
- 在 Linux 机器 / CI 上跑一次,确认大小写也对。
长期预防
- CLAUDE.md 进仓库,PR 模板里把它列为必备项。
- 用
@引入让根文件控制在 200 行以内;长篇细节放docs/。 - 加一个 pre-commit hook,只要
CLAUDE.md改成其他大小写就失败。 - 多仓库 monorepo 既在工作区根放一份 CLAUDE.md,也在每个 package 根放一份;最近的那份生效。
- 在 CLAUDE.md 自身写一句:“如果你没看到这条规则,说明文件没加载 —— 停下来问。”
- 别把关键规则放在长文件底部;开头先写硬约束。
- 定期做冷启动探测:开一个全新会话,让 Claude 确认它看到了项目文件。
常见坑
- 改了 CLAUDE.md 就以为正在跑的会话已经吃到 —— 没有。
- 把团队规范写进
~/.claude/CLAUDE.md让它”到处生效”,然后纳闷新同事的 Claude 为何完全不知道这些规范。 - 因为 IDE 自动补全成了
Claude.md或claude.md就将错就错。 - 完全依赖
@引入,却没意识到目标被.gitignore忽略了。 - 把 30k token 的历史背景全塞进 CLAUDE.md,真正的规则反而被截掉。
- 把对项目架构的误解归咎于模型,实际上往往就是 CLAUDE.md 没加载。
- 假定子代理自动继承文件;关于上下文交接的相关问题,参见子代理结果未回传。
FAQ
Q: 工具调用里我看到 Claude 确实读了 CLAUDE.md,但还是不遵守。怎么回事?
读到不等于把它当作权威。在文件顶部加一行明确声明:“这些规则不可商量。任何工具调用前先确认你读过。“然后在一条具体规则上验证。
Q: 每次编辑 CLAUDE.md 都要重启吗?
要保证生效,是的。或者把改动章节贴进对话作为指令。没有热加载。
Q: 不同分支能有不同的 CLAUDE.md 吗?
可以 —— 它就在仓库里,分支级版本天然支持。worktree 里派的子代理要留意,可参考 Claude Code settings.json 未加载 里的路径解析相关问题。
Q: 多大算太大?
超过 8-10k token 你会开始丢尾部。超过 15k token,就算加载进去模型也无法稳定权衡 —— 量太大了。
Q: CLAUDE.local.md 怎么用?
同一个加载器,但当作个人覆盖,不进 git。.gitignore 加一笔。适合存放个人偏好而不污染团队文件。