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

2026/05/15 23:16
🌐zh-Hans

从41%到3%,Karpathy的4条规则还不够

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 弯路,欢迎转发。

[原文链接]

QQlink

Không có cửa hậu mã hóa, không thỏa hiệp. Một nền tảng xã hội và tài chính phi tập trung dựa trên công nghệ blockchain, trả lại quyền riêng tư và tự do cho người dùng.

© 2024 Đội ngũ R&D QQlink. Đã đăng ký Bản quyền.