2026 年 1 月底,Andrej Karpathy 发了一条推文抱怨 Claude 写代码的问题。三种失败模式:沉默的错误假设、过度复杂化、对不该碰的代码造成正交破坏。
Forrest Chang 读了这个帖子,把抱怨打包成 4 条行为规则放进一个 CLAUDE.md 文件,丢到了 GitHub 上。第一天 5828 星。两周 6 万书签。今天 12 万星。 2026 年增长最快的单文件仓库。
然后我在 30 个代码库上测试了 6 周。
这 4 条规则确实有效。在它们擅长的任务上,错误率从 ~40% 降到了 3% 以下。但那个模板是为解决 1 月的代码写作问题而建的。
2026 年 5 月的 Claude Code 生态面临不同的问题——agent 争斗、hook 级联、skill 加载冲突、跨会话断裂的多步骤工作流。
于是我又加了 8 条规则。下面是完整的 12 条规则 CLAUDE.md、每条为什么有资格入选,以及原始 Karpathy 模板在 4 个地方悄悄失效的原因。
如果你只想粘贴使用,完整文件在文章末尾。
为什么这很重要
Claude Code 的 CLAUDE.md 是整个 AI 编程栈里最被低估的文件。大多数开发者要么:
- 把它当成所有偏好的大杂烩,膨胀到 4000+ token,规则遵从率掉到 30%
- 完全跳过它,每次都手动 prompt——5 倍 token 浪费,会话之间毫无一致性
- 复制一个模板然后忘掉。管用两周,然后随着代码库演变悄悄失效
Anthropic 官方文档写得很清楚:CLAUDE.md 是建议性的。Claude 大约 80% 的时间会遵守。超过 200 行后遵从率急剧下降,因为重要规则被噪音淹没了。
Karpathy 的模板用一个文件、65 行、4 条规则解决了这个问题。这是底线。
天花板更高。加上下面的 8 条规则,你覆盖的不只是 Karpathy 抱怨的 2026 年 1 月代码写作问题,还有模板写出来时还不存在的 2026 年 5 月的 agent 编排问题。
原始 4 条规则
如果你还没读过 Forrest Chang 的仓库,这是底线:
规则 1 — Think Before Coding(编码前先思考)。 不要沉默假设。陈述你的假设。暴露权衡。不确定时先问,不要猜。有更简单的方案时主动反馈。
规则 2 — Simplicity First(简单优先)。 解决问题所需的最少代码。不做推测性功能。不对单次使用的代码做抽象。如果高级工程师会说这过度设计了——简化。
规则 3 — Surgical Changes(外科手术式修改)。 只碰必须碰的。不要"改进"相邻代码、注释或格式化。不要重构没坏的东西。匹配现有风格。
规则 4 — Goal-Driven Execution(目标驱动执行)。 定义成功标准。循环迭代直到验证通过。不要告诉 Claude 按步骤做,告诉它成功长什么样,让它自己迭代。
这四条堵住了我在无人监督的 Claude Code 会话中看到的约 40% 的失败模式。剩下的 ~60% 藏在下面的空白里。
我加的 8 条规则(以及为什么)
每条都来自一个真实的时刻——Karpathy 的 4 条不够用的时刻。我先展示那个时刻,再给出规则。
规则 5 — 别让模型做非语言工作
Karpathy 的规则对此只字未提。模型决定了一些本该由确定性代码决定的事情——是否重试 API 调用、如何路由消息、何时升级。每周做不同的决定。一个脆弱的 if-else,花 $0.003 每 token。
## Rule 5 — Use the model only for judgment calls
Use Claude for: classification, drafting, summarization, extraction from unstructured text.
Do NOT use Claude for: routing, retries, status-code handling, deterministic transforms.
If a status code already answers the question, plain code answers the question.
中文对照(条文):
## 规则 5 — 仅将模型用于判断类任务
用 Claude 做:分类、起草、摘要、从非结构化文本中提取信息。
不要用 Claude 做:路由、重试、状态码处理、确定性转换。
若状态码本身已能回答问题,就用普通代码回答。
那个时刻: 用 Claude "判断 503 时是否重试"的代码完美运行了两周,然后开始不稳定——因为模型开始读取请求体作为决策上下文。重试策略变得随机,因为 prompt 是随机的。
规则 6 — 硬性 token 预算,没有例外
没有预算的 CLAUDE.md 是空白支票。每个循环都有机会螺旋上升成 50000 token 的上下文转储。模型自己不会停。
## Rule 6 — Token budgets are not advisory
Per-task budget: 4,000 tokens.
Per-session budget: 30,000 tokens.
If a task is approaching budget, summarize and start fresh. Do not push through.
Surfacing the breach > silently overrunning.
中文对照(条文):
## 规则 6 — Token 预算不是建议
每任务预算:4000 token。
每会话预算:30000 token。
任务接近预算时:总结并重新开始,不要硬撑。
主动暴露超预算,优于默默超支。
那个时刻: 一个调试会话运行了 90 分钟。模型非常乐意在同一个 8KB 错误信息上反复迭代,逐渐忘记它已经试过哪些修复。到最后,它在建议我 40 条消息前就已经否决过的修复。token 预算能在第 12 分钟就把它终止。
规则 7 — 暴露冲突,不要取平均
当代码库的两个部分有分歧时,Claude 试图两全其美。结果是自相矛盾的代码。
## Rule 7 — Surface conflicts, don't average them
If two existing patterns in the codebase contradict, don't blend them.
Pick one (the more recent / more tested), explain why, and flag the other for cleanup.
"Average" code that satisfies both rules is the worst code.
中文对照(条文):
## 规则 7 — 暴露冲突,不要取平均
若代码库中两种既有模式互相矛盾,不要混在一起用。
选一个(较新 / 测试更充分),说明理由,并标记另一套待清理。
两头讨好的「平均」代码是最差的代码。
那个时刻: 一个代码库有两种错误处理模式——一种用 async/await 加显式 try/catch,一种用全局 error boundary。Claude 写的新代码两种都用上了。错误处理器翻倍。花了我 30 分钟才搞明白为什么错误被吞了两次。
规则 8 — 写之前先读
Karpathy 的"外科手术式修改"告诉 Claude 不要碰相邻代码。但它没告诉 Claude 先理解相邻代码。没有这条,Claude 会写出和 30 行外的现有代码冲突的新代码。
## Rule 8 — Read before you write
Before adding code in a file, read the file's exports, the immediate caller, and any obvious shared utilities.
If you don't understand why existing code is structured the way it is, ask before adding to it.
"Looks orthogonal to me" is the most dangerous phrase in this codebase.
中文对照(条文):
## 规则 8 — 写之前先读
在文件里加代码前:先读该文件的导出、直接调用方,以及明显的共享工具。
若不理解现有代码为何这样组织,先问再动手。
「看起来跟我没关系」是本代码库里最危险的一句话。
那个时刻: Claude 在一个已有相同函数的文件旁边加了一个新函数,但它没读那个旧函数。两个函数做同样的事。新函数因为 import 顺序先被执行。旧函数已经当了 6 个月的事实标准。
规则 9 — 测试不是可选项,但也不是目标
Karpathy 的目标驱动执行暗示测试是成功标准。实际上,Claude 把"测试通过"当成唯一目标,写出通过浅层测试但破坏一切的代码。
## Rule 9 — Tests verify intent, not just behavior
Every test must encode WHY the behavior matters, not just WHAT it does.
A test like \`expect(getUserName()).toBe('John')\` is worthless if the function takes a hardcoded ID.
If you can't write a test that would fail when business logic changes, the function is wrong.
中文对照(条文):
## 规则 9 — 测试验证意图,不只验证行为
每个测试都要编码「为何」该行为重要,而不只是「做了什么」。
若函数拿的是硬编码 ID,则像 expect(getUserName()).toBe('John') 这类测试毫无价值。
若写不出在业务逻辑变化时会失败的测试,这个函数就是错的。
那个时刻: Claude 为一个 auth 函数写了 12 个测试。全部通过。线上 auth 是坏的。测试验证的是函数返回了什么,而不是返回的是不是正确的东西。函数通过是因为它返回了一个常量。
规则 10 — 长运行操作需要检查点
Karpathy 的模板假设一次性交互。真正的 Claude Code 工作是多步骤的——跨 20 个文件重构、在一个会话中构建功能、跨多个提交调试。没有检查点,一步走错就丢失所有进度。
## Rule 10 — Checkpoint after every significant step
After completing each step in a multi-step task: summarize what was done, what's verified, what's left.
Don't continue from a state you can't describe back to me.
If you lose track, stop and restate.
中文对照(条文):
## 规则 10 — 每个重要步骤后做检查点
多步骤任务里每完成一步:总结做了什么、验证了什么、还剩什么。
不要从我无法把你当前状态复述回来的地方继续。
若跟丢了,停下并重新陈述。
那个时刻: 一个 6 步重构在第 4 步出错。到我发现时,Claude 已经在错误状态上又做了第 5 和第 6 步。拆解比重新做一遍更花时间。检查点能在第 4 步就截住。
规则 11 — 惯例优于新颖
在有既定模式的代码库里,Claude 喜欢引入自己的模式。即使它的方式"更好",引入两种模式比单独任何一种都更差。
## Rule 11 — Match the codebase's conventions, even if you disagree
If the codebase uses snake_case and you'd prefer camelCase: snake_case.
If the codebase uses class-based components and you'd prefer hooks: class-based.
Disagreement is a separate conversation. Inside the codebase, conformance > taste.
If you genuinely think the convention is harmful, surface it. Don't fork it silently.
中文对照(条文):
## 规则 11 — 匹配代码库惯例,即使你不认同
代码库用 snake_case 而你偏好 camelCase:用 snake_case。
代码库用 class 组件而你偏好 hooks:用 class。
「不认同」可以另开对话;在代码库内,遵守惯例 > 个人品味。
若真心认为某惯例有害,要明确提出来,不要悄悄分叉出一套。
那个时刻: Claude 在一个 class 组件代码库里引入了 React hooks。它们能跑。但它们也破坏了代码库的测试模式——那些测试假设了 componentDidMount。花了半天删除并重写。
规则 12 — 失败要可见,不要沉默
最昂贵的 Claude 失败是那些看起来像成功的。"功能正常"但返回了错误数据。"迁移完成"但跳过了 30 条记录。"测试通过"但仅仅是因为断言写错了。
## Rule 12 — Fail loud
If you can't be sure something worked, say so explicitly.
"Migration completed" is wrong if 30 records were skipped silently.
"Tests pass" is wrong if you skipped any.
"Feature works" is wrong if you didn't verify the edge case I asked about.
Default to surfacing uncertainty, not hiding it.
中文对照(条文):
## 规则 12 — 失败要大声说出来
若不能确定某件事做对,要明确说出来。
若 30 条记录被悄悄跳过,说「迁移完成」就是错的。
若你跳过了任何测试,说「测试通过」就是错的。
若没验证我要求的边界情况,说「功能正常」就是错的。
默认暴露不确定性,不要掩盖。
那个时刻: Claude 说数据库迁移"成功完成"。它悄悄跳过了 14% 的记录——那些记录触发了约束违规。跳过被记录了但没被暴露。11 天后报表开始不对劲时才发现问题。
数据
我在 30 个代码库上追踪了同一组 50 个代表性任务,持续 6 周。三种配置:
错误率(Mistake rate) = 任务需要修正或重写才能匹配意图。计次:沉默错误假设、过度工程、正交破坏、沉默失败、惯例违规、冲突取平均、缺失检查点。
遵从率(Compliance) = Claude 在规则适用时实际可见地应用规则的频率。
有意思的结果不是从 41% 降到 3% 的标题数字。而是从 4 条规则到 12 条规则几乎没增加遵从率开销(78% → 76%),但错误率又降了 8 个百分点。新规则覆盖了原始 4 条没处理的失败模式——它们不争抢同一个注意力预算。
Karpathy 模板在哪些地方悄悄失效
原始 4 条规则模板不够用的四个地方,甚至在加新规则之前:
1. 长运行 agent 任务。 Karpathy 的规则针对 Claude 正在写代码的那一刻。它们对 Claude 运行多步骤流水线时会发生什么只字未提。没有预算规则。没有检查点规则。没有"大声失败"规则。流水线会漂移。
2. 多代码库一致性。 "匹配现有风格"假设只有一种风格。在 12 个服务的 monorepo 里,Claude 必须选一种风格。原始规则没告诉它怎么选。它随机选,或者取平均。
3. 测试质量。 目标驱动执行把"测试通过"当成功。没说要测试有意义。结果是测试什么都没测但让 Claude 很自信。
4. 生产 vs 原型。 保护生产代码免于过度工程的同 4 条规则,也拖慢了那些确实需要 100 行推测性脚手架来探索方向的原型。Karpathy 的"简单优先"在早期代码上误伤率太高。
这 8 条新增规则不是在替换 Karpathy 的 4 条。它们填补了空白——他的模型(2026 年 1 月、自动补全式编码)与 2026 年 5 月的 agent 驱动、多步骤、多代码库工作之间的空白。
什么没用
在我最终确定 12 条规则之前试过的东西:
- 加我在 Reddit / X 上看到的规则。 大多数要么是 Karpathy 4 条的同义反复,要么是领域特定的("始终用 Tailwind 类名")无法泛化。删了。
- 超过 12 条规则。 我测试到 18 条。超过 14 条后遵从率从 76% 降到 52%。200 行的天花板是真实的。超过之后,Claude 开始模糊匹配"规则存在"而不实际读取它们。
- 依赖可能不存在的工具的规则。 "始终用 eslint"——当 eslint 没装时就坏了。规则悄悄失效。替换为与能力无关的表述:"匹配代码库强制执行的风格"而不是"用 eslint"。
- 在 CLAUDE.md 里放示例而不是规则。 示例比规则更重。三个示例的成本相当于约 10 条规则,而且 Claude 对它们过拟合。规则是抽象的,示例是具体的。用规则。
- "小心" / "仔细想" / "真正专注"。 纯粹的噪音。对这些话的遵从率掉到 ~30%,因为它们不可验证。替换为具体指令("明确陈述假设")。
- 告诉 Claude 要"资深"。 没用。Claude 已经觉得自己很资深了。遵从差距在"想"和"做"之间。指令式规则能弥合这个差距;身份提示不能。
完整 12 条规则 CLAUDE.md(可直接粘贴)
# CLAUDE.md — 12-rule template
These rules apply to every task in this project unless explicitly overridden.
Bias: caution over speed on non-trivial work. Use judgment on trivial tasks.
## Rule 1 — Think Before Coding
State assumptions explicitly. If uncertain, ask rather than guess.
Present multiple interpretations when ambiguity exists.
Push back when a simpler approach exists.
Stop when confused. Name what's unclear.
## Rule 2 — Simplicity First
Minimum code that solves the problem. Nothing speculative.
No features beyond what was asked. No abstractions for single-use code.
Test: would a senior engineer say this is overcomplicated? If yes, simplify.
## Rule 3 — Surgical Changes
Touch only what you must. Clean up only your own mess.
Don't "improve" adjacent code, comments, or formatting.
Don't refactor what isn't broken. Match existing style.
## Rule 4 — Goal-Driven Execution
Define success criteria. Loop until verified.
Don't follow steps. Define success and iterate.
Strong success criteria let you loop independently.
## Rule 5 — Use the model only for judgment calls
Use me for: classification, drafting, summarization, extraction.
Do NOT use me for: routing, retries, deterministic transforms.
If code can answer, code answers.
## Rule 6 — Token budgets are not advisory
Per-task: 4,000 tokens. Per-session: 30,000 tokens.
If approaching budget, summarize and start fresh.
Surface the breach. Do not silently overrun.
## Rule 7 — Surface conflicts, don't average them
If two patterns contradict, pick one (more recent / more tested).
Explain why. Flag the other for cleanup.
Don't blend conflicting patterns.
## Rule 8 — Read before you write
Before adding code, read exports, immediate callers, shared utilities.
"Looks orthogonal" is dangerous. If unsure why code is structured a way, ask.
## Rule 9 — Tests verify intent, not just behavior
Tests must encode WHY behavior matters, not just WHAT it does.
A test that can't fail when business logic changes is wrong.
## Rule 10 — Checkpoint after every significant step
Summarize what was done, what's verified, what's left.
Don't continue from a state you can't describe back.
If you lose track, stop and restate.
## Rule 11 — Match the codebase's conventions, even if you disagree
Conformance > taste inside the codebase.
If you genuinely think a convention is harmful, surface it. Don't fork silently.
## Rule 12 — Fail loud
"Completed" is wrong if anything was skipped silently.
"Tests pass" is wrong if any were skipped.
Default to surfacing uncertainty, not hiding it.
中文对照(全文模板,与上表对照阅读;实际粘贴进仓库时原文作者仍以英文短语为主):
# CLAUDE.md — 12 条规则模板
除非另有说明,下列规则适用于本项目的每一项任务。
倾向:在非琐碎工作上宁愿谨慎也不要一味求快;琐碎任务可自行判断。
## 规则 1 — 编码前先思考
明确陈述假设。不确定时先问,不要猜。
存在歧义时呈现多种理解。
有更简单的做法时主动提出。
困惑就停下来,说清楚哪里不清楚。
## 规则 2 — 简单优先
用最少代码解决问题,不做无根据的臆测。
不添加超出需求的功能。不对只用一次的代码做抽象。
检验标准:资深工程师会觉得过度复杂吗?若是,则简化。
## 规则 3 — 外科手术式修改
只改必须改的部分,只收拾自己弄乱的地方。
不要「顺手改进」相邻代码、注释或格式。
没坏就不要重构。遵循现有风格。
## 规则 4 — 目标驱动执行
定义成功标准,循环迭代直到验证通过。
不要机械执行步骤。定义什么叫成功,再迭代。
清晰的成功标准才能让你独立迭代。
## 规则 5 — 仅将模型用于判断类任务
用我做:分类、起草、摘要、信息提取。
不要用我做:路由、重试、确定性转换。
代码能回答的,就让代码回答。
## 规则 6 — Token 预算不是建议
每任务:4000 token。每会话:30000 token。
接近预算时总结并重新开始。
暴露超预算,不要悄悄超限。
## 规则 7 — 暴露冲突,不要取平均
若两种模式矛盾,选一种(较新 / 测试更充分)。
说明理由,并标记另一套待清理。
不要混搭互相矛盾的范式。
## 规则 8 — 写之前先读
加代码前先读导出、直接调用方、共享工具。
「看起来正交」很危险。若不清楚现有结构为何如此,先问。
## 规则 9 — 测试验证意图,不只验证行为
测试必须编码为何行为重要,而不只是做了什么。
业务逻辑变更时仍不会失败的测试是错的。
## 规则 10 — 每个重要步骤后做检查点
总结做了什么、验证了什么、还剩什么。
不要从无法对当前状态复盘的状态继续。
跟丢了就停下并重新陈述。
## 规则 11 — 匹配代码库惯例,即使你不认同
在代码库内,遵守惯例优先于个人品味。
若真心认为某惯例有害,要明确提出来,不要悄悄分叉。
## 规则 12 — 失败要大声说出来
若有任何事被悄悄跳过,「完成」就是错的。
若有任何测试被跳过,「测试通过」就是错的。
默认暴露不确定性,不要掩盖。
保存为仓库根目录的 CLAUDE.md。在 12 条之下添加项目特定规则(技术栈、测试命令、错误模式)。总共不要超过 200 行,超过后遵从率会下降。
怎么安装
两步:
# 1. 将 Karpathy 的 4 条规则基线追加到你的 CLAUDE.md
curl https://raw.githubusercontent.com/forrestchang/andrej-karpathy-skills/main/CLAUDE.md >> CLAUDE.md
# 2. 把本文的规则 5-12 粘贴到下面
保存到仓库根目录。>> 很重要——它追加到你现有的 CLAUDE.md 而不是覆盖你已经有的项目特定规则。
心法模型
CLAUDE.md 不是愿望清单。它是一个行为契约,堵住你观察到的特定失败模式。
每条规则应该回答:这条防止什么错误?
![[b0a897e35c71724b5b8e13644cb08945_MD5.jpg]]
Karpathy 的 4 条防止他在 2026 年 1 月看到的失败模式: 沉默假设、过度工程、正交破坏、弱成功标准。它们是基础。不要跳过它们。
我加的 8 条防止 2026 年 5 月出现的失败模式: 没有预算的 agent 循环、没有检查点的多步骤任务、不测试的测试、隐藏失败的沉默成功。它们是累加的。
你的效果会不同。如果你不跑多步骤流水线,规则 10 就不重要。如果你的代码库有 linting 强制执行的一致风格,规则 11 就是多余的。读完 12 条,保留那些对应你实际犯过的错误的,删掉其余的。
一个针对你真实失败模式调优的 6 条规则 CLAUDE.md,胜过有 6 条你永远不需要的 12 条规则版本。
完
Karpathy 2026 年 1 月的帖子是一次抱怨。Forrest Chang 把它变成了 4 条规则。12 万开发者收藏了结果。他们中的大多数人今天还在跑这 4 条规则。
模型进步了。生态变了。多步骤 agent、hook 级联、skill 加载、多代码库工作——这些都是 Karpathy 发帖时不存在的东西。这 4 条规则不处理它们。它们没有错;它们是不完整的。
又加了 8 条。在 30 个代码库上 6 周的测试。错误率从 41% 到 3%。
收藏本文,今晚就把 12 条规则粘贴进你的 CLAUDE.md。如果它省了你一周的 Claude 走弯路,转发.