60K+ Stars,一条 CLAUDE.md 文件解决 LLM 编码最头疼的三大问题。

📋 目录

  1. 问题背景
  2. Karpathy Guidelines 是什么?
  3. 四大铁律详解
  4. 安装配置
  5. 实战案例
  6. 最佳实践
  7. 总结

问题背景

Andrej Karpathy 在 Twitter 上发过一条引发广泛讨论的帖子,总结了 LLM 编码助手最常见的三大问题:

问题 1:错误假设与隐藏困惑

“Models make wrong assumptions on your behalf and just run along with them without checking. They don’t manage their confusion, don’t seek clarifications, don’t surface inconsistencies, don’t present tradeoffs, don’t push back when they should.”

AI 常常在不确定的情况下自己瞎猜,然后一路跑下去,不会:

  • 管理自己的困惑
  • 寻求澄清
  • 提出不一致之处
  • 展示权衡方案
  • 在该反对的时候反对

问题 2:过度复杂化

“They really like to overcomplicate code and APIs, bloat abstractions, don’t clean up dead code… implement a bloated construction over 1000 lines when 100 would do.”

AI 天生喜欢过度设计

  • 代码和 API 越来越臃肿
  • 抽象越来越复杂
  • 不清理死代码
  • 100 行能解决的问题写出 1000 行

问题 3:随意修改无关代码

“They still sometimes change/remove comments and code they don’t sufficiently understand as side effects, even if orthogonal to the task.”

AI 有时会顺手改掉它不理解的东西:

  • 修改或删除注释
  • 改动与任务无关的代码
  • 作为”副作用”引入意外变更

Karpathy Guidelines 是什么?

Karpathy Guidelines 是基于 Andrej Karpathy 观察提炼出的四条铁律,直接解决上述三大问题。

铁律 解决的问题
Think Before Coding 错误假设、隐藏困惑、缺失权衡
Simplicity First 过度复杂化、臃肿抽象
Surgical Changes 无关修改、边界不清
Goal-Driven Execution 缺乏验证、循环效率低

核心思想:不是让 AI 更聪明,而是给 AI 明确的行为约束


四大铁律详解

1. Think Before Coding

核心:不要假设。不要隐藏困惑。展示权衡。

LLM 的天性是选一个解释然后一路跑下去。这条铁律强制它显式思考:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
❌ 错误做法(隐藏假设):
AI: 我来帮你添加用户认证...
[直接开始写代码]

✅ 正确做法(显式思考):
AI: 你提到"添加用户认证",我需要澄清:
1. 认证方式:JWT 还是 Session?
2. 是否需要社交登录?
3. 密码重置用邮件还是短信?

推荐方案:
- JWT:适合分布式部署
- Session:适合单体应用,实现简单

你的系统目前是单体,我推荐 Session。同意吗?

执行要点:

  • 明确假设 - 不确定就问,不要猜
  • 多方案展示 - 别偷偷选一个,展示 2-3 种方案
  • 主动反对 - 有更简单的方案就说出来
  • 停下来澄清 - 不清楚就问,不要假装明白

2. Simplicity First

核心:最小代码解决问题。不做投机性设计。

对抗 AI 的”过度设计冲动”:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
❌ 错误做法(过度设计):
AI: 我添加了一个配置系统:
- 支持环境变量
- 支持 JSON 文件
- 支持远程配置中心
- 支持热更新
- 支持 schema 验证
[总共 800 行代码]

用户: 我只是想改个数据库连接字符串...

✅ 正确做法(最小代码):
AI: 我添加了环境变量配置:
DATABASE_URL = os.environ.get('DATABASE_URL', 'default')
[1 行代码]

如果以后需要更多配置,到时候再加。

执行要点:

  • 没有要求的功能不加
  • 单次使用的代码不抽象
  • 没有要求的”灵活性”不加
  • 不可能发生的情况不处理
  • 200 行能写成 50 行,就重写

检验标准:资深工程师看了会说”这也太复杂了”吗?如果会,就简化。

3. Surgical Changes

核心:只改必须改的。只清理自己产生的垃圾。

防止 AI “顺手优化”周边代码:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
❌ 错误做法(顺手优化):
任务: 添加日志记录
AI 改了:
- 添加了日志 ✅
- "顺便"重构了错误处理 ❌
- "顺便"改了变量命名 ❌
- "顺便"删除了"看起来无用"的注释 ❌
- "顺便"格式化了整个文件 ❌

✅ 正确做法(手术式修改):
任务: 添加日志记录
AI 只改了:
- 添加了日志 ✅

注意:看到 `old_function()` 可能无用,但不删除,因为不在任务范围内。

执行要点:

  • 不”优化”邻近代码、注释、格式
  • 不重构没坏的东西
  • 匹配现有风格,即使你觉得更好的
  • 注意到无关死代码 → 提示用户,不直接删

检验标准:每行改动都能追溯到用户的请求。

4. Goal-Driven Execution

核心:定义成功标准。循环直到验证。

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

命令式(弱) 目标式(强)
“添加验证” “写失败输入的测试,然后让它们通过”
“修复 bug” “写复现测试,然后让它通过”
“重构 X” “确保重构前后测试都通过”

多步骤任务的规划模板:

1
2
3
1. [步骤] → verify: [检查点]
2. [步骤] → verify: [检查点]
3. [步骤] → verify: [检查点]

执行要点:

  • 成功标准强 → AI 可以独立循环
  • 成功标准弱(”让它工作”)→ 需要频繁澄清

Karpathy 原话:

“LLMs are exceptionally good at looping until they meet specific goals… Don’t tell it what to do, give it success criteria and watch it go.”


安装配置

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

1
2
3
4
5
# 1. 添加市场
/plugin marketplace add multica-ai/andrej-karpathy-skills

# 2. 安装插件
/plugin install andrej-karpathy-skills@karpathy-skills

方式二:CLAUDE.md 文件(项目级)

新项目:

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

现有项目(追加):

1
2
echo "" >> CLAUDE.md
curl https://raw.githubusercontent.com/multica-ai/andrej-karpathy-skills/main/CLAUDE.md >> CLAUDE.md

方式三:Cursor

Cursor 版本在 .cursor/rules/karpathy-guidelines.mdc

1
2
# 复制到你的项目
cp .cursor/rules/karpathy-guidelines.mdc your-project/.cursor/rules/

详见 CURSOR.md


实战案例

案例 1:Think Before Coding

场景:添加缓存功能

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
你: 帮我给 API 加个缓存

AI(遵循铁律):
我理解你想添加缓存。让我先澄清:

1. 缓存策略:
- 内存缓存(适合单机,简单)
- Redis(适合分布式,需要额外部署)

2. 缓存粒度:
- 整个响应?
- 还是部分数据?

3. 缓存失效:
- TTL 自动过期?
- 还是手动触发?

你的 API 目前是单机服务,我推荐内存缓存 + TTL。
同意这个方向吗?

没有铁律的情况:

1
2
3
4
5
你: 帮我给 API 加个缓存

AI(跳过思考):
[直接开始写 Redis 集成代码]
[你发现:你根本不需要 Redis,浪费了半天]

案例 2:Simplicity First

场景:实现错误处理

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
❌ 过度复杂(无铁律):
AI: 我创建了一个完整的错误处理系统:
- 自定义 Error 类(BaseError, ValidationError, AuthError...)
- 全局错误中间件
- 错误日志服务
- 错误上报到 Sentry
- 错误重试机制
[500 行代码]

用户: 我只是想让 API 返回正确的错误格式...

✅ 简洁设计(有铁律):
AI: 我添加了简单的错误格式化:
def format_error(e):
return {"error": str(e), "code": "UNKNOWN"}
[20 行代码]

以后如果需要更多错误类型,再加。

案例 3:Surgical Changes

场景:修改配置文件

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
❌ 顺手优化(无铁律):
任务: 添加新的环境变量
AI 改了:
- 添加了新变量 ✅
- "顺便"把所有变量名改成更"规范"的 ❌
- "顺便"加了类型注释 ❌
- "顺便"重组了文件结构 ❌

结果:整个项目的环境变量引用都坏了

✅ 手术式修改(有铁律):
任务: 添加新的环境变量
AI 只改了:
- 添加了新变量 ✅

保持原有变量名、格式、结构不变。

案例 4:Goal-Driven Execution

场景:修复登录 bug

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
❌ 命令式(弱目标):
你: 修复登录失败的 bug
AI: 我改了代码,应该能工作了
[没测试,假设已修复]

✅ 目标式(强目标):
你: 修复登录失败的 bug

AI(遵循铁律):
目标: 让 `test_login_with_expired_token` 通过

Step 1: 写复现测试 → verify: 测试失败 ✅
Step 2: 分析根因 → verify: 找到 token 过期检查遗漏
Step 3: 修复根因 → verify: 测试通过 ✅
Step 4: 验证其他测试 → verify: 无新增失败 ✅

完成:登录 bug 已修复,所有测试通过。

最佳实践

1. 检验是否生效

这些铁律生效时,你应该看到:

  • diff 更干净 - 只有请求的改动,没有”顺手优化”
  • 首次就简洁 - 不需要重写过度复杂的代码
  • 先问后写 - 澄清问题出现在实现之前,而不是出错之后
  • PR 更干净 - 没有 drive-by refactor 或”顺便改进”

2. 项目定制

铁律可以与项目特定规则合并:

1
2
3
4
5
6
7
## Karpathy Guidelines(来自插件)

## 项目特定规则

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

3. 权衡:谨慎 vs 速度

这些铁律偏向谨慎。对于真正简单的任务(修复 typo、显而易见的一行改动),可以灵活处理。

目标:减少非琐碎工作的错误,不是拖慢简单任务。

4. 常见信号

当 AI 有这些想法时,警惕:

信号 意味着
“顺便优化一下” 违反 Surgical Changes
“加个抽象层会更灵活” 违反 Simplicity First
“我猜你是想…” 违反 Think Before Coding
“应该能工作了” 违反 Goal-Driven Execution

总结

Karpathy Guidelines 的核心价值:

铁律 核心价值
Think Before Coding 防止错误假设,强制澄清
Simplicity First 防止过度设计,保持最小
Surgical Changes 防止顺手修改,边界清晰
Goal-Driven Execution 强制验证,循环可靠

不是让 AI 更聪明,而是给 AI 明确的行为边界。

如果你在使用 AI 编码助手时遇到过:

  • AI 瞎猜需求,写出一堆你不需要的功能
  • AI 顺手改了不该改的东西,引入 bug
  • AI “修复”一个问题,又搞出两个新问题
  • AI 说”应该能工作”,结果根本没验证

Karpathy Guidelines 可能就是你需要的——不是更好的 AI,而是更有纪律的 AI。


延伸阅读