同一个项目写两份 CLAUDE.md:一份像项目简介,一份像操作手册。 行数差一行,token 却差 141——中文长句很吃 token,短命令几乎不吃。 这一节给一条可操作的判据:这条如果被违反了,我能当场指出来吗?指不出来的,删掉或者改写。
上一节讲层级,这一节讲项目记忆那一层里到底写什么。 这一层是最常被写坏的:它离开发者最近,很容易被写成一份 README。 但 README 是给人看的,CLAUDE.md 是给模型看并且要它照做的。
一、两种写法的差别不在文笔
演示里两份文件都是给同一个亮化工程管理平台写的,一份十二行,一份十三行。 简介式那份讲项目背景、为什么自研、架构大致什么样,语句通顺,人读着舒服。 手册式那份只有命令、约定、禁区,一句废话没有,人读着像说明书。
指标摆出来差得很明显:简介式模糊词 3 行、可执行行 4 行;手册式模糊词 0 行、可执行行 7 行。 关键不在谁写得好,在于两类句子在模型那儿的待遇完全不同。
二、模糊指令为什么等于没写
「代码结构参考了若干开源项目,尽量保持清晰」——这句话对人不算坏话,写文档时到处都是。 但模型读完不知道该干什么。「尽量保持清晰」到底允不允许一个文件八百行? 「命名上尽量使用英文」能不能用拼音? 每一条模糊指令都会变成一个自由裁量点。 而模型每次裁量的结果可能不一样——同一个任务跑两遍,出来的目录结构可能不同。
不是它不稳定,是这句话本来就允许两种做法。你把判断权交给了它,然后又抱怨它判断得不一样。 还有一个更隐蔽的坏处:模糊句子会占掉注意力。十三条里有两句云里雾里,剩下的十一条也会被稀释。
三、可判定原则
判据只有一条:这条规矩如果被违反了,我能不能当场指出来? 「金额一律用 Decimal,禁止用 float」——能。看一眼类型就知道了。 「新增接口必须同步写 tests 下对应用例」——能。看 tests 目录里有没有对应文件。
「保持适当的耦合度」——不能。什么叫适当?谁来判? 按这条筛一遍,通常会删掉三到四成。删完再读一遍,会发现剩下的每一条都在干活。 删掉的那些不是没用,它们属于 README、属于设计文档、属于新人培训材料。 只是不该占模型的常驻预算。
四、一份能照着写的骨架
第一段放命令。起服务、跑测试、跑迁移、跑 lint,一条一行,照抄能跑。 这段最值钱,因为它是模型最常需要的、也最容易猜错的东西。 第二段放约定。技术栈、命名、目录结构、错误处理方式。写「是什么」不写「为什么」。 第三段放禁区。不要改什么、不要用什么、哪些目录只读。禁区比约定更值钱,因为违反代价高。
第四段可以放验收方式。改完怎么自检,跑哪条命令算过。这一段直接决定它什么时候停。 不要再加第五段。背景、历史、架构图,都放别处。 长度上,一份能用的 CLAUDE.md 通常在一百行以内。 超过两百行,基本可以断定里面混进了本该放技能或者文档的东西。
五、一份能直接抄的骨架
下面这份是按四段结构写的,内容换成你自己的就行。 它不到三十行,覆盖了模型最常需要、也最容易猜错的东西。
# 项目名
## 命令
- 装依赖:uv sync
- 起服务:uv run uvicorn app.main:app --reload
- 跑测试:uv run pytest -q
- 迁移:uv run alembic upgrade head
- 格式化:uv run ruff format .
## 约定
- 金额一律用 Decimal,禁止用 float。
- 新增接口必须同步写 tests/ 下对应用例。
- 组件按业务域分目录,不要建 components/common。
- 提交信息一行写完,不超过五十字。
## 禁区
- 不要直接 pip install,一律走 uv add。
- 不要改 migrations/ 下已提交的脚本,要改就新加一条。
- 不要动 data/raw 下的原始数据,只读。
## 验收
- 改完跑 uv run pytest -q,全绿才算完成。
- 涉及接口的改动,同时贴出 curl 示例。
四段各管一件事:命令让它别猜、约定让它别问、禁区让它别撞、验收让它知道什么时候停。 最后一段最容易被漏掉。没有验收标准,它只能靠自己判断「做完了没有」,而这个判断经常偏乐观。 骨架只是骨架。往里填的每一条都要能过可判定那一关,否则填了也是白填。
六、写完怎么验
第一遍自己读:每一行能不能用「是/否」回答。不能的改写或者删。 第二遍数冲突:同一个主题是不是出现了两次(这跟上一节的叠加有关)。 第三遍实跑:让它按这份文件干一件小事,看它有没有照做。 没照做的那几条,要么写得不够硬,要么本来就不该放在这里。
第三遍最有用,也最少人做。写完不验,等于没写。
七、动手 Demo:两份 CLAUDE.md:一份像简介,一份像操作手册
同一项目、两份文件,行数差不多。 用四个指标量一遍:总行、正文行、模糊词行、可执行行、带路径或命令的行。 然后逐行看那几个模糊词长什么样,再算一遍 token——这里会出现一个反直觉的结果。
VAGUE = [u"尽量", u"适当", u"合理", u"根据需要", u"参考", u"保持", u"逐步"]
ACT = [u"用", u"跑", u"禁止", u"必须", u"不要", u"一律", u"同步"]
def stat(text, name):
body = [x for x in text.split(u"\n") if x.strip() and not x.startswith(u"#")]
vague = [x for x in body if any(v in x for v in VAGUE)]
act = [x for x in body if any(a in x for a in ACT)]
return name, len(body), len(vague), len(act)
实跑输出:
--------------------------------------------------------------------
两份 CLAUDE.md:一份像简介,一份像操作手册
--------------------------------------------------------------------
两份都是给同一个项目写的,行数差不多。差别在哪,先把指标摆出来。
| 写法 | 总行 | 正文行 | 模糊词行 | 可执行行 | 带路径或命令 |
|---|---:|---:|---:|---:|---:|
| 简介式 | 12 | 8 | 3 | 4 | 0 |
| 手册式 | 13 | 9 | 0 | 7 | 3 |
① 差在哪一行
--------------------------------------------------------------------
简介式那份,模糊词命中 3 行,可执行行只有 4 行。
手册式那份,模糊词 0 行,可执行行 7 行。
两组数字说的是同一件事:前者在描述这个项目是什么,后者在告诉模型怎么做。
② 逐行看那几个模糊词
--------------------------------------------------------------------
· 2024 年决定自研一套系统,逐步替代原有流程。
· 代码结构参考了若干开源项目,尽量保持清晰。命名上尽量使用英文,避免拼音。
· 如果需要新增模块,请根据需要合理规划目录结构,保持适当的耦合度。
! 这些句子对人不算坏话,写给人看的文档里到处都是。
但模型读完不知道该干什么:「尽量使用英文」到底允不允许拼音?「合理规划」是按功能分还是按层分?
每一条模糊指令都会变成一个自由裁量点,而模型每次裁量的结果可能不一样。
同一个任务跑两遍,出来的目录结构可能不同——不是它不稳定,是这句话本来就允许两种做法。
③ 手册式怎么写的
--------------------------------------------------------------------
- 起服务:uv run uvicorn app.main:app --reload
- 跑测试:uv run pytest -q
- 迁移:uv run alembic upgrade head
- 金额一律用 Decimal,禁止用 float。
- 新增接口必须同步写 tests/ 下对应用例。
- 组件按业务域分目录,不要建 components/common。
- 提交信息用中文,一行写完,不超过五十字。
- 不要直接 pip install,一律走 uv add。
- 不要改 migrations/ 下已提交的脚本,要改就新加一条。
! 每一条都能当场判定做没做到:用了 uv 没有、测试写了没有、提交信息是不是中文。
能判定,才谈得上遵守。
④ 长度也是指标,但行数不等于 token
--------------------------------------------------------------------
简介式 12 行,手册式 13 行——手册式还多一行。
可 token 是 349 对 208,手册式反而少了 141。
! 中文长句很吃 token,短命令和路径几乎不吃。
简介式那几段漂亮的长句,换算过来比九条命令还贵——而它们对「该怎么做」一点帮助都没有。
所以判断一条该不该留,不看长短看用处。
写给人看的背景说明放 README,给模型的常驻预算只留能判定的句子。
! 判断标准一句话:这条如果被违反了,我能当场指出来吗?指不出来的,删掉或改写。
①第一张表五行数字。简介式模糊词 3 行、可执行 4 行;手册式模糊词 0、可执行 7。 这两组数不是文风差异,是「这段文字能不能被判定」的差异。 ②把模糊词那三行原样打出来。 读一遍就明白问题在哪:每一句都留着裁量空间,而裁量空间就是不一致的来源。 「尽量使用英文,避免拼音」——那变量名叫 user_id 还是 yonghu_id?「避免」到什么程度算避免? 这两句话放在一起,能解释出三种做法。 ③手册式那九条,每一条都能当场判定。这就是可判定原则落地之后的样子。 ④最反直觉的一格在这里:手册式多一行,token 反而少 141。 原因是中文长句吃 token,短命令和路径几乎不吃。简介式那几段漂亮的长句,换算过来比九条命令还贵。 所以「删短一点」这个直觉有时会失效——真正该做的是把长句换成短句,不是把内容砍掉。
30 秒实验
- 把手册式里那条「金额一律用 Decimal,禁止用 float」改写成「金额处理要严谨」,重跑第 ① 步。 哪几个指标会变?
- 给简介式加一段「验收方式」:改完跑 uv run pytest -q 全绿才算完成。可执行行变成几行?
- 找一份你自己项目的 README,按可判定原则过一遍,数一数有几行能留下。
常见误区
- 把 README 改名成 CLAUDE.md。前者讲这个项目是什么,后者讲该怎么动手,两者的读者和用途都不同。
- 以为写得越多越好。常驻内容是每轮都要付的,多一句无关的话就多挤掉一分注意力。
- 用「尽量」「适当」「合理」。这类词在给模型看的文件里等于没写,因为它不知道边界在哪。
- 只写「要做什么」不写「不许做什么」。禁区往往比约定更值钱,因为违反代价高。
- 写完不验。让它按文件干一件小事,是最快发现「这条写得不够硬」的办法。
自测三问(点开对答案)
1. 判断一条规矩该不该留在 CLAUDE.md 里,最快的问法是什么? —— 问「这条如果被违反了,我能不能当场指出来」。 指不出来的说明它是模糊指令,要么改写得更具体,要么挪去 README。 2. 为什么行数多一行、token 反而更少是可能的? —— 因为 token 由字符与词决定,不由行数决定。 中文长句每字几乎都算一个 token,而短命令、路径、参数里有很多可以合并的片段。 3. 一份 CLAUDE.md 通常该写多长?超过多少说明写歪了? —— 能用的一般在一百行以内。 超过两百行,基本可以断定里面混进了本该放技能或文档的内容——那些不需要每轮都在。根目录的写完了,下一节讲怎么让一部分规矩只在碰到某些文件时才生效。
- ☐ (本篇完,下一篇 2.4 条件化规则系统)
相关笔记
- 五层记忆:五层里项目记忆的位置
- 条件化规则:按路径条件加载
- Skill 提效实战 · 索引
- 🐎 Claude Code 实战 · 索引