Claude Code 表现拉跨的最常见原因,不是”模型不够聪明”,而是它根本没拿到你项目的关键上下文。这种情况下它做任何事都会”看似在干活,实际全是猜”。
最快的修复: 在项目里跑一次 /init 自动生成 CLAUDE.md,然后在下一条 prompt 里直接列出你关心的那 3-5 个文件。这两步就能解决大多数”Claude 无视我项目”的抱怨。下面是完整工具箱,按收益从高到低排列。
没有项目上下文时是什么样
- 改了文件,但根本没打开真正的主逻辑文件
- 创建了已经存在的函数 / 组件(重复造轮子)
- 问你”哪里定义了 X”,其实你 README 里已经写了
- 自动改一堆”风格”细节,破坏了原本的规范
- 调试时一直在表面打补丁,不去看真正的源头
真正的原因
Claude Code 每次对话都从一个全新的上下文窗口开始,它不会自动读完你整个仓库。会话开始时它只能看到:
- 你 prompt 里明确提到的文件
- 工作目录及其上层目录里的
CLAUDE.md(启动时整份加载) - 它为这个仓库写过的 auto memory(即
MEMORY.md的前 200 行 / 25KB) - 它在执行任务中用工具(
Read、Grep、Glob)主动找到的文件
如果第 1-3 项都很稀疏,它就只能靠”猜常见结构”。Next.js 就猜 app/page.tsx,Astro 就猜 src/pages/,结果你的项目其实是个 monorepo / 自定义结构,它就全部对不上。
一个值得知道的坑:截至 2026 年 6 月,CLAUDE.md 是在 system prompt 之后以 user message 的形式注入的,并不是强制配置。 Claude 会读它、会尽量照做,但写得含糊或互相冲突的指令,遵守起来就不稳定。具体的写法永远比”愿景式”的写法管用。
你属于哪一类?
| 症状 | 最可能的原因 | 去看 |
|---|---|---|
| 重复造已有代码、文件路径错 | 没有 CLAUDE.md,prompt 里也没列文件 | 方法 1、方法 2 |
| 小仓库正常,到你的 monorepo 就出错 | 上下文量超了;拾取了不相关的子包 | 方法 5、方法 6(.claude/rules/、claudeMdExcludes) |
| 去改了生成目录 / 第三方目录 | 没有硬性禁止 | 方法 4(permissions.deny) |
| “它无视我的 CLAUDE.md” | 文件没被加载、太长或太含糊 | 跑 /memory,见 FAQ |
| 每次都犯同一个错 | 没人把它记下来 | 方法 1 + auto memory |
让 Claude Code 真正读懂项目的 7 个方法
1. 生成并打磨一份 CLAUDE.md(收益最高)
CLAUDE.md 是 Claude 每次对话开始时都会读的”项目说明书”。不要从零手写——在项目里跑 /init。Claude 会分析你的代码库,生成一份包含 build 命令、test 命令以及它发现的约定的文件。如果已经有 CLAUDE.md,/init 会给出改进建议而不是直接覆盖。
想要引导式设置,可以先设置 CLAUDE_CODE_NEW_INIT=1 再跑 /init:它会先问你要创建哪些产物(CLAUDE.md、skills、hooks),用一个 subagent 探索代码库,然后在真正写文件之前给你一份可审阅的方案。
之后再手动打磨。一份好的 CLAUDE.md 应包含:
- 技术栈:框架、语言、版本、包管理器
- 目录结构:每个一级目录是做什么的
- 关键约定:文件命名、状态管理、路由、CSS 方案(要写具体:“API handlers live in
src/api/handlers/”,而不是”保持文件组织良好”) - 运行 / 构建 / 测试命令:
npm run dev、npm test - 本地踩过的坑:哪些目录不要碰
- 如何添加新功能 / 新页面 / 新组件的实际步骤
截至 2026 年 6 月,有两条规则很关键:
- 控制在 200 行以内。 越长越占上下文,而且会实打实降低 Claude 遵守指令的可靠性。CLAUDE.md 无论多长都会被整份加载,所以长度是真实成本。
- 写具体、可验证的指令。 “Run
npm testbefore committing” 管用,“测试一下你的改动”不管用。
反例:一份
CLAUDE.md写满了”项目愿景 / 设计理念”——Claude 不需要这个。它要的是”add a new page 要做的 4 步”。
你也可以把项目说明放在 ./.claude/CLAUDE.md(而不是根目录),而且可以叠加多份:~/.claude/CLAUDE.md 放跨项目的个人偏好,./CLAUDE.md 提交给团队共享,再加一份 gitignore 掉的 ./CLAUDE.local.md 放你自己的 sandbox URL 和测试数据。它们是拼接(从根目录往下),不会互相覆盖。
2. 在 Prompt 里直接指路
不要写”帮我修 login 的 bug”。写:
帮我修
src/auth/login.ts的 bug,相关逻辑还在src/auth/session.ts和src/lib/cookies.ts。先读这三个文件,再告诉我修改方案。
点名 3-5 个文件,能让 agent 跳过”找文件”阶段,直接进到真正的代码。这是单条 prompt 里最有效的杠杆。
3. 让它先扫一遍结构
第一次进入项目时,在任何改动之前先让它做一次结构扫描:
先
ls -la看根目录,再tree -L 3 -I 'node_modules|.next|dist',告诉我这是什么类型的项目、入口在哪里,然后再开始。
这相当于给它一次”开机扫描”。再配一个确认步骤:让它在动手前用一两句话总结这个项目。如果总结错了就停下来纠正——这是发现”它理解错了”最省成本的时刻。
4. 硬性禁止它不能碰的目录
这里有两层,很多人会搞混:
.claudeignore(用 gitignore 语法)是软性的”别自动读取”提示。它能让文件不进自动上下文,但截至 2026 年 6 月,Claude 仍可以通过显式Read或搜索读到被 ignore 的文件。适合降噪,不适合护着密钥。.claude/settings.json里的permissions.deny是硬性禁止——Claude 去读或改被禁止的路径时会直接报错。.env、凭证、生成产物,或者你永远不想被重写的legacy/目录,用这个。
.claude/settings.json 示例:
{
"permissions": {
"deny": [
"Read(./.env)",
"Read(./secrets/**)",
"Edit(./generated/**)",
"Edit(./legacy/**)"
]
}
}
你仍然可以在 CLAUDE.md 里保留人类可读的红线(“Do NOT edit anything in node_modules/, .next/, dist/, generated/, legacy/”),但要把它当作建议,而不是强制。凡是敏感的东西,真正兜底的是 permissions.deny 这一层。
5. 用 .claude/rules/ 按区域拆分指令
项目大了,别把所有东西都塞进一份 CLAUDE.md。把主题文件放进 .claude/rules/(比如 testing.md、api-design.md、security.md)。每个文件都可以按路径限定,只有当 Claude 碰到匹配的文件时才加载:
---
paths:
- "src/api/**/*.ts"
---
# API Development Rules
- 所有 endpoint 必须做输入校验
- 使用统一的 error response 格式
- 包含 OpenAPI 文档注释
没有 paths 字段的 rule 会每次会话都加载,优先级和 .claude/CLAUDE.md 相同。按路径限定的 rule 只在 Claude 读到匹配文件时触发,这样能让”常驻上下文”保持精简。
6. monorepo:每个包一份 + claudeMdExcludes
在 monorepo 里,给每个子包放一份 CLAUDE.md。子目录里的文件是按需加载的——只有当 Claude 读那个目录里的文件时才加载,所以 packages/api/CLAUDE.md 只在 Claude 进到 packages/api/ 工作时才占用上下文。
如果 Claude 拾取了别的团队、跟你无关的上层 CLAUDE.md,在 .claude/settings.local.json 里排除它:
{
"claudeMdExcludes": [
"**/monorepo/CLAUDE.md",
"/abs/path/monorepo/other-team/.claude/rules/**"
]
}
匹配的是绝对路径,用 glob 语法。(被 managed policy 管理的 CLAUDE.md 无法排除。)
7. 给”如何添加一个 X”的清单和导览注释
两个便宜又持久的收益。
在 CLAUDE.md 里写清单式段落,能让 agent 照着步骤走,而不是临时发明一个新约定:
## How to add a new page
1. Create `src/content/articles/[lang]/[category]/[slug].mdx`
2. Use the schema in `src/content/config.ts`
3. Add the slug to internal links from the related category landing
4. Run `npm run audit:content` before commit
在重要文件顶部加 3-5 行”这个文件干什么”的注释,对 agent 和人类都有用:
// auth/session.ts
// Owns session lifecycle: create, refresh, destroy.
// Reads cookies via lib/cookies.ts. Writes audit logs via lib/log.ts.
// IMPORTANT: do not call this from middleware; use auth/edge-session.ts there.
让 auto memory 帮你扛下其余的
截至 2026 年 6 月(Claude Code v2.1.59 及以上),auto memory 默认开启。 Claude 会按仓库给自己写笔记——build 命令、调试心得、它发现的偏好——存到 ~/.claude/projects/<project>/memory/MEMORY.md。每次会话加载它的前 200 行(或 25KB)。
你不用专门管它,但可以管:当你跟 Claude 说”always use pnpm, not npm”,它会把这条存进 auto memory。跑 /memory 可以浏览、编辑、删除它存的内容,或者关掉 auto memory(环境变量 CLAUDE_CODE_DISABLE_AUTO_MEMORY=1 也能关)。如果 Claude 一直犯同一个错,那就是信号:要么当场纠正它(让 auto memory 把修复记下来),要么你自己把这条规则写进 CLAUDE.md。
最短修复路径
按落地难度从低到高:
- 跑
/init生成CLAUDE.md,再裁到 200 行以内 - 每条 prompt 都点名文件(3-5 个路径)
- 给绝对不能碰的目录加
permissions.deny - 关键文件加导览注释
- monorepo 再用每包一份
CLAUDE.md+.claude/rules/
只做前两步,效果就能立竿见影。
如何确认已经修好
- 跑
/memory,确认你的CLAUDE.md(以及任何CLAUDE.local.md)出现在已加载列表里。没列出来就说明 Claude 看不到它——要么位置不对,要么文件名写错了。 - 跑
/context看按类别分的 token 占用(system prompt、tools、memory files、messages、free space)。确认 “Memory files” 不为零,并且还留有可观的 free space。 - 让 Claude 用两句话总结项目结构、说出入口在哪。总结正确说明上下文进去了。
- 重跑那个失败的任务。如果它现在先打开正确的文件、不再重复造已有代码,那原来的问题就是上下文。
什么时候不是上下文问题
- 你的项目结构本身就乱,新人也读不懂 → 先重构。
- 同一个 prompt 在小项目里没问题,到大 monorepo 才出错 → 上下文量超了;看
/context,用.claude/rules/拆分。 - agent 反复重试同一个文件 → 它没拿到真正的路径,把准确路径贴给它。
- 仓库一份文档都没有 → 跑
/init补上缺的事实。
容易误判的情况
- “Claude 笨了。” 是你的项目变大了。Claude Code 不能一次读 100 万行——要让它按需读。
- “它无视我的 CLAUDE.md。” 用
/memory检查文件名大小写和位置。记住 CLAUDE.md 是建议不是强制;必须执行的步骤改用 hook。 - “它编造代码。” 多半是它没看到原代码,被迫”补一个看起来对的”。点名文件。
- “它不会用工具。” 你的 prompt 没让它扫描;让它先
tree/grep。
常见问题(FAQ)
Q:CLAUDE.md 写多长合适?
A:目标是 200 行以内。Anthropic 官方文档明确说,越长越占上下文、越降低 Claude 遵守指令的可靠性。顺序按:技术栈 → 目录 → 关键命令 → 不要做的事 → 怎么加新东西。内容变多就把细节挪到 .claude/rules/。
Q:CLAUDE.md 和 README,用哪个?
A:CLAUDE.md 是 agent 的说明书,README 给人看。内容可以重叠,但 CLAUDE.md 更强调”agent 该怎么做”。如果你已经为别的工具维护着 AGENTS.md,那就建一份 CLAUDE.md,开头写 @AGENTS.md,让两边读同一份源——因为 Claude 只读 CLAUDE.md,不读 AGENTS.md。
Q:怎么把别的文件导入 CLAUDE.md?
A:在文件任意位置用 @path/to/file.md(相对或绝对路径都行,递归最多 4 层)。被导入的文件在启动时仍会进上下文,所以这是为了组织,不是为了省 token。想提到一个路径但又不想导入它,就用反引号把它包起来。
Q:.claudeignore 真能阻止 Claude 读文件吗?
A:不能。截至 2026 年 6 月它是软性的”别自动读取”提示;Claude 仍可以通过显式读取或搜索打开被 ignore 的文件。要真正硬性阻止(密钥、凭证),用 .claude/settings.json 里的 permissions.deny。
Q:能让 Claude Code 一次读完整个项目吗?
A:只有项目很小才行。默认上下文窗口是 20 万 token(部分套餐 100 万),所以中大型仓库要让它按需读,不要全塞进去。用 /context 盯着占用。
Q:怎么知道它现在拿到了正确上下文?
A:跑 /memory 确认文件加载、跑 /context 看 token 分布,再让 Claude 在动手前总结一下结构。总结不对就停下来纠正。
相关问题
- Cursor 一直 indexing 怎么办
- Claude usage limit 到了怎么办
- Prompt 很长但效果更差怎么办
- AI 提交前审查工作流
- Claude Code SEO 审计教程
- AI 依赖升级工作流
外部参考:Claude Code memory 官方文档 与 上下文窗口指南。
标签: #Claude #Claude Code #AI 编程 #排查