
这是「Claude Code 通关手册」系列的第 3 篇,共 10 篇。从这篇开始进入 Level 2(配置篇)。如果你还没配好权限系统,建议先看第 2 篇。
Claude Code 通关手册(一):Cursor 用户转 Claude Code,第一天我就后悔了——后悔没早点用
Claude Code 通关手册(二):权限系统搞明白,效率直接翻倍
我来描述一个场景,你看有没有中过招——
周一早上,你打开终端,启动 Claude Code,准备让它帮你做一个代码重构。
你输入:"帮我重构 ArticleCard 组件。"
Claude 问:"这个项目用的是什么框架?"
你答:"Next.js 14,App Router。"
Claude 问:"用 TypeScript 还是 JavaScript?"
你答:"TypeScript,严格模式。"
Claude 问:"样式方案呢?Tailwind 还是 CSS Modules?"
你答:"Tailwind CSS。"
Claude 问:"组件导出方式有什么偏好吗?"
你答:……
你已经花了两分钟在重复上周说过的话。
周二,同样的事情再来一遍。周三,又来一遍。到了周五,你的耐心已经被这些重复对话消磨殆尽。
问题的根源是什么?Claude Code 每次启动都是一张白纸。 它不记得你昨天跟它说的任何事情。每次打开都是一个全新的 AI,对你的项目一无所知。
但有一个文件,写好它之后,Claude 每次启动都会自动读取——从此它打开项目就知道技术栈是什么、编码规范是什么、常用命令怎么跑。
这个文件叫 CLAUDE.md。
今天这篇文章,我把它讲透。
CLAUDE.md 是你写给 Claude Code 的"项目交接文档"。
打个比方:你们团队来了一个新同事,能力极强但对项目完全陌生。你会怎么做?
大概率会写一份入职文档,告诉他:项目是干嘛的、技术栈是什么、代码结构长什么样、日常开发要跑哪些命令、编码规范是什么、有什么坑要注意。
CLAUDE.md 就是这份文档——只不过你的"新同事"是 Claude Code,而且它每天早上都会"失忆",所以它每天上班第一件事就是把这份文档读一遍。
技术上说:
CLAUDE.md,全大写,不能是 claude.md很多人以为 CLAUDE.md 就是一个文件的事。其实 Claude Code 有一整套分层记忆系统,CLAUDE.md 只是其中最核心的一层。
┌──────────────────────────────────────────────────────────┐
│ Claude Code 记忆系统全景图 │
├──────────────────────────────────────────────────────────┤
│ │
│ ┌────────────────────────────────────┐ │
│ │ 第 1 层:全局 CLAUDE.md │ │
│ │ ~/.claude/CLAUDE.md │ │
│ │ → 所有项目通用的个人偏好 │ │
│ │ → "我喜欢 2 空格缩进" │ │
│ └──────────┬─────────────────────────┘ │
│ ↓ 叠加 │
│ ┌────────────────────────────────────┐ │
│ │ 第 2 层:项目 CLAUDE.md │ │
│ │ 项目根目录/CLAUDE.md │ │
│ │ → 项目专属信息,提交到 Git │ │
│ │ → "本项目用 Next.js 14 + TS" │ │
│ └──────────┬─────────────────────────┘ │
│ ↓ 叠加 │
│ ┌────────────────────────────────────┐ │
│ │ 第 3 层:个人本地 CLAUDE.local.md │ │
│ │ 项目根目录/CLAUDE.local.md │ │
│ │ → 个人偏好,不提交到 Git │ │
│ │ → "用中文回答我" │ │
│ └──────────┬─────────────────────────┘ │
│ ↓ 叠加 │
│ ┌────────────────────────────────────┐ │
│ │ 第 4 层:子目录 CLAUDE.md │ │
│ │ src/components/CLAUDE.md │ │
│ │ → 按需加载,操作该目录时才读取 │ │
│ │ → "组件必须用函数式声明" │ │
│ └──────────┬─────────────────────────┘ │
│ ↓ 叠加 │
│ ┌────────────────────────────────────┐ │
│ │ 第 5 层:Auto Memory(自动记忆) │ │
│ │ ~/.claude/projects/<项目>/memory/ │ │
│ │ → Claude 自己记的笔记 │ │
│ │ → 自动记录,无需你维护 │ │
│ └────────────────────────────────────┘ │
│ │
│ 叠加规则:所有层级同时生效,不是覆盖关系 │
│ 冲突时:越具体的层级优先级越高 │
│ │
└──────────────────────────────────────────────────────────┘
关键概念:叠加,不是覆盖。
这跟 CSS 的层叠逻辑很像——全局样式 + 项目样式 + 局部样式同时生效,发生冲突时以更具体的为准。
日常使用中,你最需要关心的是前两层:全局 CLAUDE.md(你的个人偏好)和项目 CLAUDE.md(项目专属上下文)。其他三层按需使用。
这个问题至关重要。写多了浪费 Token、Claude 可能忽略关键指令;写少了等于没写。
业内共识是这样的:
┌──────────────────────────────────────────────────────────┐
│ CLAUDE.md 内容取舍原则 │
├──────────────────────────────────────────────────────────┤
│ │
│ ✅ 该写的(每次会话都需要知道的信息) │
│ ├── 项目是什么、用了什么技术栈 │
│ ├── 项目目录结构的关键说明 │
│ ├── 编码规范和命名约定 │
│ ├── 日常开发要跑的命令(dev/build/test/lint) │
│ ├── 重要的架构决策和约束 │
│ └── 常踩的坑和特殊注意事项 │
│ │
│ ❌ 不该写的 │
│ ├── "写出高质量代码" — 太模糊,等于没说 │
│ ├── "遵循最佳实践" — Claude 自己知道,不用你教 │
│ ├── 完整的 API 文档 — 太长,用 @docs/ 引用 │
│ ├── 频繁变动的信息 — 放到对话里说就行 │
│ ├── 所有可能用到的命令 — 只写高频的 │
│ └── SOLID 原则的定义 — Claude 比你还熟 │
│ │
│ 核心思路: │
│ 想象你给一个高级工程师写交接文档 │
│ 他什么都会,只是不了解"你这个项目的特殊情况" │
│ 你只需要写特殊情况,不需要教他基础知识 │
│ │
└──────────────────────────────────────────────────────────┘
经验法则:控制在 100-150 行以内。 研究表明,前沿 AI 模型能稳定遵循大约 150-200 条指令。超过这个范围,遵循率会下降。与其写一篇面面俱到的万字长文,不如写一份精炼的、每条都有分量的指南。
记住一个核心原则——渐进式披露(Progressive Disclosure)。不要把所有信息都塞进 CLAUDE.md。只在里面写"每次会话都需要的信息",其他的放到文档目录里用 @docs/xxx.md 按需引用。这样既节省 Token,又能在需要时提供深度上下文。
说再多不如做一遍。我们来给 DevPulse 项目写一份完整的 CLAUDE.md。
在 DevPulse 项目目录下启动 Claude Code,输入:
分析这个项目的完整结构,帮我生成一份 CLAUDE.md 初稿,
包括项目概述、技术栈、目录结构、编码规范和常用命令
或者更简单——Claude Code 内置了一个初始化命令:
/init
这个命令会让 Claude 自动扫描你的项目,生成一份 CLAUDE.md 初稿。
但注意:**/init 生成的只是起点,不是终点。** 它能识别出技术栈和基本命令,但你的编码规范、架构约束、团队约定这些"隐性知识"需要你手动补充。
下面是 DevPulse 项目的完整 CLAUDE.md,你可以直接参考:
# DevPulse 项目说明
## 项目概述
DevPulse 是一个基于 Next.js 14 的技术博客平台,支持 Markdown 文章发布、
用户认证、评论互动和全文搜索。面向技术社区,部署在 Vercel 上。
## 技术栈
- 框架:Next.js 14.x(App Router,不使用 Pages Router)
- 语言:TypeScript 5.x(strict 模式,tsconfig 中 strict: true)
- 样式:Tailwind CSS 3.x(不使用 CSS Modules)
- ORM:Prisma 5.x + PostgreSQL 16
- 认证:NextAuth.js v5
- 部署:Vercel(自动部署 main 分支)
## 项目结构
src/
├── app/ # App Router 页面和布局
│ ├── (auth)/ # 认证路由组(登录、注册)
│ ├── (blog)/ # 博客路由组(文章列表、详情)
│ ├── api/ # API Routes
│ └── layout.tsx # 根布局
├── components/ # 可复用组件
│ ├── ui/ # 基础 UI(Button、Input、Modal 等)
│ └── features/ # 业务组件(ArticleCard、CommentBox 等)
├── lib/ # 工具函数、配置、第三方封装
├── types/ # TypeScript 类型定义(全局共享类型)
└── prisma/ # 数据库 schema 和迁移文件
## 编码规范
- 组件声明:使用 function 关键字,不用箭头函数导出
正确:export function ArticleCard() {}
错误:export const ArticleCard = () => {}
- Props 类型命名:ComponentNameProps(如 ArticleCardProps)
- 服务端组件是默认值,只在需要交互时添加 'use client'
- 禁止使用 any 类型,所有变量和参数必须有明确类型
- import 使用命名导入,避免 default export(组件除外)
- 提交信息格式:type(scope): description(英文)
示例:feat(blog): add article search functionality
## 常用命令
- 开发服务器:npm run dev
- 生产构建:npm run build
- 类型检查:npx tsc --noEmit
- 代码检查:npm run lint
- 运行测试:npm run test
- 测试覆盖率:npm run test -- --coverage
- 数据库迁移:npx prisma migrate dev
- 数据库客户端:npx prisma studio
- 生成 Prisma 类型:npx prisma generate
## 重要约束
- 所有页面组件默认是 Server Component,数据获取在服务端完成
- 客户端交互组件必须显式标注 'use client'
- 图片必须使用 next/image,链接必须使用 next/link
- API Routes 统一放在 src/app/api/,使用 Route Handlers(不是旧版 API Routes)
- 环境变量在 .env.local 中,不要提交到 Git
- Prisma schema 修改后必须运行 migrate dev 和 generate
写好 CLAUDE.md 后,开一个全新的会话来测试:
# 退出当前会话
Ctrl+D
# 重新启动(不要用 -c 继续,要全新启动)
claude
然后输入:
帮我重构 ArticleCard 组件,拆分成更小的子组件
注意看——这次你什么背景信息都没说,但 Claude 已经知道:
ArticleCardProps这就是 CLAUDE.md 的魔力——一次编写,每次会话自动生效。
同样一个项目,CLAUDE.md 写成什么样,Claude 的表现天差地别。
# My Project
This is a web project. Use React.
Write clean code and follow best practices.
问题在哪?
结果就是:Claude 只能靠猜,猜错了你再纠正,一来一回浪费大量时间。
就是上面 DevPulse 的那份——每条信息都具体、可执行、没有歧义。
对比总结:
┌────────────┬──────────────────────┬──────────────────────┐
│ 维度 │ ❌ 差的 │ ✅ 好的 │
├────────────┼──────────────────────┼──────────────────────┤
│ 项目描述 │ "一个网站" │ "基于 Next.js 14 的 │
│ │ │ 技术博客平台" │
├────────────┼──────────────────────┼──────────────────────┤
│ 技术栈 │ "用了 React" │ "Next.js 14 + TS │
│ │ │ strict + Tailwind" │
├────────────┼──────────────────────┼──────────────────────┤
│ 编码规范 │ "写干净的代码" │ "function 声明组件, │
│ │ │ Props 命名 XxxProps" │
├────────────┼──────────────────────┼──────────────────────┤
│ 常用命令 │ 没有 │ 完整的 dev/build/ │
│ │ │ test/lint/migrate │
├────────────┼──────────────────────┼──────────────────────┤
│ 信息密度 │ 3 行 │ 80-100 行 │
├────────────┼──────────────────────┼──────────────────────┤
│ 效果 │ Claude 不断追问 │ Claude 上手就能干活 │
└────────────┴──────────────────────┴──────────────────────┘
你的项目有不同类型的代码——组件、API、测试——它们各自有不同的规范。全部塞进根目录的 CLAUDE.md?太臃肿了。
更好的做法是在子目录里放独立的 CLAUDE.md:
DevPulse/
├── CLAUDE.md ← 项目全局上下文
├── src/
│ ├── components/
│ │ └── CLAUDE.md ← 组件开发规范
│ ├── app/api/
│ │ └── CLAUDE.md ← API 开发规范
│ └── lib/
│ └── CLAUDE.md ← 工具函数规范
└── tests/
└── CLAUDE.md ← 测试编写规范
加载时机:子目录的 CLAUDE.md 不是启动时就加载的,而是按需加载——当 Claude 读取或操作该目录下的文件时,才会自动读取对应的 CLAUDE.md。
这就是"渐进式披露"的具体应用:Claude 写组件的时候加载组件规范,写 API 的时候加载 API 规范,不用的时候不加载,节省宝贵的上下文窗口空间。
举个例子,src/components/CLAUDE.md 可以这么写:
# 组件开发规范
## 文件组织
- 每个组件一个文件,文件名与组件名一致(PascalCase)
- 复杂组件可以建子目录:ComponentName/index.tsx + 子组件
- 基础 UI 组件放 ui/,业务组件放 features/
## 组件结构顺序
1. 'use client'(如果需要)
2. import 语句
3. Props 接口定义
4. 组件函数
5. 辅助函数(组件外部)
## 样式规范
- 优先使用 Tailwind 工具类
- 超过 5 个类名时用 clsx/cn 函数合并
- 响应式断点:sm:640 md:768 lg:1024 xl:1280
- 暗色模式使用 dark: 前缀
## 性能注意事项
- 列表渲染必须有稳定的 key(不用 index)
- 大列表考虑虚拟滚动
- 图片使用 next/image 的 sizes 属性优化加载
而 src/app/api/CLAUDE.md 的内容完全不同:
# API Routes 开发规范
## 文件结构
- 每个路由放在对应目录下:api/posts/route.ts
- 使用 Route Handler 语法(export async function GET/POST/PUT/DELETE)
## 错误处理
- 所有路由必须有 try-catch 包裹
- 统一错误格式:{ error: string, code: string }
- 使用 NextResponse.json() 返回响应
- 4xx 错误返回用户友好的提示,5xx 记录日志但返回通用提示
## 数据校验
- 请求体用 zod schema 校验
- 校验失败返回 400 + 具体的字段错误信息
## 认证
- 需要认证的路由使用 getServerSession() 检查
- 未认证返回 401,无权限返回 403
两份规范,两个场景,各管各的,互不干扰。
2025 年底,Claude Code 上线了一个叫 Auto Memory(自动记忆) 的功能。它跟 CLAUDE.md 互补:
自动记忆的存储位置:~/.claude/projects/<项目名>/memory/
目录结构:
~/.claude/projects/devpulse/memory/
├── MEMORY.md ← 索引文件,启动时加载前 200 行
├── debugging.md ← Claude 记录的调试经验
├── patterns.md ← Claude 发现的代码模式
└── api-conventions.md ← Claude 总结的 API 约定
你可以主动告诉 Claude 记住某件事:
记住:这个项目的数据库连接偶尔会超时,
如果 Prisma 报连接错误,先检查 DATABASE_URL 是否正确,
再检查 PostgreSQL 服务是否在运行
Claude 会把这条信息写入它的 MEMORY.md 文件。下次遇到数据库报错,它会自动回忆起这条经验。
也可以用 /memory 命令直接编辑 MEMORY.md:
/memory
Auto Memory 和 CLAUDE.md 的分工:
┌──────────────────────────────────────────────────────────┐
│ CLAUDE.md vs Auto Memory 分工 │
├────────────────┬─────────────────────────────────────────┤
│ CLAUDE.md │ Auto Memory │
├────────────────┼─────────────────────────────────────────┤
│ 你写的 │ Claude 自己写的 │
│ 指令和规范 │ 经验和发现 │
│ 提交到 Git │ 本地保存 │
│ 团队共享 │ 个人专属 │
│ 启动时全量加载 │ 启动时加载前 200 行 │
│ 你负责维护 │ Claude 自动维护 │
├────────────────┼─────────────────────────────────────────┤
│ 该写什么: │ 该记什么: │
│ 技术栈、规范、 │ 调试经验、踩过的坑、 │
│ 命令、架构约束 │ 发现的项目特殊模式 │
└────────────────┴─────────────────────────────────────────┘
简单说:CLAUDE.md 是项目宪法,Auto Memory 是工作笔记。 一个是你定的规矩,一个是它积累的经验。
如果你的团队有很多规范,全部塞进一个 CLAUDE.md 会很臃肿。从 2025 年末开始,Claude Code 支持模块化规则文件:
.claude/rules/
├── typescript.md ← TypeScript 规范
├── testing.md ← 测试规范
├── api-design.md ← API 设计规范
└── git-workflow.md ← Git 工作流规范
每个规则文件可以通过 frontmatter 指定作用范围:
---
globs: ["src/**/*.tsx", "src/**/*.ts"]
---
# TypeScript 代码规范
- 禁止使用 any,使用 unknown 替代
- 函数返回值必须有显式类型标注
- ...
这份规则只在 Claude 操作匹配 src/**/*.tsx 或 src/**/*.ts 的文件时才会加载。
什么时候用 rules/ 而不是子目录 CLAUDE.md?
rules/(比如所有 .tsx 文件遵循同一套规范)CLAUDE.md(比如 components/ 和 api/ 有不同规范)两者可以混合使用。
除了项目级别的 CLAUDE.md,你还应该有一份全局的 ~/.claude/CLAUDE.md,定义你在所有项目中通用的偏好。
# 全局偏好
## 语言和沟通
- 用中文回答问题和写注释
- 代码中的变量名、函数名、commit message 用英文
- 解释技术概念时优先用类比和例子
## 代码风格
- 缩进:2 个空格
- 引号:单引号(字符串)
- 分号:不使用(除非 ASI 有歧义)
- 命名导入优先于默认导入
## Git 习惯
- commit message 格式:type(scope): description
- 每次提交前先跑 lint 和类型检查
- 不要自动 push,commit 后等我确认
## 回答偏好
- 直接给解决方案,减少铺垫
- 代码修改时说明"为什么"改,不只是"改成什么"
- 有多种方案时列出优劣对比,让我选择
这份全局配置 + 项目级 CLAUDE.md,叠加起来就是完整的上下文。
CLAUDE.md 不是写一次就永远不动的。项目在演进,规范在变化,CLAUDE.md 也需要跟着更新。
┌──────────────────────────────────────────────────────────┐
│ CLAUDE.md 维护策略 │
├──────────────────────────────────────────────────────────┤
│ │
│ 个人项目 / Side Project │
│ ├── 启动时让 Claude 分析并更新: │
│ │ "检查 CLAUDE.md 是否与当前项目一致,有过时内容就更新" │
│ └── 频率:感觉不准的时候随时更新 │
│ │
│ 团队项目 │
│ ├── 纳入 Code Review 流程 │
│ │ → 修改 CLAUDE.md 必须有人 review │
│ ├── 指定一个 owner 定期维护 │
│ └── 频率:每两周或每个 Sprint 检查一次 │
│ │
│ 维护信号(出现以下情况就该更新了): │
│ ├── Claude 生成的代码经常不符合规范 │
│ ├── 你发现自己在会话中反复纠正同一件事 │
│ ├── 项目新增了重要的依赖或架构变更 │
│ └── Code Review 中发现 Claude 遗漏了某个约定 │
│ │
│ 大小控制: │
│ ├── 理想:80-120 行 │
│ ├── 上限:150 行 │
│ ├── 超了怎么办 → 拆分到子目录 CLAUDE.md 或 rules/ │
│ └── 用 @docs/xxx.md 引用详细文档,不要全塞进来 │
│ │
└──────────────────────────────────────────────────────────┘
一个实用技巧:让 Claude 自己检查 CLAUDE.md 的时效性。
读一下 @CLAUDE.md,对比当前项目实际的 package.json 和 tsconfig.json,
看看有没有过时或者不一致的信息,如果有就帮我更新
这样你不用自己一条条核对,Claude 帮你做对账。
前端达人的读者里有不少 Vue 用户,这里提供一份 Vue3 + Nuxt 的 CLAUDE.md 模板:
# [项目名] 项目说明
## 项目概述
[一句话描述项目用途]
## 技术栈
- 框架:Nuxt 3.x(使用 Composition API,不使用 Options API)
- 语言:TypeScript(strict 模式)
- 样式:UnoCSS / Tailwind CSS
- 状态管理:Pinia
- 请求:useFetch / useAsyncData(Nuxt 内置)
- 部署:[Vercel / 阿里云 / 腾讯云]
## 编码规范
- 组件使用 <script setup lang="ts"> 语法
- Props 使用 defineProps<PropsType>() 声明
- Emits 使用 defineEmits<EmitsType>() 声明
- 组合式函数放在 composables/ 目录下,以 use 开头命名
- 页面组件放在 pages/,布局放在 layouts/
- 服务端 API 放在 server/api/
## 常用命令
- 开发:npm run dev / pnpm dev
- 构建:npm run build
- 类型检查:npx nuxi typecheck
- 代码检查:npm run lint
把技术栈换掉,结构和思路是通用的。
三个核心收获:
第一,CLAUDE.md 是 Claude Code 的"项目交接文档"。每次会话自动加载,让 Claude 打开项目就知道该怎么干活。一次编写,永久生效。
第二,记忆系统有五个层级——全局、项目、本地、子目录、自动记忆——它们叠加生效。日常重点维护前两层,其他按需使用。
第三,控制在 100-150 行以内,只写"每次会话都需要的信息"。太模糊的不写("写干净的代码"),太详细的不写(放到 docs/ 目录用 @ 引用),频繁变动的不写(在会话中说就行)。
~/.claude/CLAUDE.md 定义个人偏好全部打勾?Level 2 第一关通过。
第 4 篇:Claude Code 通关手册(四)—— 自定义命令 + 模型策略,把重复劳动砍掉 80%
下一篇解决另一个效率问题——你每天都让 Claude 做代码审查,每次都敲一大段提示词,是不是太浪费生命了?
把高频操作做成 Slash 命令,以后输入 /review auth.ts 一秒搞定。再配合正确的模型选择策略——简单任务用 Haiku 省钱,复杂任务切 Opus 飙性能——你的效率和成本控制都能上一个台阶。
今日话题
你的项目有 CLAUDE.md 吗?写了多少行?效果如何?欢迎在评论区晒出你的 CLAUDE.md(隐去敏感信息),互相参考、互相"抄作业"。
如果这篇文章让你对 CLAUDE.md 有了新的认识,欢迎点赞、在看、转发三连——这可能是整个系列里最能即学即用的一篇。
关注「前端达人」,我们下篇见。