Claude写代码总出错?这12条规则把错误率降到了 3%

原文标题:Karpathy’s 4 CLAUDE.md rules cut Claude mistakes from 41% to 11%. After 30 codebases, I added 8 more
原文作者:@Mnilax
编译:Peggy,BlockBeats

编者按:2026 年 1 月,Andrej Karpathy 对 Claude 写代码的吐槽,引出了一个看似很小、但在 AI 编程工作流中极其关键的文件:CLAUDE.md。Forrest Chang 随后将这些问题整理成 4 条行为规则,试图约束 Claude 在编码时常见的错误:静默假设、过度工程化、误伤无关代码,以及缺乏清晰的成功标准。

但几个月后,Claude Code 的使用场景已经不再只是「让模型写一段代码」。随着多步骤 Agent、hook 链式触发、skill 加载和多代码库协作成为常态,新的失败模式也开始出现:模型在长任务中失控、测试通过却没有验证真实逻辑、迁移完成但静默跳过错误、不同代码风格被错误混合。

本文作者在 6 周内测试了 30 个代码库,并在 Karpathy 原有 4 条规则基础上新增 8 条规则,试图覆盖 AI 编程从单次补全走向 Agent 化协作后的新问题。

以下为原文:

2026 年 1 月下旬,Andrej Karpathy 发了一条推文串,吐槽 Claude 写代码的方式。他指出了三类典型问题:在没有说明的情况下做出错误假设、过度复杂化,以及对原本不该改动的代码造成无关破坏。

Forrest Chang 看到了这条推文串,把其中的抱怨整理成 4 条行为规则,写进一个单独的 CLAUDE.md 文件,并发布到了 GitHub。这个项目上线第一天就获得了 5,828 个 Star,两周内被收藏 60,000 次,如今已有 120,000 个 Star,成为 2026 年增长最快的单文件代码仓库。

随后,我在 6 周时间里,用 30 个代码库对它进行了测试。

这 4 条规则确实有效。过去大约 40% 概率会出现的错误,在适合这些规则发挥作用的任务中,下降到了 3% 以下。但问题在于,这个模板最初是为了解决 1 月份 Claude 写代码时出现的错误。

到了 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:编码前先思考。

不要默默做假设。要说明你的假设,暴露权衡点。在猜测之前先提问。当存在更简单的方案时,要主动提出反对意见。

规则 2:简单优先。
用能解决问题的最少代码。不要加入想象中的功能。不要为一次性代码设计抽象层。如果一位资深工程师会认为它过度复杂,那就应该简化。

规则 3:外科手术式修改。
只改必须改的部分。不要顺手「优化」相邻代码、注释或格式。不要重构没有坏掉的东西。保持与现有风格一致。

规则 4:以目标为导向执行。
先定义成功标准,然后循环迭代,直到完成验证。不要告诉 Claude 每一步该怎么做,而是告诉它成功结果应该是什么样,让它自己迭代。

这 4 条规则,能解决我在无人监督的 Claude Code 会话中看到的大约 40% 的失败模式。剩下约 60% 的问题,则藏在下面这些空白地带。

我新增的 8 条规则,以及为什么

每一条规则,都来自一个真实时刻:Karpathy 原来的 4 条规则已经不够用了。下面我会先讲那个场景,再给出对应规则。

规则 5:不要让模型做非语言类工作

可以用 Claude 处理:分类、起草、总结、从非结构化文本中提取信息。 不要用 Claude 处理:路由、重试、状态码处理、确定性转换。 如果一个状态码已经回答了问题,那就让普通代码来回答这个问题。

Karpathy 的规则没有覆盖这一点。于是模型开始决定一些本该由确定性代码处理的问题:是否重试一次 API 调用、如何路由一条消息、什么时候升级处理。结果是,每周的判断都不一样。你得到的是一种按每 token 0.003 美元计费的、不稳定的 if-else。

那个时刻是这样的:有一段代码会调用 Claude 来「判断遇到 503 时是否应该重试」。它一开始运行得很好,持续了两周,后来突然变得不稳定,因为模型开始把请求体也当作判断上下文。重试策略变得随机,因为 prompt 本身就是随机的。

规则 6:设置硬性 token 预算,没有例外

单个任务预算:4,000 tokens。 单次会话预算:30,000 tokens。 如果一个任务接近预算上限,就总结当前状态,然后重新开始。不要硬撑着继续。 明确暴露预算超限问题,比默默超支更好。

没有预算约束的 CLAUDE.md,就等于一张空白支票。每一次循环都有可能失控,变成一次 50,000 token 的上下文倾倒。模型不会自己停下来。

那个时刻是这样的:一次调试会话持续了 90 分钟。模型一直在围绕同一段 8KB 的错误信息反复迭代,并逐渐忘记自己已经尝试过哪些修复方案。到最后,它开始提出 40 条消息之前我已经否定过的方案。如果有 token 预算,这个过程在第 12 分钟就该被终止。

规则 7:暴露冲突,不要折中平均

如果代码库中已有的两种模式相互矛盾,不要把它们混在一起。 选择其中一种模式,优先选择更新的或经过更多测试的模式,说明理由,并标记另一种模式后续需要清理。 那种试图同时满足两套规则的「平均代码」,是最糟糕的代码。

当代码库里的两个部分互相矛盾时,Claude 会试图同时讨好两边,结果写出来的是一团不连贯的代码。

那个时刻是这样的:一个代码库里存在两套错误处理模式,一套是 async/await 加显式 try/catch,另一套是全局错误边界。Claude 写出的新代码把两套都用了。结果错误处理被做了两遍。我花了 30 分钟才弄明白,为什么错误被吞掉了两次。

规则 8:先读,再写

在一个文件里新增代码之前,先阅读这个文件的导出内容、直接调用方,以及任何明显相关的共享工具函数。 如果你不理解现有代码为什么这样组织,就先提问,不要直接往里加东西。 「在我看来这不相关」,是这个代码库里最危险的一句话。

Karpathy 的「外科手术式修改」告诉 Claude 不要改动相邻代码。但它没有告诉 Claude:先理解相邻代码。没有这一条,Claude 会写出和 30 行之外既有代码相冲突的新代码。

那个时刻是这样的:Claude 在一个已有函数旁边新增了一个功能完全相同的函数,因为它没有先读原来的函数。两个函数做的是同一件事。但由于 import 顺序的关系,新函数覆盖了旧函数,而旧函数已经作为事实上的唯一标准存在了 6 个月。

规则 9:测试不是可选项,但测试本身不是目标

每一个测试都必须编码「为什么这个行为重要」,而不只是「它做了什么」。 像 expect(getUserName()).toBe(‘John’) 这样的测试是没有价值的,如果这个函数其实接收的是一个硬编码 ID。 如果你写不出一个会在业务逻辑变化时失败的测试,那这个函数本身就是错的。

Karpathy 的「以目标为导向执行」暗示测试可以作为成功标准。但在实践中,Claude 会把「测试通过」当成唯一目标,于是写出一些能通过浅层测试、却会破坏其他东西的代码。

那个时刻是这样的:Claude 为一个认证函数写了 12 个测试,全部通过。但生产环境里的认证逻辑坏了。那些测试只是在验证函数「返回了某个东西」,而不是验证它是否返回了正确的东西。函数之所以能通过测试,是因为它返回的是一个常量。

规则 10:长时间运行的操作需要检查点

在多步骤任务中,每完成一个步骤后,总结已经做了什么、验证了什么、还剩下什么。 不要从一个你无法向我复述清楚的状态继续往下做。 如果你发现自己已经跟丢了,就停下来,重新陈述当前状态。

Karpathy 的模板默认交互是一次性的。但真实的 Claude Code 工作往往是多步骤的:跨 20 个文件重构、在一个会话里构建功能、跨多个 commit 调试。如果没有检查点,一步走错,前面所有进度都可能丢失。

那个时刻是这样的:一个 6 步重构任务在第 4 步出错了。等我发现时,Claude 已经在错误状态之上继续完成了第 5 步和第 6 步。拆解修复花的时间,比重做整个任务还长。如果有检查点,第 4 步就能发现问题。

规则 11:约定优先于新意

如果代码库使用 snake_case,而你更喜欢 camelCase:使用 snake_case。 如果代码库使用 class-based components,而你更喜欢 hooks:使用 class-based components。 不同意见是另一场讨论。在代码库内部,一致性优先于个人偏好。 如果你真的认为某个约定有害,就明确提出。不要默默开出一条分叉路径。

在一个已经有成熟模式的代码库里,Claude 喜欢引入自己的写法。哪怕它的写法「更好」,引入第二套模式本身,也比任何一种单一模式都更糟。

那个时刻是这样的:Claude 在一个基于 class component 的 React 代码库里引入了 hooks。它确实能运行。但它同时破坏了代码库原有的测试模式,因为那些测试依赖 componentDidMount。最后花了半天时间才把它删掉并重写。

规则 12:要显性失败,不要静默失败

如果你不能确定某件事已经成功,就明确说出来。如果有 30 条记录被静默跳过,就不能说「迁移完成」。如果你跳过了任何测试,就不能说「测试通过」。如果你没有验证我要求的边界情况,就不能说「功能可用」。默认暴露不确定性,而不是隐藏它。

Claude 最昂贵的失败,往往是那些看起来像成功的失败。一个函数「能跑」,但返回了错误数据;一次 migration「完成了」,但跳过了 30 条记录;一个测试「通过了」,但只是因为断言本身是错的。

那个时刻是这样的:Claude 说一次数据库迁移「成功完成」。但实际上,它静默跳过了 14% 触发约束冲突的记录。跳过行为被写进了日志,却没有被明确暴露出来。11 天后,当报表数据开始异常时,我们才发现问题。

数据结果

我在 6 周时间里,追踪了同一组 50 个代表性任务,覆盖 30 个代码库,测试了三种配置。

错误率指的是:任务需要被纠正或重写,才能匹配原始意图。计入的错误包括:静默错误假设、过度工程化、无关破坏、静默失败、违反约定、冲突折中、漏掉检查点。

遵守率指的是:当某条规则适用时,Claude 有多大概率会显性应用这条规则。

真正有意思的结果,不只是错误率从 41% 降到 3%。更重要的是,从 4 条规则扩展到 12 条规则,几乎没有增加遵守负担,遵守率只是从 78% 变成 76%,但错误率又下降了 8 个百分点。新增规则覆盖的是原来 4 条规则没有处理的失败模式,它们并没有争夺同一块注意力预算。

Karpathy 模板会在哪些地方悄悄失效

即便不加入新规则,原来的 4 条规则模板也至少在 4 个地方不够用。

第一,长时间运行的 Agent 任务。
Karpathy 的规则主要针对 Claude 正在写代码的那一刻。但当 Claude 在运行一个多步骤 pipeline 时,会发生什么?原模板没有预算规则,没有检查点规则,也没有「大声失败」规则。于是 pipeline 会慢慢漂移。

第二,多代码库一致性。
「匹配现有风格」默认只有一种风格。但在一个拥有 12 个服务的 monorepo 里,Claude 必须选择到底匹配哪一种风格。原始规则没有告诉它怎么选。于是它要么随机选择,要么把几种风格平均混合。

第三,测试质量。
「以目标为导向执行」会把「测试通过」视为成功,却没有说明测试本身必须有意义。结果就是,Claude 写出一些几乎什么都没验证的测试,但这些测试会让它误以为自己很有把握。

第四,生产环境与原型阶段的差异。
同样的 4 条规则,可以防止生产代码被过度工程化,但也可能拖慢原型开发。因为原型阶段有时确实需要 100 行探索性脚手架,先摸清方向。Karpathy 的「简单优先」在早期代码里容易过度触发。

这 8 条新增规则并不是要取代 Karpathy 的原始 4 条规则,而是在修补它们的空白:原模板对应的是 2026 年 1 月那种偏自动补全式的代码写作场景;而到了 2026 年 5 月,Claude Code 已经进入由 Agent 驱动的、多步骤、多代码库协作环境,两者面对的问题并不一样。

哪些方法没有奏效

在最终确定这 12 条规则之前,我也尝试过一些其他方案。

加入我在 Reddit / X 上看到的规则。
其中大多数,要么只是用不同说法重复 Karpathy 原来的 4 条规则,要么是无法泛化的领域特定规则,比如「始终使用 Tailwind class」。最后都删掉了。

超过 12 条规则。
我最多测试到 18 条。超过 14 条后,遵守率从 76% 掉到了 52%。200 行的上限是真实存在的。超过这个长度后,Claude 就会开始模式匹配成「这里有规则」,而不是真的逐条阅读规则。

依赖某些工具存在的规则。
比如「始终使用 eslint」,一旦项目里没有安装 eslint,这条规则就会失效,而且是静默失效。后来我把它改成了不依赖具体工具的表达,比如把「使用 eslint」改成「遵循代码库中已经强制执行的风格」。

在 CLAUDE.md 里放示例,而不是规则。
示例比规则更占上下文。三个示例消耗的上下文,差不多相当于 10 条规则,而且 Claude 很容易对示例过拟合。规则是抽象的,示例是具体的。所以,应当使用规则。

「小心一点」「认真思考」「专注一点」。
这些都是噪音。这类指令的遵守率掉到了大约 30%,因为它们无法被检验。后来我把它们替换成了更具体的命令式规则,比如「明确说明假设」。

告诉 Claude 要像「资深工程师」一样。
这没有用。Claude 本来就觉得自己像资深工程师。真正的问题不在于它是否这样认为,而在于它是否这样执行。命令式规则可以缩小这个差距,身份提示词不行。

完整的 12 条规则版 CLAUDE.md

以下是可直接复制粘贴使用的完整版本。

暂时无法在飞书文档外展示此内容

将它保存为仓库根目录下的 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 不是愿望清单,而是一份行为契约,用来封堵你已经观察到的具体失败模式。

每一条规则都应该回答一个问题:它能防止什么错误?

Karpathy 的 4 条规则,防的是他在 2026 年 1 月看到的失败模式:静默假设、过度工程化、无关破坏、成功标准薄弱。它们是基础,不要跳过。

我新增的 8 条规则,防的是 2026 年 5 月之后出现的新失败模式:没有预算约束的 Agent 循环、没有检查点的多步骤任务、看似测试了但其实没测到关键逻辑的测试,以及把静默失败包装成静默成功的问题。它们是增量补丁。

当然,具体效果因人而异。如果你不跑多步骤 pipeline,规则 10 对你就没那么重要。如果你的代码库只有一种统一风格,而且已经由 lint 强制执行,规则 11 就是冗余的。读完这 12 条后,保留那些真正对应你实际犯过错误的规则,删掉其余部分。

一份针对真实失败模式定制的 6 条规则版 CLAUDE.md,胜过一份有 12 条规则、其中 6 条你永远用不上的版本。

结语

Karpathy 在 2026 年 1 月的那条推文,本质上是一场抱怨。Forrest Chang 把它变成了 4 条规则。最终,12 万开发者给这个结果点了 Star。而其中大多数人,今天仍然只在使用那 4 条规则。

模型已经进步,生态也已经变了。多步骤 Agent、hook 链式触发、skill 加载、多代码库协作——这些在 Karpathy 写下那条推文时都还不存在。原来的 4 条规则并没有解决这些问题。它们不是错了,而是不完整了。

新增 8 条规则。6 周时间,覆盖 30 个代码库的测试。错误率从 41% 降到 3%。

今晚就收藏这篇文章,把这 12 条规则粘贴进你的 CLAUDE.md。如果它帮你少走一周 Claude 弯路,欢迎转发。

[原文链接]

点击了解律动BlockBeats 在招岗位

欢迎加入律动 BlockBeats 官方社群:

Telegram 订阅群:https://t.me/theblockbeats

Telegram 交流群:https://t.me/BlockBeats_App

Twitter 官方账号:https://twitter.com/BlockBeatsAsia

4-9.93%
MORE314.62%
HOOK-1.77%
此页面可能包含第三方内容,仅供参考(非陈述/保证),不应被视为 Gate 认可其观点表述,也不得被视为财务或专业建议。详见声明
  • 赞赏
  • 评论
  • 转发
  • 分享
评论
请输入评论内容
请输入评论内容
暂无评论