我见过有人的 CLAUDE.md 长这样:

This is a Next.js project. Please help me code.

然后他来问我,为什么 Claude Code 每次生成的代码风格都不一样,为什么它老是用错数据库字段,为什么同样的需求今天能跑明天就报错。

我看完他的配置文件,忍住没说出口的话是:你这写的是个寂寞。

你以为它记得,其实它什么都不记得

Claude Code 没有记忆。

这句话很多人听过,但没真正想明白它的含义。

说人话就是:你昨天告诉它"我们用 Prisma 不用 TypeORM",今天它照样可能给你写 TypeORM 的代码。 不是它叛变了,是它昨天的对话根本没留下任何痕迹。

我自己也在这个坑里栽过。刚开始做一个出海的订阅工具,项目跑了两周,有一天让 Claude Code 加一个新的 API 路由,它给我生成的代码里用了 moment.js

我们全项目都在用 date-fns,这个决定是第一周就定下来的,我跟它说过至少三次。

它不知道。它每次都是第一次见我。

CLAUDE.md 就是用来解决这个问题的——让它每次启动都知道自己在哪、跟谁工作、规矩是什么。

CLAUDE.md 到底是什么、放在哪

先说清楚机制,不然后面的内容你没法理解为什么要这么写。

Claude Code 启动时,会自动读取以下位置的配置文件:

  • 项目级{项目根目录}/CLAUDE.md — 只对当前项目生效

  • 用户级~/.claude/CLAUDE.md — 对你所有项目生效

  • 子目录级:任何子目录里也可以放 CLAUDE.md,进入那个目录的对话会叠加读取

大多数教程只告诉你"在根目录放一个 CLAUDE.md",但没告诉你用户级配置的存在。

这个是真正省时间的地方。你的个人习惯、常用技术偏好、英语不好所以让它用中文回复——这些放到 ~/.claude/CLAUDE.md,一次配置,所有项目受益。

mkdir -p ~/.claude
touch ~/.claude/CLAUDE.md

我的用户级配置长这样:

# 个人偏好

## 语言
- 用中文回复我,代码注释用英文
- 解释技术概念时先给结论,再给原因

## 代码风格
- TypeScript 优先,能不用 any 就不用
- 函数命名用动词开头:getUser、createPayment、validateEmail
- 异步代码统一用 async/await,不用 .then() 链

## 操作习惯
- 改文件前先告诉我改哪里、改什么,让我确认
- 不要主动重构我没提到的代码
- 遇到不确定的需求,先问我再动手

细节:用户级配置和项目级配置会叠加生效,不是覆盖。项目级配置写的内容优先级更高,有冲突时项目级赢。

项目级 CLAUDE.md 怎么写——六个模块缺一不可

我试过很多结构,最后稳定在这六块。顺序不重要,但每块都要有。

模块一:项目定位(5行以内)

# 项目定位

这是一个面向北美中小企业的 SaaS 时间管理工具。
目标用户:10人以下的小团队,英语母语用户为主。
商业模式:按月订阅,用 Stripe 收费。
当前阶段:MVP,核心功能是任务管理和时间追踪。

为什么要写这个?因为 Claude Code 帮你做技术决策时,它需要知道"这个产品是给谁用的"。

同样是"要不要加多语言支持",给北美英语用户就是过度设计,给出海东南亚的产品就是必须做。没有这个背景,它给你的建议是脱离实际的。

模块二:技术栈(明确到库级别)

# 技术栈

## 前端
- Next.js 14,App Router,不用 Pages Router
- Tailwind CSS,组件库用 shadcn/ui
- 状态管理:Zustand(不用 Redux)
- 日期处理:date-fns + date-fns-tz(不用 moment.js、dayjs)

## 后端
- Next.js API Routes(app/api/ 目录)
- 数据库:PostgreSQL,ORM 用 Prisma
- 认证:NextAuth.js v5
- 邮件:Resend(不用 SendGrid、NodeMailer)

## 支付
- Stripe,货币单位 USD
- Webhook 路由:app/api/webhooks/stripe/route.ts

把"不用什么"也写进去,这点 99% 的人没做。

Claude Code 有自己的偏好,moment.js、axios、Redux 这些"老牌"库它非常熟悉,没有明确禁止它会自然而然地用。把你不想要的东西列出来,它就不会给你惊喜了。

模块三:目录结构约定

# 目录结构

app/
  (auth)/          # 认证相关页面
  (dashboard)/     # 登录后的主功能页面
  api/             # API 路由
    webhooks/      # 第三方 webhook 接收
lib/
  db.ts            # Prisma client 单例
  stripe.ts        # Stripe client 单例
  auth.ts          # NextAuth 配置
components/
  ui/              # shadcn/ui 基础组件,不要手动修改
  features/        # 业务功能组件
types/             # TypeScript 类型定义

这个模块的作用是:告诉它新文件放哪里。

没有这个,它可能把 Stripe 的工具函数直接塞进某个 API 路由文件里,下次你找不到,它也找不到。

模块四:出海关键约定(做出海产品必写)

# 出海约定

## 时区
- 数据库存储:统一用 UTC
- 前端显示:用 Intl.DateTimeFormat 或 date-fns-tz 根据用户时区转换
- 禁止用 new Date() 直接格式化展示给用户

## 多语言
- 使用 next-intl,消息文件在 messages/ 目录
- key 格式:模块名.功能名.文案描述,如 dashboard.timer.startButton
- 默认语言 en,当前支持 en 和 zh-TW

## Stripe 支付
- 金额统一用分(cents)存储,100 = $1.00
- 创建 Checkout Session 时必须传 success_url 和 cancel_url
- Webhook 必须验证 signature,用 stripe.webhooks.constructEvent()
- 环境变量:STRIPE_SECRET_KEY、STRIPE_WEBHOOK_SECRET、NEXT_PUBLIC_STRIPE_PUBLISHABLE_KEY

这是做出海产品最容易出问题的三个地方。

时区坑我踩过,Stripe 金额单位坑我也踩过(生产环境把 dollar 当 cent 传进去,有一个用户被收了 100 倍的费,那个晚上我没睡着)。写进去,它就会帮你守这条线。

模块五:当前工作重点

# 当前任务

正在开发:订阅管理页面(app/(dashboard)/billing/)
已完成:用户认证、任务管理核心功能、Stripe Checkout 接入
待完成:Stripe Webhook 处理(subscription 状态同步)、邮件通知

Prisma schema 里已有的表:User、Task、TimeEntry、Subscription
Subscription 表的状态字段:active、canceled、past_due、trialing

这个模块是动态的,每隔几天我会更新一次。

好处是:当我说"继续上次的 Webhook",它知道"上次"是什么。当我让它新建一个功能,它知道已有哪些基础可以复用,不会重复造轮子。

模块六:禁止行为清单

# 禁止行为

- 不要修改 components/ui/ 里的任何文件(这是 shadcn/ui 生成的,改了升级会冲突)
- 不要在客户端组件里直接调用数据库(必须通过 API 路由或 Server Action)
- 不要把密钥硬编码进代码,必须用环境变量
- 不要删除 // @ts-ignore 注释(那是有意为之的临时处理)
- 不要把 console.log 留在生产代码里

说人话就是:这是你的"红线清单"。

Claude Code 有时候会做一些"聪明但危险"的事,比如它觉得某段代码可以优化,就顺手改了,改完你发现逻辑变了。提前把红线写清楚,能省掉很多不必要的修复时间。

踩坑环节

坑一:CLAUDE.md 写了等于没写——因为放错了位置

有一次我配置好了 CLAUDE.md,但发现 Claude Code 完全没在执行里面的规范。排查了半小时,发现我把文件放在了 src/CLAUDE.md,而不是项目根目录。

Claude Code 从启动时的工作目录往上找,不是从 src/ 找。

解决方案: 确认文件在项目根目录,和 package.json 同级。可以用这个命令验证:

ls -la | grep CLAUDE

坑二:写了太多"应该",没写"不应该"——它看到机会就出手

早期我的 CLAUDE.md 只有正向规范,比如"用 date-fns 处理日期"。但有一次它帮我加功能,顺手把一段本来用 new Date() 的老代码也"修"了——用的是 moment.js

因为我没说不让用 moment,它觉得这是帮我升级。

而我整个项目除了那段被它改的代码,没有安装 moment。结果是 build 的时候找不到模块,报错找了二十分钟。

解决方案: 技术选型要正反都写。用什么、不用什么,缺一不可。

总结

CLAUDE.md 的本质是:把你脑子里的隐性知识,变成它每次都能读到的显性规则。

它的上限不是你有多聪明,是你愿意花多少时间把项目规则写清楚。


问你一个实际的问题: 你现在的项目里,有没有某个"不成文的规定"——比如某个文件不能动、某个库是禁忌、某种写法是团队共识——这种规定,你写进 CLAUDE.md 了吗?如果没有,你觉得是什么让你没写?

Logo

这里是“一人公司”的成长家园。我们提供从产品曝光、技术变现到法律财税的全栈内容,并连接云服务、办公空间等稀缺资源,助你专注创造,无忧运营。

更多推荐