基于 Karpathy 理念的 Claude Code 指南

一个 CLAUDE.md 文件,用于改善 Claude Code 的行为,灵感源自 Andrej Karpathy 关于 LLM 编码陷阱的观察

问题所在

引用 Andrej 的原文:

“模型会替你做错误的假设,并且不加验证地执行下去。它们不会管理自己的困惑,不会主动寻求澄清,不会指出不一致之处,不会呈现权衡方案,也不会在应该拒绝的时候提出异议。”

“它们非常喜欢把代码和 API 复杂化,堆砌抽象,不清理死代码……原本 100 行就能解决的问题,它们会搞出 1000 行的臃肿构造。”

“它们有时仍然会作为副作用,修改或删除自己不够理解的注释和代码——即使这些改动与当前任务正交。”

解决方案

用一个文件包含四条原则,直接针对上述问题:

原则 解决的问题
编码前三思 错误假设、隐藏的困惑、缺失的权衡
简单至上 过度复杂、臃肿的抽象
精准手术式修改 正交改动、改动不该动的代码
目标驱动执行 通过测试先行、可验证的成功标准来发挥模型能力

四条原则详解

1. 编码前三思

不要假设。不要隐藏困惑。要呈现权衡。

LLM 经常默默地选择一种理解方式,然后直接执行。这条原则迫使模型进行显式推理:

  • 明确陈述假设 —— 如果不确定,主动询问,不要猜测
  • 呈现多种理解方式 —— 存在歧义时,不要默默选一种
  • 必要时提出异议 —— 如果有更简单的做法,直接说出来
  • 困惑时停下来 —— 指出哪些地方不清楚,并要求澄清

2. 简单至上

以最少的代码解决问题。不写投机性的代码。

对抗过度工程的倾向:

  • 不添加超出需求范围的功能
  • 不为只用一次的代码创建抽象
  • 不添加未被要求的“灵活性”或“可配置性”
  • 不处理不可能发生的异常场景
  • 如果 200 行代码可以用 50 行实现,就重写它

检验标准: 资深工程师会不会说这段代码过度复杂?如果会,就简化它。

3. 精准手术式修改

只动必须动的地方。只清理自己造成的垃圾。

在修改现有代码时:

  • 不要“顺手改进”旁边的代码、注释或格式
  • 不要重构没有坏的东西
  • 匹配现有的代码风格,即使你自己会写成另一种样子
  • 如果发现了不相关的死代码,可以提一下——但不要删除它

当你的修改产生了无用代码:

  • 删除由于你的改动而不再使用的导入/变量/函数
  • 除非被要求,否则不要删除预先存在的死代码

检验标准: 每一行被修改的代码,都应该能直接追溯到用户的需求。

4. 目标驱动执行

定义成功标准。循环执行,直到验证通过。

将命令式任务转化为可验证的目标:

不要这样说 而要转化为
“添加校验” “编写针对无效输入的测试,然后让它们通过”
“修复这个 bug” “编写能复现该 bug 的测试,然后让它通过”
“重构 X” “确保重构前后测试都能通过”

对于多步骤任务,简要说明计划:

1. [步骤] → 验证:[检查项]
2. [步骤] → 验证:[检查项]
3. [步骤] → 验证:[检查项]

强力的成功标准能让 LLM 自主循环执行。弱标准(比如“把它做好”)则需要不断的澄清。

安装

方式 A:Claude Code 插件(推荐)

在 Claude Code 内部,先添加 marketplace:

/plugin marketplace add forrestchang/andrej-karpathy-skills

然后安装插件:

/plugin install andrej-karpathy-skills@karpathy-skills

这将把该指南作为 Claude Code 插件安装,使该 skill 在你的所有项目中可用。

方式 B:CLAUDE.md(每个项目单独配置)

新项目:

curl -o CLAUDE.md https://raw.githubusercontent.com/forrestchang/andrej-karpathy-skills/main/CLAUDE.md

已有项目(追加内容):

echo "" >> CLAUDE.md
curl https://raw.githubusercontent.com/forrestchang/andrej-karpathy-skills/main/CLAUDE.md >> CLAUDE.md

核心见解

引用 Andrej:

“LLM 非常擅长循环执行,直到达成特定目标……不要告诉它做什么,给它成功标准,然后看它自己完成。”

“目标驱动执行”原则正是体现了这一点:将命令式指令转化为声明式目标,并配以验证循环。

如何判断它在起作用

如果你看到以下现象,说明这些指南正在起作用:

  • diff 中不必要的变化更少 —— 只有被要求的变化出现
  • 因过度复杂导致的重写更少 —— 代码首次写出来就很简洁
  • 澄清性问题在实现之前提出 —— 而不是犯错之后
  • 干净、极简的 PR —— 没有顺便做的重构或“改进”

定制化

这些指南设计为可以与项目特定的指令合并使用。你可以把它们加到现有的 CLAUDE.md 中,或者新建一个。

对于项目特定的规则,可以添加类似下面的章节:

## 项目特定指南

- 使用 TypeScript 严格模式
- 所有 API 端点必须有测试
- 遵循 `src/utils/errors.ts` 中现有的错误处理模式

权衡说明

这些指南偏向于 谨慎优先,而非速度优先。对于琐碎的任务(简单的错别字修正、明显的一行改动),请自行判断——并非每次改动都需要完整执行全部原则。

目标是减少在非琐碎工作上代价高昂的错误,而不是拖慢简单任务的速度。

许可证

MIT

Clade-code 原文

CLAUDE.md

用于减少常见 LLM 编码错误的行为指南。可根据需要与项目特定的指令合并使用。

权衡说明: 这些指南偏向于谨慎优先,而非速度优先。对于琐碎的任务,请自行判断。

1. 编码前三思

不要假设。不要隐藏困惑。要呈现权衡。

在实现之前:

  • 明确陈述你的假设。如果不确定,请主动询问。
  • 如果存在多种理解方式,请列出来——不要默默地选择一种。
  • 如果有更简单的做法,直接说出来。必要时提出异议。
  • 如果某些事情不清楚,请停下来。指出哪里令人困惑。然后提问。

2. 简单至上

以最少的代码解决问题。不写投机性的代码。

  • 不添加超出需求范围的功能。
  • 不为只用一次的代码创建抽象。
  • 不添加未被要求的“灵活性”或“可配置性”。
  • 不处理不可能发生的异常场景。
  • 如果你写了 200 行代码但可以用 50 行实现,请重写它。

问自己:“资深工程师会不会说这段代码过度复杂?” 如果会,就简化它。

3. 精准手术式修改

只动必须动的地方。只清理自己造成的垃圾。

在修改现有代码时:

  • 不要“顺手改进”旁边的代码、注释或格式。
  • 不要重构没有坏的东西。
  • 匹配现有的代码风格,即使你自己会写成另一种样子。
  • 如果发现了不相关的死代码,可以提一下——但不要删除它。

当你的修改产生了无用代码:

  • 删除由于你的改动而不再使用的导入/变量/函数。
  • 除非被要求,否则不要删除预先存在的死代码。

检验标准:每一行被修改的代码,都应该能直接追溯到用户的需求。

4. 目标驱动执行

定义成功标准。循环执行,直到验证通过。

将任务转化为可验证的目标:

  • “添加校验” → “编写针对无效输入的测试,然后让它们通过”
  • “修复这个 bug” → “编写能复现该 bug 的测试,然后让它通过”
  • “重构 X” → “确保重构前后测试都能通过”

对于多步骤任务,简要说明计划:

1. [步骤] → 验证:[检查项]
2. [步骤] → 验证:[检查项]
3. [步骤] → 验证:[检查项]

强力的成功标准能让你自主循环执行。弱标准(比如“把它做好”)则需要不断的澄清。


这些指南正在起作用的表现: diff 中不必要的变化更少,因过度复杂导致的重写更少,澄清性问题在实现之前提出——而不是犯错之后。

参考资料