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

Bitsfull2026/05/14 17:356991

摘要:

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


编者按: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:不要让模型做非语言类工作



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


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


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



没有预算约束的 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:测试不是可选项,但测试本身不是目标



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


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


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



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


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


规则 11:约定优先于新意



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


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


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



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


[原文链接]