刚开始用 Claude Code 那段时间,我把 CLAUDE.md 当成一个什么都能塞的地方。项目历史塞进去了,技术决策塞进去了,我个人的写作偏好也塞进去了,甚至有一次我把公司的价值观也复制进去了。。。当时觉得,信息越全,AI 不是越懂我吗?

然后 Claude 就开始生成一些莫名其妙的东西。

我盯着屏幕看了很久,完全不知道它在想什么,也不知道问题出在哪。后来才明白,不是 AI 变蠢了,是我把它淹死了。

这篇我想聊聊用 Claude Code 这段时间踩出来的 8 条经验,都是一些反直觉的东西,有些我自己现在也还在校准。不成熟的想法,大家随便看看。


第一条,200 行封顶。

你可能跟我当时一样,觉得信息越多 AI 越懂你。但实际上反过来,信息一多,它反而分不清哪些是重点。

Boris Cherny,claude-code-best-practice 的作者,建议 CLAUDE.md 不要超过 200 行。这个数字我一开始觉得太保守了,后来才理解为什么。Claude Code 每次会话都会把这个文件完整加载,直接占上下文窗口。你多写一行废话,它理解你代码的空间就少一点。

# ❌ 不要这样
## 项目历史
2023 年,我们的 CTO 在 hackathon 上提出了这个想法...
(300 行的公司叙事 + 营销文案)

# ✅ 要这样
## Project Overview
B2B 分析仪表盘,面向运营经理。
核心目标:缩短「从数据到洞察」的时间。
优化优先级:加载速度 > 交互丰富度 > 视觉花哨。

验证方法我觉得挺好用的,找一个完全没看过你项目的人,让他读完 CLAUDE.md,30 秒内能答出三个问题吗,这是什么产品?技术栈是什么?新代码放哪?能答出来,就合格了。

答不出来,说明你写的不是给 AI 看的,是给自己看的。


第二条,禁止清单和技术栈一样重要,甚至更重要。

很多人写 CLAUDE.md 只写"我们用什么",不写"我们不用什么"。我之前就是这样。

问题在于,AI 的知识截止到训练日,它不知道你的项目有历史包袱。它会出于善意,把它认为最优的方案引进来。Redux、Material UI、MongoDB,那些你上半年刚迁移走的东西,它可能下一秒就给你加回来。

## Tech Stack

- Next.js 15 App Router + TypeScript
- Tailwind CSS + shadcn/ui
- Supabase(认证 + 数据)

Do NOT introduce unless explicitly requested:

- Redux(已迁移到 React Context + Zustand)
- styled-components(全站 Tailwind,不接受 CSS-in-JS)
- Material UI(与 shadcn/ui 样式冲突)
- MongoDB(数据层已锁定 PostgreSQL)

这段写了,省的不是一次纠正,是之后 10 次会话不用再修兼容性。


第三条,规则要能执行,不是能感受。

"写干净的代码",我以前真的写过这种规则。。。

AI 不懂「干净」,它懂「用 named export 而不是 default export」,懂「组件不超过 200 行」,懂「async/await 不用 then 链」。

# ❌ 模糊——Claude 无法执行
## Coding Rules
- 写干净的代码
- 保持简洁
- 注重性能

# ✅ 具体——Claude 可以直接执行
## Coding Rules
- 使用 named export(路由文件除外)
- 禁止 any 类型,用泛型或接口替代
- 单个组件不超过 200 行(有充分理由可超)
- async/await 替代 Promise 链
- 变量名全拼,不缩写(除 id/url/ctx)
- 只在意图不明显时写注释
- 不留注释掉的代码块或 console.log

怎么判断一条规则写得够不够具体?就一个标准,读完之后,你能在 5 秒内判断一段代码符不符合它吗?能,留着。不能,改写。


第四条,CLAUDE.md 是目录,不是图书馆。

这个想明白之后,我整个 CLAUDE.md 的写法都变了。

它的职责不是存储信息,是告诉 AI 去哪找信息。

## Project Context

- 架构总览:docs/architecture.md
- 设计决策记录:docs/adrs/
- API 文档:docs/api.md
- 部署流程:docs/deploy.md

AI 不需要在 CLAUDE.md 里读完所有架构文档,它只需要知道,想了解架构的时候,打开哪个文件。

进一步的玩法是分层,每次必加载的放 CLAUDE.md,按需读取的指向具体文档,历史归档目录直接标注「除非明确要求,不碰」。这样无关请求的时候不浪费上下文,要用的时候知道去哪找。

## Context Tiers
Tier 1(每次加载):CLAUDE.md — 项目是什么 + 怎么工作
Tier 2(按需加载):docs/architecture.md, docs/api.md — Claude 工作时自动读取
Tier 3(忽略):docs/archive/ — 除非明确要求,不碰

第五条,敏感模块要开本地 CLAUDE.md。

根目录那份管不住所有地方,这个我是踩了坑才知道的。

有些模块出错的代价比其他地方大得多,认证、支付、数据库迁移,这些地方需要单独管。在 src/auth/src/payments/infra/ 下面各放一个本地 CLAUDE.md,AI 操作这些目录的时候会自动加载。

# src/auth/CLAUDE.md

## 安全红线

- 绝不修改 token 验证逻辑,除非明确要求且经过 review
- 绝不引入新的认证方式而不更新测试
- 所有认证相关变更必须通过 pnpm test src/auth 全部测试

## 已知陷阱

- Magic link 生成依赖 crypto.randomUUID(),不要换成其他随机方法
- Session 存储在 Redis,不是内存,重启不会丢失

第六条,靠 Hook,不靠记性。

你写了「每次改完要跑测试」,AI 看了,点头,然后不跑。因为它忘了。

## Hooks & Quality Gates
以下规则由 `.claude/hooks/` 强制执行,不是提醒:
- 每次编辑后自动格式化(PreToolUse hook → prettier)
- 核心模块变更后自动跑测试(PostToolUse hook → vitest related)
- 禁止直接编辑 `src/auth/`、`src/billing/`、`prisma/migrations/` 而不先确认

这不是 AI 的问题,记性本来就不可靠。把规则挂到工具触发上才是正经做法。

// .claude/hooks/pre-tool-use.json
{
  "hooks": [
    {
      "matcher": "Edit|Write",
      "command": "npx prettier --write ",
      "on_failure": "warn"
    }
  ]
}

写在 CLAUDE.md 里的规则是「请记住」,配了 Hook 的规则是「你必须」。这两个不是一回事。


第七条,用 MEMORY.md 存跨会话的发现。

每开一个新会话,AI 都像第一次见到你的项目。这个问题我想了很久,以为要上向量数据库,后来发现一个文件就够了。

在 CLAUDE.md 里加一条指令,让它自己维护 MEMORY.md。

## Memory

MEMORY.md 记录了之前任务中发现的关键洞察、最佳实践和已知陷阱。

每次新任务开始前,先读取 MEMORY.md。
每次任务结束后,如果有新发现,更新进去。

可以 Git 追踪,不会因为会话结束就消失。说实话这个方案比我想象的好用,有点惊喜。


第八条,把开场白写死在文件里。

每次新对话都要重复「你帮我做 X 时注意 Y」,这是在浪费消息,也是在浪费你自己的时间。

## My Working Style

- 先给方案,不要直接写代码
- 不确定时列出选项,不要猜测
- 重大变更前先问,小优化可以直接执行
- 不要用「Great question!」这类废话
- 回复用中文,代码注释用英文
- 文件路径用绝对路径

这 6 行,省掉了每次新会话的前 5 条消息。


一张表总结

HHpQp0Ra0AACeak (1).png

坦率的讲,这 8 条我自己现在也没有全部做到,有几条还在调整。CLAUDE.md 这个东西,不是写完就放那不管的,AI 每踩一个重复的坑,你每总结一条有效规则,都应该更新进去。

我觉得它最终变成什么样,取决于你用它的时间有多长。

用的时间越长,它越懂你。

大家也可以把自己的 CLAUDE.md 配置分享出来,我挺好奇不同项目的差异有多大的。

以上,既然看到这里了,如果觉得不错,随手点个赞、在看、转发三连吧,如果想第一时间收到推送,也可以给我个星标~ 谢谢你看我的文章,我们,下次再见。