Clipping 微信公众号

别再让 `-init` 自己跑了:90% 的人都漏了 CLAUDE.md 这一步

Created: 2026-05-23

公众号名称:三木AI编程

作者名称:Sam

发布时间:2026-05-23 13:01

一个被严重低估的命令,毁了多少人的 Claude Code 体验

上周一个做跨境电商 SaaS 的朋友找我吐槽:「Claude Code 越用越蠢,每次让它改个组件,它都要我把项目结构再讲一遍,比新来的实习生还费劲。」

我让他打开项目根目录,问了一句:「你的 CLAUDE.md 多大?」

他愣了三秒:「啥 md?」

——这就是问题所在。用 Claude Code 超过一个月却没认真读过 CLAUDE.md 的人,占了至少七成。/init 这个命令大家都跑过,但跑完之后那个文件里写了什么、该怎么改、什么时候重新生成,基本没人深究。结果就是:你以为 AI 懂你的项目,其实它每次都在盲人摸象。

为什么这个命令值得单独写一篇

我自己也踩过这个坑。去年做一个面向东南亚市场的订阅制 Web 产品,项目结构有点复杂——前端 Next.js + i18n 多语言、后端 Hono on Cloudflare Workers、数据库 D1、支付走 Stripe。我兴冲冲装上 Claude Code,直接 claude 进入 REPL 开干。

前两天感觉良好。第三天开始崩。

让它在结算页加一个「按用户时区显示订阅续费时间」的功能,它给我返回的代码用的是 new Date().toLocaleString() ——在 Cloudflare Workers 里跑 Intl API 是有坑的(后面踩坑环节细说)。我以为是模型能力问题,换了几次提示词,结果还是不对。

后来我才发现:它根本不知道我用的是 Workers 运行时,因为我从来没告诉过它,而 /init 默认生成的 CLAUDE.md 也没识别出来。

说人话就是——/init 是起点,不是终点。绝大多数教程到这里就结束了,但真正决定 Claude Code 好不好用的,是这个文件后续怎么维护。

核心:把 /init 当成项目的「记忆持久化」来用

第一步:理解 /init 到底在干什么

官方说明很简短:扫描当前文件夹,生成 CLAUDE.md,作为后续对话的上下文。

但有几个细节需要扣清楚:

  • 它不是把所有代码都塞进去。如果是这样,大项目分分钟爆 token。它做的是「项目知识图谱」——提取目录结构、关键技术栈、入口文件、约定规范。

  • 它生成的内容是给 AI 看的,不是给你看的。所以你看到的 CLAUDE.md 可能写得平平无奇,但每次对话它都会被自动注入上下文。

  • 它只创建/更新 CLAUDE.md,绝对不动其他文件。这点放心,可以随便跑。

在项目根目录直接执行:

/init

这段命令在做什么:让 Claude Code 扫描你当前所在的整个目录,把它”理解”到的项目信息写成 markdown。这里有个细节要注意:它读的是「当前工作目录」,不是你 git 仓库的根。如果你在子目录里跑,生成的图谱就是子目录的——这个我后面也踩过。

第二步:打开生成的 CLAUDE.md,准备手动改

跑完 /init 别急着进入下一轮对话。先用编辑器打开 CLAUDE.md,通读一遍。

你大概会看到类似这样的结构(以一个出海 Web 项目举例):

# Project Overview
This is a Next.js application with TypeScript...

# Directory Structure
- /app: Next.js app router pages
- /components: React components
- /lib: Utility functions
...

# Key Dependencies
- next@14.2.0
- react@18.3.0
...

这段内容在做什么:Claude Code 给你的项目做了一份”自我介绍”。但坦白讲,默认生成的内容偏「字面识别」——它能看到你装了什么包,但看不到你的业务约定。

这里有个细节要注意:Claude Code 在每次对话开始时,会把这个文件作为系统级上下文加载。也就是说,你写在这里的每一句话,都会”持久”地影响后续所有对话。这是个金矿,但大多数人没用起来。

第三步:补充「大多数教程不告诉你」的关键信息

这是我自己踩了无数坑后总结的、做出海 Web 产品时必须手动加进 CLAUDE.md 的几类信息:

1. 运行时环境的精确说明

## Runtime Environment
- Backend runs on Cloudflare Workers (NOT Node.js)
- Do NOT use Node-specific APIs like `fs`, `path`, `Buffer`
- Use Web Standard APIs: `fetch`, `Request`, `Response`, `crypto.subtle`
- Database: Cloudflare D1 (SQLite-compatible, accessed via env.DB binding)

说人话就是:你不告诉它你跑在 Workers 上,它默认就当 Node.js 给你写代码,然后你部署的时候喜提一堆 runtime error。

2. 国际化与时区的硬约定

## i18n & Timezone Rules
- All timestamps stored as UTC ISO 8601 strings in database
- Frontend displays time in user's local timezone via `Intl.DateTimeFormat`
- Supported locales: en-US, ja-JP, ko-KR, zh-TW, id-ID
- Translation keys live in `/locales/{locale}/common.json`
- NEVER hardcode user-facing strings; always use `t('key.path')`

这段内容在做什么:把项目里”心照不宣”的规矩明文化。AI 不会读心,你不写,它就乱来。我加完这段之后,Claude Code 再也没给我硬编码过英文文案。

3. 支付集成的关键约束

## Stripe Integration
- Use Stripe API version: 2024-06-20
- All amounts in smallest currency unit (cents for USD, yen for JPY without decimals)
- Webhook endpoint: /api/webhooks/stripe (must verify signature)
- Test mode keys are in .dev.vars; production keys via Workers secrets
- For Japan market: use Konbini payment method, not just card

这里有个细节要注意:日元、韩元这些没有小数的货币,Stripe 的金额单位规则跟美元不一样。AI 默认按美元逻辑给你写 amount * 100,日元市场直接金额放大 100 倍。这种坑不写进 CLAUDE.md,你每次都得手动提醒。

4. 项目特有的命名与目录约定

## Conventions
- API routes follow REST: GET/POST/PATCH/DELETE under /app/api/v1/
- All API responses use shape: { ok: boolean, data?: T, error?: { code, message } }
- Components: PascalCase files, default export
- Hooks: camelCase starting with `use`, named export
- Tests colocated as *.test.ts next to source

第四步:用 Prompt 让 Claude Code 自己帮你完善 CLAUDE.md

这是大多数人不知道的玩法。/init 生成的是初版,但你可以让 Claude Code 自己迭代它。

我常用的 Prompt 是这样:

请阅读当前的 CLAUDE.md,然后扫描以下文件:/lib/db.ts/middleware.ts/app/api/v1/checkout/route.ts。基于这些文件实际使用的 API 和模式,在 CLAUDE.md 中追加一个章节 ## Codebase Patterns,记录:1) 数据库查询的统一封装方式;2) 鉴权中间件的使用约定;3) API 错误处理的标准模式。每条不超过 2 行,要具体到函数名。

这段 Prompt 在做什么:让 AI 不靠”猜”,而是基于真实代码总结约定,然后把总结沉淀到自己的”长期记忆”里。

跑完之后,CLAUDE.md 里就会多出这样的内容:

## Codebase Patterns
- DB queries: always use `db.query(env.DB).select(...)` from `/lib/db.ts`, never raw SQL
- Auth: protected routes wrap handler with `withAuth(handler)` from `/middleware.ts`
- API errors: throw `ApiError(code, message, status)`, caught by global handler

这里有个细节要注意:这种”自反式”更新比手写效率高一个量级,但你必须每次审一眼,因为 AI 偶尔会总结错。我一般跑完之后用 git diff CLAUDE.md 看一下改了什么。

第五步:配合 /clear 形成稳定工作流

/init/clear 是一对。我的常规节奏是:

# 项目结构有大变动后
/init

# 通读并手动补充 CLAUDE.md(花 5 分钟)

# 清空旧对话,带着新上下文重新开始
/clear

# 开始新一轮开发

说人话就是:把 CLAUDE.md 当成项目的”出厂设置”,每次重大变更后刷新一次。日常开发不需要每次都跑 /init,但每两周或每个 milestone 跑一次,长期下来对话质量稳定得多。

踩坑环节

坑一:在子目录跑 /init,生成的图谱缺一大半

我有一次在 monorepo 的 /apps/web 子目录里直接 claude,然后 /init。生成的 CLAUDE.md 只包含 web 这个子项目,完全不知道 /packages/shared 里有共用的类型定义和工具函数。

怎么发现的:让它写一个用到 shared 包里 formatCurrency 的组件,它自己重新写了一个一模一样的函数,放在了 /apps/web/lib 下。我看到这段代码愣了一下——明明已经有了为什么不复用?然后才反应过来它根本不知道 shared 包存在。

怎么解决的:在 monorepo 根目录跑 /init,生成全局 CLAUDE.md;同时在每个子项目里也单独跑,作为补充。配合 --add-dir 参数显式把 shared 包加进工作目录。这个坑我卡了大概一个半小时才搞明白。

坑二:CLAUDE.md 写得太详细,反而把 token 上下文撑爆

第一次知道可以手动编辑 CLAUDE.md 之后,我兴奋过头,把项目里几乎所有约定、所有 API、所有边界 case 都塞进去,文件膨胀到 800 多行。

怎么发现的:某天对话进行到一半,Claude Code 提示上下文紧张,我跑 /context 查了一下,发现光 CLAUDE.md 自己就吃掉了 30% 的 context window,导致后续对话动不动就需要 /compact

怎么解决的:重写 CLAUDE.md,定一条原则——只写”AI 不看代码就猜不到”的信息。代码里能直接读出来的(比如某个函数怎么用),不写;约定、运行时、业务规则、命名习惯,这些隐性知识才写。砍完之后从 800 行压到 180 行,效果反而更好。

总结

/init 不是一次性命令,而是项目和 AI 的「契约文件」起点——你愿意花多少时间维护这份契约,Claude Code 就能给你多大的杠杆。


**最后一个实际的问题:**如果你已经在用 Claude Code 做项目,打开你的 CLAUDE.md 看一眼:里面有几条信息是你手动加的、而不是 /init 自动生成的? 评论区聊聊你加了什么最有用的一条,我挑几个有意思的回复在下篇文章里细聊。


cover_image

Original Sam 三木AI编程


内容效果不满意?点此反馈

输入关键词开始搜索