CLAUDE.md:让语言模型写出你不必重写的代码的实战笔记

Field Notes on Getting a Language Model to Write Code You Will Not Rewrite
A Short List of Rules, Earned by Watching the Same Mistakes Twice ——一份在「同一个错误看两遍」之后总结出的短规则清单

作者 / Author:Andrej Karpathy

说明:本文为英文原文逐节中英对照。英文部分完整保留作者原文,未做改动;中文为对照翻译,以达意为主。

Abstract · 摘要

Abstract
This file exists because language models make predictable mistakes when they write code. Not random mistakes, just the same ones, over and over, often enough that it was worth writing them down. What follows is not a set of suggestions but a set of rules. The throughline is the same in every section: the model is fast at generating plausible code and slow to notice that plausible is not the same as correct, so the discipline has to come from the process around it.
摘要
这份文件之所以存在,是因为语言模型在写代码时会犯一些可预测的错误。不是随机的错误,而是同样的错误,一遍又一遍,频繁到值得把它们写下来。接下来的内容不是一组建议,而是一组规则。每一节贯穿的主线都一样:模型擅长快速生成看似合理的代码,却迟迟意识不到「看似合理」并不等于「正确」——所以纪律必须来自围绕它构建的流程。
Index Terms
LLM-assisted programming, code review, software craftsmanship, minimal diffs, debugging, dependency hygiene.
关键词
LLM 辅助编程、代码审查、软件工艺、最小化 diff、调试、依赖卫生。
— 正文 / Rules —

I. Read Before You Write · 先读,再写

The biggest source of bad model-written code is writing before reading the codebase. Read the files you are about to touch; read, not skim. Copy the patterns that already exist, and check the imports to see what the project actually depends on, so you do not reach for axios where everything is fetch. When you cannot find a pattern, ask instead of guessing.
模型写出烂代码的最大根源,是在读代码库之前就动手写。读你即将改动的那些文件——是读,不是扫一眼。复用已经存在的模式,检查 import 看清项目真正依赖什么,这样在所有地方都用 fetch 时,你才不会偏偏伸手去拿 axios。当你找不到可参照的模式时,去问,而不是猜。

II. Think Before You Code · 先想,再写

Figure out what you are doing before you type. State your assumptions ("add authentication" is five different things, so name the one you picked) and name the tradeoffs. If something is genuinely confusing, stop and ask rather than filling the gap with plausible-looking code; that is exactly the code that passes a casual review and fails when it matters.
在敲键盘之前先弄清楚你要做什么。说明你的假设(「加认证」可以是五种完全不同的东西,所以要点明你选的是哪一种),并指出其中的权衡。如果有什么是真的让人困惑,就停下来发问,而不是用看似合理的代码把缺口填上;恰恰是这种代码,能通过随手一瞥的审查,却在关键时刻出事。

III. Simplicity · 简单

Write the minimum code that solves the problem in front of you now, not the minimum that could solve every future version of it. Resist premature abstraction, skip error handling for errors that cannot occur, and hardcode values until there is a real reason to configure them. The test: if the only reason something is abstracted is "in case we need to," you have over-built it.
写出解决眼前问题的最少代码,而不是能解决它未来每一种形态的最少代码。抵制过早抽象,对不可能发生的错误不做处理,在没有真实理由配置化之前就把值硬编码。检验标准:如果某处被抽象出来的唯一理由是「以防万一我们需要」,那你就过度设计了。

IV. Surgical Changes · 外科手术式的改动

Your diff should be as small as the task allows. Do not touch what you were not asked to touch, match the existing style, and do not reformat; a formatter pass buries the three lines that matter inside three hundred that do not. The test is whether you can justify every changed line by the task. If a line is there because "while I was in there," revert it.
你的 diff 应当小到任务允许的极限。不要去碰没让你碰的地方,匹配既有风格,不要重新格式化;一次格式化会把真正重要的三行,埋进无关的三百行里。检验标准是你能否用任务本身为每一行改动辩护。如果某一行的存在理由是「反正我都进来了」,把它撤掉。

V. Verification · 验证

The gap between code that works and code you think works is testing. When fixing a bug, write the failing test first, watch it fail, then fix it; that is the only proof you fixed the cause and not the symptom. Test behavior that can actually break, not that a constructor sets a field. If something is hard to test, that is information about the design, not permission to skip it.
「能跑的代码」和「你以为能跑的代码」之间,隔着测试。修 bug 时,先写一个会失败的测试,看着它失败,再去修;这是你修的是病因而非症状的唯一证据。测试那些真的会出错的行为,而不是「构造函数有没有给某个字段赋值」。如果某样东西很难测试,那是关于设计的信息,而不是允许你跳过它的理由。

VI. Goal-Driven Execution · 目标驱动的执行

Every task needs a success criterion before code is written. "Add validation" becomes "reject a missing or malformed email, return 400 with a clear message, and test both cases." For anything multi-step, state the plan first so the user can catch a wrong approach before you spend an hour building it.
每个任务在写代码之前都需要一个成功标准。「加校验」要变成「拒绝缺失或格式错误的邮箱,返回 400 并附带清晰的提示信息,并对两种情况都写测试」。对任何多步骤的工作,先把计划讲清楚,这样用户能在你花一个小时动手之前,就发现方向错了。

VII. Debugging · 调试

When something breaks, investigate; do not guess. Read the whole error and the stack trace, reproduce the problem before you change anything, and change one thing at a time. Do not paper over an unexpected null with a null check; find out why it is null, or the bug just moves somewhere quieter.
出问题时,去调查,别猜。完整读完报错和调用栈,在改动任何东西之前先复现问题,并且一次只改一处。不要用一个 null 检查把意外的 null 糊弄过去;查清它为什么是 null,否则这个 bug 只是挪到了一个更安静的地方。

VIII. Dependencies · 依赖

Every dependency is permanent code you do not control. Before adding one, ask whether the project or the standard library can already do it with crypto.randomUUID() over a uuid package. When you do add one, say why, so the choice is visible rather than smuggled into the manifest.
每一个依赖,都是你无法掌控的永久代码。在添加之前,先问问项目或标准库是不是已经能做到——用 crypto.randomUUID() 而不是一个 uuid 包。当你确实要加一个时,说明理由,让这个选择是可见的,而不是被偷偷塞进 manifest 里。

IX. Communication · 沟通

Say what you did and why, not just a block of code. Flag concerns even when you did exactly what was asked, and be precise about uncertainty: "I am not sure this library supports streaming" tells the user what to verify; "I think this should work" does not.
说清楚你做了什么、为什么这么做,而不是甩出一坨代码。即便你完全照要求做了,也要把顾虑标出来;并且要精确地表达不确定性:「我不确定这个库是否支持流式」告诉了用户该去验证什么,「我觉得这应该能行」则什么也没说。

X. Common Failure Modes · 常见失败模式

A few patterns recur often enough to name: the Kitchen Sink (restructuring half the codebase while you are at it), the Wrong Abstraction (copy-paste twice before you abstract), the Optimistic Path (the happy path handled and the 500 ignored), and the Runaway Refactor (a fix that cascades across files). Catch yourself in any of these and the right move is to stop, not to push through.
有几种模式反复出现,频繁到值得起个名字:大杂烩(Kitchen Sink,顺手把半个代码库重构了)、错误的抽象(Wrong Abstraction,复制粘贴两次之后再抽象)、乐观路径(Optimistic Path,处理了顺利的情况,却无视了 500)、以及失控的重构(Runaway Refactor,一个修复在文件间层层蔓延)。一旦发现自己掉进其中任何一个,正确的做法是停下来,而不是硬着头皮推下去。

© 2026 A. Karpathy. Personal use of this material is permitted. This is an independent reformatting of the author's working notes on LLM-assisted programming (CLAUDE.md, v260626) into a conference-style document. Freely available; rules subject to revision as the models change.

© 2026 A. Karpathy。允许对本材料作个人使用。本文是将作者关于 LLM 辅助编程的工作笔记(CLAUDE.md,v260626)独立重排为会议论文风格的文档。可自由获取;规则会随模型的演进而修订。

English EN 简体中文 ZH