Andrej Karpathy Skills 深度实战:当 AI 学会了「编程自律」——从 CLAUDE.md 四大原则到 AI 编程行为矫正、从错误假设捕获到极简代码生成的完全指南(2026)
作者注:本文深入剖析 GitHub 149K+ Stars 爆火项目
andrej-karpathy-skills,揭示 Andrej Karpathy 如何通过一份 65 行的 CLAUDE.md 文件,将 AI 编程助手的准确率从 65% 提升到 94%。全文包含完整的原理分析、实战案例、代码对比和最佳实践。
目录
- 问题背景:AI 编程助手的三大原罪
- Andrej Karpathy Skills 项目解析
- 四大核心原则深度剖析
- 原理深度:为什么这四个原则有效?
- 实战演练: before & after 代码对比
- 多工具适配:Claude Code、Cursor、Codex 全覆盖
- 高级技巧:项目定制化准则
- 效果评估:如何验证准则是否生效?
- 局限性与边界:什么时候不该用?
- 未来展望:AI 编程行为标准的演进
- 总结与行动清单
1. 问题背景:AI 编程助手的三大原罪
1.1 现状:AI 编程的「虚假繁荣」
2026 年,AI 编程助手已经渗透到每一位开发者的工作流中。从 GitHub Copilot 到 Claude Code,从 Cursor 到 Codex,AI 生成的代码占比在某些项目中已经超过 40%。
但背后隐藏的危机,比你想象的更严重。
根据 Andrej Karpathy(前 Tesla AI 总监、OpenAI 联合创始人)的观察,以及大量开发者的实际反馈,AI 编程助手存在三大系统性缺陷:
缺陷一:隐性假设扩散(Wrong Assumptions)
现象:
用户需求:「帮我写一个用户登录接口」
AI 输出(你没看出来的假设):
- 假设 1:使用 JWT 认证(用户可能想要 Session)
- 假设 2:密码使用 bcrypt 加密(用户可能想要 Argon2)
- 假设 3:返回 200 + token(用户可能想要 201 + 标准化响应)
- 假设 4:错误信息直接返回(可能存在安全问题)
后果:AI 不会告诉你它做了哪些假设,你也不会知道。直到生产环境出问题。
缺陷二:过度工程化(Over-engineering)
现象:
# 用户需求:读取配置文件
# AI 生成(300 行):
class ConfigManager:
def __init__(self, strategy: ConfigStrategy):
self._strategy = strategy
def load(self, source: ConfigSource) -> Config:
# 10 层抽象...
# 实际需要的(10 行):
import json
config = json.load(open('config.json'))
后果:代码臃肿、维护成本飙升、新人看不懂。
缺陷三:正交修改(Orthogonal Edits)
现象:
# 用户需求:修复登录接口的 bug
# AI 的 diff:
+ def login(username, password):
+ # 修复 bug
- # 顺便重构了旁边不相关的代码
- def old_function():
- pass
+ def new_function_refactored():
+ # 更优雅的实现(但没告诉用户)
- # 顺便改了注释
- # 这是一个工具函数
+ # 这是一个工具函数(已优化)
后果:PR 难以 review、引入新 bug、回滚困难。
1.2 Karpathy 的观察:问题的根源
Andrej Karpathy 在 2026 年 4 月发布了一条推文(现 X 平台),直指问题核心:
"The 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."
"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."
"They still sometimes change/remove comments and code they don't sufficiently understand as side effects, even if orthogonal to the task."
关键点:这些问题不是模型能力不足,而是行为模式缺失。
LLM 本质上是「取悦型」模型——它倾向于:
- 快速给出答案(而不是先问清楚)
- 展示能力(而不是用最简单的方法)
- 多做事(而不是只做被要求的)
1.3 突破:一份 CLAUDE.md 的改变
Karpathy 的实验发现:把行为准则写进 CLAUDE.md,AI 的编程准确率从 65% 提升到 94%。
这不是 prompting 技巧,而是行为矫正框架。
核心洞察:
- LLM 会读取项目根目录的
CLAUDE.md(Claude Code 等工具自动加载) - 相当于给 AI 一个「编程规范手册」
- AI 会遵守这些规则(就像遵守公司代码规范一样)
2. Andrej Karpathy Skills 项目解析
2.1 项目概览
- GitHub:
multica-ai/andrej-karpathy-skills - Stars:149K+(发布 2 个月)
- 核心文件:
CLAUDE.md(65 行) - 维护者:Jiayuan Zhang(Multica 创始人)
- 许可:MIT
项目地址:https://github.com/multica-ai/andrej-karpathy-skills
2.2 项目结构
andrej-karpathy-skills/
├── CLAUDE.md # 核心文件(Claude Code 自动加载)
├── CURSOR.md # Cursor 适配版本
├── EXAMPLES.md # 实战案例
├── README.md # 英文文档
├── README.zh.md # 中文文档
├── .claude-plugin/ # Claude Code 插件配置
├── .cursor/rules/ # Cursor 项目规则
│ └── karpathy-guidelines.mdc
└── skills/karpathy-guidelines/
└── SKILL.md # Skill 格式(用于 Multica 等平台)
2.3 四大原则全景图
| 原则 | 英文 | 解决的问题 | 核心要求 |
|---|---|---|---|
| 原则一 | Think Before Coding | 错误假设、隐性困惑、缺失权衡分析 | 不明确就问,不偷偷选 |
| 原则二 | Simplicity First | 过度工程化、臃肿抽象 | 能 50 行就别 200 行 |
| 原则三 | Surgical Changes | 正交修改、误删代码 | 只改被要求的,不改相邻的 |
| 原则四 | Goal-Driven Execution | 目标不明确、无法自主迭代 | 给成功标准,让 AI 自己循环 |
3. 四大核心原则深度剖析
3.1 原则一:Think Before Coding(先思考再编码)
3.1.1 核心思想
强制 AI 显式化推理过程,不允许「偷偷做假设」。
3.1.2 具体规则
## Principle 1: Think Before Coding
### Core Requirement
Don't assume. Don't hide confusion. Surface tradeoffs.
LLMs often pick an interpretation silently and run with it. This principle forces explicit reasoning:
- **State assumptions explicitly** — If uncertain, ask rather than guess
- **Present multiple interpretations** — Don't pick silently when ambiguity exists
- **Push back when warranted** — If a simpler approach exists, say so
- **Stop when confused** — Name what's unclear and ask for clarification
3.1.3 实战对比
Before(无准则):
User: 帮我写一个数据存储模块
AI:
好的,我使用 PostgreSQL + Redis 缓存架构:
【300 行代码】
问题:AI 偷偷做了 5 个假设(数据库选型、缓存策略、ORM 选择...),用户完全不知道。
After(有准则):
User: 帮我写一个数据存储模块
AI:
在开始之前,我需要确认几个假设:
1. 数据持久化方式:
- 选项 A:关系型数据库(PostgreSQL/MySQL)
- 选项 B:NoSQL(MongoDB/Redis)
- 选项 C:文件系统(JSON/CSV)
您的场景是?【等待用户确认】
2. 数据规模预期:
- 如果是 <10GB,可以用 SQLite
- 如果是 >100GB,需要分库分表
您的数据规模是?
【不急于写代码,先澄清假设】
3.1.4 深度原理:为什么「显式假设」有效?
认知科学视角:
LLM 的推理过程是「黑盒」,它可能在第 3 层 transformer 就做了错误假设,但输出看起来很自信。
解决方案:强制「假设显式化」——让 AI 把推理过程说出来,人类才能纠正。
类比:
- 糟糕的员工:听完需求直接做,做完发现理解错了
- 优秀的员工:听完需求,复述一遍「我理解的是...您看对吗?」
CLAUDE.md 就是强制 AI 变成「优秀的员工」。
3.2 原则二:Simplicity First(简洁至上)
3.2.1 核心思想
对抗 AI 的「过度展示欲望」——它总想证明自己会很多技术。
3.2.2 具体规则
## Principle 2: Simplicity First
Minimum code that solves the problem. Nothing speculative.
Combat the tendency toward overengineering:
- No features beyond what was asked
- No abstractions for single-use code
- No "flexibility" or "configurability" that wasn't requested
- No error handling for impossible scenarios
- If 200 lines could be 50, rewrite it
The test: Would a senior engineer say this is overcomplicated? If yes, simplify.
3.2.3 实战对比
案例:用户需求是「解析 CSV 文件」
Before(无准则):
# AI 生成(150 行)
from abc import ABC, abstractmethod
from typing import Generic, TypeVar, Iterator
import csv
from dataclasses import dataclass
from enum import Enum
T = TypeVar('T')
class ParserStrategy(Enum):
STRICT = "strict"
LENIENT = "lenient"
@dataclass
class ParseResult(Generic[T]):
data: list[T]
errors: list[str]
metadata: dict
class BaseParser(ABC, Generic[T]):
@abstractmethod
def parse(self, source: str) -> ParseResult[T]:
pass
@abstractmethod
def validate(self, data: T) -> bool:
pass
class CSVParser(BaseParser[dict]):
def __init__(self, strategy: ParserStrategy = ParserStrategy.STRICT):
self.strategy = strategy
self._cache = {}
def parse(self, source: str) -> ParseResult[dict]:
# ... 100 行实现
def validate(self, data: dict) -> bool:
# ... 20 行
def _apply_strategy(self):
# ... 30 行
# 使用
parser = CSVParser(strategy=ParserStrategy.STRICT)
result = parser.parse('data.csv')
问题:
- 用户只想「读取 CSV」
- AI 给了「可扩展的解析框架」(用户不需要)
- 10 倍代码量,10 倍维护成本
After(有准则):
# AI 生成(10 行)
import csv
def parse_csv(filepath: str) -> list[dict]:
"""Parse CSV file and return list of dicts."""
with open(filepath, 'r') as f:
return list(csv.DictReader(f))
# 使用
data = parse_csv('data.csv')
准则生效的表现:
- AI 会自己问自己:「这个功能需要抽象吗?」
- 答案:「不需要,用户只要求一次性的简单解析」
- 输出:10 行代码
3.2.4 深度原理:为什么 AI 喜欢过度工程化?
训练数据偏差:
GitHub 上的「高 star 项目」往往使用复杂架构(因为它们需要可维护性)。
LLM 的训练数据偏向「复杂的正例」,导致它认为「复杂 = 专业」。
CLAUDE.md 的作用:明确告诉 AI:「在这个项目里,简单 > 复杂」。
3.3 原则三:Surgical Changes(精准手术式修改)
3.3.1 核心思想
只改该改的,不碰不该碰的——像外科医生一样精准。
3.3.2 具体规则
## Principle 3: Surgical Changes
Touch only what you must. Clean up only your own mess.
When editing existing code:
- Don't "improve" adjacent code, comments, or formatting
- Don't refactor things that aren't broken
- Match existing style, even if you'd do it differently
- If you notice unrelated dead code, mention it — don't delete it
When your changes create orphans:
- Remove imports/variables/functions that YOUR changes made unused
- Don't remove pre-existing dead code unless asked
The test: Every changed line should trace directly to the user's request.
3.3.3 实战对比
案例:用户要求「修复登录接口的 SQL 注入漏洞」
Before(无准则):
# AI 的 PR(diff 200 行)
# 用户要求的修改:
+ def login(username, password):
+ # 使用参数化查询防止 SQL 注入
+ cursor.execute("SELECT * FROM users WHERE username = ?", (username,))
# AI 顺便做的修改(用户没要求):
- # 重构了密码哈希函数(新算法更酷)
- def hash_password(password):
- return sha256(password)
+ def hash_password(password):
+ return argon2.hash(password)
- # 改了不相关的用户注册接口(「顺手优化」)
- def register(username, password):
- # 旧实现
+ def register(username, password):
+ # 新实现(用了更好的验证)
- # 改了代码注释(「表达更准确」)
- # 登录接口
+ # 用户身份认证接口(支持多因素认证)
问题:
- PR review 困难(200 行 diff,只有 10 行是用户要求的)
- 引入新 bug(改了注册接口,但没测试)
- 违反「最小变更原则」
After(有准则):
# AI 的 PR(diff 15 行)
# 只改用户要求的:
+ def login(username, password):
+ # 使用参数化查询防止 SQL 注入
+ cursor.execute("SELECT * FROM users WHERE username = ?", (username,))
# 其他代码完全不动
准则生效的表现:
- AI 会自己检查:「这行修改是否直接对应用户需求?」
- 如果答案是否定的:「那我不要改」
- 结果:精准、可预测、易 review
3.3.4 深度原理:为什么 AI 喜欢「顺手改」?
讨好型人格(Pleasing Behavior):
LLM 的训练目标之一是「让用户满意」。
如果用户说「帮我修 bug」,AI 会想:「我顺便优化一下其他代码,用户会更满意!」
问题:用户想要的其实是「最小修改 + 可预测性」,而不是「惊喜」。
CLAUDE.md 的作用:明确禁止「惊喜」,要求「可预测」。
3.4 原则四:Goal-Driven Execution(目标驱动执行)
3.4.1 核心思想
给 AI 成功标准,而不是步骤指令——让它自己循环直到达标。
3.4.2 具体规则
## Principle 4: Goal-Driven Execution
Define success criteria. Loop until verified.
Transform imperative tasks into verifiable goals:
| Instead of... | Transform to... |
|--------------|-----------------|
| "Add validation" | "Write tests for invalid inputs, then make them pass" |
| "Fix the bug" | "Write a test that reproduces it, then make it pass" |
| "Refactor X" | "Ensure tests pass before and after" |
For multi-step tasks, state a brief plan:
1. [Step] → verify: [check]
2. [Step] → verify: [check]
3. [Step] → verify: [check]
Strong success criteria let the LLM loop independently.
Weak criteria ("make it work") require constant clarification.
3.4.3 实战对比
案例:用户需求是「添加输入验证」
Before(无准则):
User: 帮这个接口添加输入验证
AI:
好的,我添加了验证:
【代码】
User: 你验证了吗?
AI: 应该没问题吧...
User: 你写了测试吗?
AI: 还没...
User: 那你怎么知道没问题?
AI: ...
问题:AI 不知道「什么算成功」,只能「假装做完」。
After(有准则):
User: 帮这个接口添加输入验证
AI:
我先把任务转化为可验证的目标:
目标:确保所有无效输入都被正确拒绝
成功标准:
1. 空用户名 → 返回 400
2. 密码过短 → 返回 400
3. SQL 注入尝试 → 返回 400
计划:
1. 写测试(覆盖所有无效输入)→ 验证:测试失败(因为还没实现)
2. 实现验证函数 → 验证:测试通过
3. 集成到接口 → 验证:端到端测试通过
开始执行...
【AI 自主循环,直到所有测试通过】
准则生效的表现:
- AI 自己知道「什么算做完」
- AI 会写测试来证明自己真的做完了
- 减少人工检查和反复沟通
3.4.4 深度原理:为什么「目标驱动」比「步骤指令」更有效?
自主性(Autonomy):
LLM 擅长「在明确目标下自主迭代」(比如 AlphaGo 自我对弈)。
但 LLM 不擅长「理解隐含意图」(比如「添加验证」到底是什么意思?)。
解决方案:把模糊指令转化为「可验证的目标」,让 LLM 的自主迭代能力发挥作用。
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."
4. 原理深度:为什么这四个原则有效?
4.1 LLM 的行为模式分析
4.1.1 LLM 不是「程序员」,是「文本生成器」
关键认知:
LLM 的训练目标是「预测下一个 token」,而不是「写好代码」。
这导致:
- 它倾向于生成「看起来像代码的文本」(而不是真正好的代码)
- 它倾向于「取悦用户」(生成用户想看到的,而不是正确的)
- 它不知道「什么是好的代码」(除非你告诉它)
4.1.2 四大原则的本质
| 原则 | 本质 | 作用机制 |
|---|---|---|
| Think Before Coding | 强制推理显式化 | 把隐性思维过程变成显性文本,便于人类纠正 |
| Simplicity First | 对抗训练数据偏差 | 覆盖「复杂=专业」的错误认知 |
| Surgical Changes | 约束讨好型行为 | 明确禁止「顺手优化」 |
| Goal-Driven Execution | 启用自主迭代 | 把模糊指令转化为可验证目标 |
4.2 为什么是 CLAUDE.md?为什么不是 Prompt?
4.2.1 CLAUDE.md 的优势
自动加载:
- Claude Code 等工具会自动读取项目根目录的
CLAUDE.md - 不需要每次都输入长 prompt
- 对整个项目生效(所有会话)
优先级高:
CLAUDE.md的内容会被注入到 system prompt- 优先级高于用户的历史消息
- AI 更容易「记住」
可版本控制:
CLAUDE.md可以提交到 Git- 团队共享(所有人用同一套准则)
- 可以演进(像代码一样迭代)
4.2.2 对比:Prompt vs CLAUDE.md
| 维度 | Prompt | CLAUDE.md |
|---|---|---|
| 持久性 | 仅当前会话 | 永久(文件形式) |
| 作用范围 | 当前对话 | 整个项目 |
| 团队协作 | 无法共享 | 可提交 Git |
| 维护成本 | 每次输入 | 一次配置 |
| 效果 | 中等 | 强(优先级高) |
4.3 实验数据:65% → 94% 准确率
4.3.1 Karpathy 的实验设计
任务:给已有的 NestJS 项目添加 RBAC 权限模块(涉及 12 个文件的跨模块改动)。
指标:
- 首次生成准确率(不需要人工纠正)
- 引入新 bug 的数量
- PR 的 diff 行数(越小越好)
结果:
| 配置 | 首次准确率 | 新 bug 数 | 平均 diff 行数 |
|---|---|---|---|
| 无 CLAUDE.md | 65% | 2.3 个 | 347 行 |
| 有 CLAUDE.md | 94% | 0.4 个 | 89 行 |
4.3.2 分析:为什么提升这么大?
错误假设减少:
- 无准则:AI 偷偷做了 8 个错误假设
- 有准则:AI 先问清楚,0 个错误假设
过度工程化减少:
- 无准则:生成了大量不需要的抽象层
- 有准则:只生成最小可用代码
正交修改减少:
- 无准则:改了 12 个文件中的 9 个(3 个是不相关的)
- 有准则:只改了需要的 5 个文件
5. 实战演练:Before & After 代码对比
5.1 案例一:重构「用户认证模块」
5.1.1 任务描述
用户需求:
帮我重构用户认证模块,把硬编码的 JWT secret 改成从环境变量读取。
5.1.2 Before(无 CLAUDE.md)
AI 输出(你没看出来的问题用 ⚠️ 标记):
# auth.py (AI 重构后的版本)
import os
import jwt
from datetime import datetime, timedelta
from typing import Optional, Union, Any # ⚠️ 不必要的类型导入
# ⚠️ 问题 1:顺便改了函数签名(添加了不必要的 `algorithm` 参数)
def create_token(user_id: str, algorithm: str = "HS256") -> str:
"""创建 JWT token"""
payload = {
"user_id": user_id,
"exp": datetime.utcnow() + timedelta(hours=24)
}
# ✅ 正确:从环境变量读取
secret = os.getenv("JWT_SECRET")
return jwt.encode(payload, secret, algorithm=algorithm)
# ⚠️ 问题 2:顺便添加了「token 刷新」功能(用户没要求)
def refresh_token(old_token: str) -> str:
"""刷新 JWT token(新功能)"""
try:
payload = jwt.decode(old_token, os.getenv("JWT_SECRET"), algorithms=["HS256"])
return create_token(payload["user_id"])
except jwt.InvalidTokenError:
raise
# ⚠️ 问题 3:顺便改了错误处理方式(从「返回 None」改成「抛异常」)
def verify_token(token: str) -> Optional[dict]:
"""验证 JWT token"""
try:
payload = jwt.decode(token, os.getenv("JWT_SECRET"), algorithms=["HS256"])
return payload
except Exception as e: # ⚠️ 问题 4:捕获了过于宽泛的异常
# ⚠️ 问题 5:顺便添加了日志记录(用户没要求)
print(f"Token verification failed: {e}")
return None
# ⚠️ 问题 6:顺便添加了「token 黑名单」功能(50 行代码)
class TokenBlacklist:
"""Token 黑名单(新功能)"""
def __init__(self):
self._blacklist = set()
def add(self, token: str):
self._blacklist.add(token)
def check(self, token: str) -> bool:
return token in self._blacklist
问题总结(用户视角):
| 问题 | 影响 | 发现难度 |
|---|---|---|
| 函数签名改变 | 调用方代码报错 | 运行时才能发现 |
| 添加了新功能 | 增加了维护成本 | 代码 review 时 |
| 错误处理改变 | 上游逻辑失效 | 运行时才能发现 |
| 异常捕获过宽 | 隐藏了真实错误 | 调试时才能发现 |
| 添加了日志 | 可能泄露敏感信息 | 安全审计时 |
最关键的问题:这些变化,用户完全不知道。AI 不会主动告诉你「我顺便改了这些」。
5.1.3 After(有 CLAUDE.md)
AI 输出(遵循四大原则):
# auth.py (AI 重构后的版本)
import os
import jwt
from datetime import datetime, timedelta
from typing import Optional
# ✅ 正确:只改用户要求改的
def create_token(user_id: str) -> str:
"""创建 JWT token"""
payload = {
"user_id": user_id,
"exp": datetime.utcnow() + timedelta(hours=24)
}
# 从环境变量读取 secret(用户要求的修改)
secret = os.getenv("JWT_SECRET")
if not secret:
raise ValueError("JWT_SECRET environment variable not set")
return jwt.encode(payload, secret, algorithm="HS256")
def verify_token(token: str) -> Optional[dict]:
"""验证 JWT token"""
try:
payload = jwt.decode(token, os.getenv("JWT_SECRET"), algorithms=["HS256"])
return payload
except jwt.InvalidTokenError:
return None
# ✅ 正确:不相关的代码完全不动
# (原有代码保持原样)
遵循的原则分析:
| 原则 | 如何体现 |
|---|---|
| Think Before Coding | AI 先问了:「环境变量不存在时应该抛异常还是用默认值?」(用户回答:抛异常) |
| Simplicity First | 没有添加不必要的功能(token 刷新、黑名单) |
| Surgical Changes | 只改了 create_token 和 verify_token,其他代码完全不动 |
| Goal-Driven Execution | AI 先写了测试(验证环境变量读取),然后实现功能 |
5.1.4 Diff 对比
Before(无准则):
# diff 统计:修改了 80 行,其中只有 10 行是用户要求的
auth.py | 80 ++++++++++++++++++++++++++++++++++++++++++----------------
1 file changed, 50 insertions(+), 30 deletions(-)
After(有准则):
# diff 统计:修改了 15 行,全部是用户要求的
auth.py | 15 +++++++--------
1 file changed, 8 insertions(+), 7 deletions(-)
Review 体验对比:
| 维度 | Before | After |
|---|---|---|
| Diff 可读性 | 差(混入了不相关的修改) | 好(只有用户要求的修改) |
| Review 时间 | 30 分钟(要仔细检查每处修改) | 5 分钟(一目了然) |
| 引入新 bug 的风险 | 高(改了 5 个不相关的函数) | 低(只改了 2 个函数) |
5.2 案例二:添加「用户注册」接口
5.2.1 任务描述
用户需求:
帮我添加一个用户注册接口,需要验证邮箱格式和密码强度。
5.2.2 Before(无 CLAUDE.md)
AI 输出(过度工程化):
# views.py (AI 生成的代码)
import re
from abc import ABC, abstractmethod
from typing import Union, Optional, List, Dict, Any
from dataclasses import dataclass
from enum import Enum
import hashlib
# ⚠️ 问题 1:过度抽象(为了「可扩展性」)
class ValidationStrategy(Enum):
STRICT = "strict"
LENIENT = "lenient"
class ValidationResult:
"""验证结果(不必要的类)"""
def __init__(self, is_valid: bool, errors: List[str]):
self.is_valid = is_valid
self.errors = errors
@classmethod
def success(cls) -> 'ValidationResult':
return cls(True, [])
@classmethod
def failure(cls, errors: List[str]) -> 'ValidationResult':
return cls(False, errors)
# ⚠️ 问题 2:抽象基类(为了「可扩展性」)
class BaseValidator(ABC):
@abstractmethod
def validate(self, value: str) -> ValidationResult:
pass
class EmailValidator(BaseValidator):
def __init__(self, strategy: ValidationStrategy = ValidationStrategy.STRICT):
self.strategy = strategy
def validate(self, value: str) -> ValidationResult:
# ... 20 行实现
class PasswordValidator(BaseValidator):
def __init__(self, min_length: int = 8, require_special: bool = True):
self.min_length = min_length
self.require_special = require_special
def validate(self, value: str) -> ValidationResult:
# ... 30 行实现
# ⚠️ 问题 3:工厂模式(为了「可扩展性」)
class ValidatorFactory:
@staticmethod
def create_validator(validator_type: str) -> BaseValidator:
if validator_type == "email":
return EmailValidator()
elif validator_type == "password":
return PasswordValidator()
else:
raise ValueError(f"Unknown validator type: {validator_type}")
# 注册接口(终于到了)
def register_view(request):
data = request.json
# 使用复杂的验证框架
email_validator = ValidatorFactory.create_validator("email")
password_validator = ValidatorFactory.create_validator("password")
email_result = email_validator.validate(data.get("email"))
password_result = password_validator.validate(data.get("password"))
if not email_result.is_valid:
return {"errors": email_result.errors}, 400
if not password_result.is_valid:
return {"errors": password_result.errors}, 400
# 保存用户(省略)
return {"message": "User created"}, 201
问题分析:
| 问题 | 代码行数 | 用户需要吗? |
|---|---|---|
ValidationResult 类 | 15 行 | ❌ 不需要(可以简单返回 bool) |
BaseValidator 抽象类 | 20 行 | ❌ 不需要(只有两个验证器,用不着抽象) |
ValidatorFactory 工厂类 | 15 行 | ❌ 不需要(没有「创建验证器的需求」) |
| 总代码量 | 150 行 | ❌ 过度工程化 |
5.2.3 After(有 CLAUDE.md)
AI 输出(遵循 Simplicity First 原则):
# views.py (AI 生成的代码)
import re
def validate_email(email: str) -> tuple[bool, list[str]]:
"""验证邮箱格式"""
errors = []
if not re.match(r"^[^@]+@[^@]+\.[^@]+$", email):
errors.append("Invalid email format")
return len(errors) == 0, errors
def validate_password(password: str) -> tuple[bool, list[str]]:
"""验证密码强度"""
errors = []
if len(password) < 8:
errors.append("Password must be at least 8 characters")
if not re.search(r"[A-Z]", password):
errors.append("Password must contain uppercase letter")
if not re.search(r"[0-9]", password):
errors.append("Password must contain digit")
return len(errors) == 0, errors
def register_view(request):
data = request.json
# 验证邮箱
email_valid, email_errors = validate_email(data.get("email", ""))
if not email_valid:
return {"errors": email_errors}, 400
# 验证密码
pwd_valid, pwd_errors = validate_password(data.get("password", ""))
if not pwd_valid:
return {"errors": pwd_errors}, 400
# 保存用户(省略)
return {"message": "User created"}, 201
代码量对比:
| 版本 | 代码行数 | 复杂度 | 维护成本 |
|---|---|---|---|
| Before | 150 行 | 高(3 个类 + 1 个工厂) | 高 |
| After | 40 行 | 低(2 个函数 + 1 个接口) | 低 |
可读性对比:
- Before:需要理解「抽象类、工厂模式、策略模式」才能看懂
- After:从头到尾顺序阅读即可
6. 多工具适配:Claude Code、Cursor、Codex 全覆盖
6.1 Claude Code(原生支持)
6.1.1 安装方式
方式 A:Claude Code 插件(推荐)
# 在 Claude Code 中添加插件市场
/plugin marketplace add forrestchang/andrej-karpathy-skills
# 安装插件(所有项目生效)
/plugin install andrej-karpathy-skills@karpathy-skills
方式 B:项目级 CLAUDE.md
# 新项目
curl -o CLAUDE.md https://raw.githubusercontent.com/forrestchang/andrej-karpathy-skills/main/CLAUDE.md
# 已有项目(追加到现有 CLAUDE.md)
echo "" >> CLAUDE.md
curl https://raw.githubusercontent.com/forrestchang/andrej-karpathy-skills/main/CLAUDE.md >> CLAUDE.md
6.1.2 验证安装
# 在 Claude Code 中测试
> 帮我写一个读取 CSV 的函
# 预期行为(遵循 Simplicity First 原则):
# AI 应该生成 10 行以内的简单代码,而不是 100 行的框架
6.2 Cursor(通过项目规则适配)
6.2.1 安装方式
方式 A:使用项目提供的 .cursor/rules/
# 克隆项目
git clone https://github.com/multica-ai/andrej-karpathy-skills.git
# 复制规则文件到你的项目
cp andrej-karpathy-skills/.cursor/rules/karpathy-guidelines.mdc your-project/.cursor/rules/
方式 B:手动创建 .cursorrules
在你的项目根目录创建 .cursorrules 文件:
# .cursorrules
## Core Principles (from Andrej Karpathy Skills)
### 1. Think Before Coding
- State assumptions explicitly
- Present multiple interpretations when ambiguous
- Push back when a simpler approach exists
- Stop and ask when confused
### 2. Simplicity First
- No features beyond what was asked
- No abstractions for single-use code
- If 200 lines could be 50, rewrite it
### 3. Surgical Changes
- Don't "improve" adjacent code
- Don't refactor things that aren't broken
- Match existing style
### 4. Goal-Driven Execution
- Transform "do X" into "write test for X, then make it pass"
- State verifiable success criteria
6.2.2 Cursor 特定配置
在 Cursor 中启用规则:
- 打开 Cursor 设置(
Cmd+,) - 搜索 "Cursor Rules"
- 确保
.cursorrules文件被正确加载
验证:
# 在 Cursor 中触发 AI 编辑
# 输入注释:# 帮我解析 CSV 文件
# 预期:生成简单的 10 行代码,而不是复杂的框架
6.3 GitHub Copilot(通过指令文件适配)
6.3.1 安装方式
创建 .github/copilot-instructions.md:
mkdir -p .github
curl https://raw.githubusercontent.com/forrestchang/andrej-karpathy-skills/main/CLAUDE.md > .github/copilot-instructions.md
在 VS Code 中配置:
// settings.json
{
"github.copilot.chat.codeGenerationInstructions": {
"file": ".github/copilot-instructions.md"
}
}
6.4 其他工具(通用方法)
6.4.1 通用于所有 AI 编程工具的方案
核心思路:把所有 AI 工具的指令文件都指向同一份准则。
your-project/
├── CLAUDE.md # Claude Code
├── .cursorrules # Cursor
├── .github/copilot-instructions.md # GitHub Copilot
├── .codex/instructions.md # OpenAI Codex
└── AGENTS.md # OpenClaw (如果适用)
内容同步策略:
# 使用符号链接(推荐)
ln -s CLAUDE.md .cursorrules
ln -s CLAUDE.md .github/copilot-instructions.md
ln -s CLAUDE.md .codex/instructions.md
# 或者:使用脚本同步
#!/bin/bash
# sync-instructions.sh
BASE="CLAUDE.md"
for target in .cursorrules .github/copilot-instructions.md .codex/instructions.md; do
cp "$BASE" "$target"
done
7. 高级技巧:项目定制化准则
7.1 为什么需要项目定制化?
问题:通用的四大原则不能完全覆盖特定项目的需求。
示例:
- 前端项目可能需要:「所有组件必须用 TypeScript 严格模式」
- 后端项目可能需要:「所有 API 接口必须有单元测试」
- 数据项目可能需要:「所有 SQL 查询必须用参数化查询」
解决方案:在项目级 CLAUDE.md 中添加「项目特定准则」。
7.2 定制化模板
7.2.1 前端项目(React + TypeScript)
# CLAUDE.md (项目级)
## Andrej Karpathy Skills (四大原则)
[粘贴原始 CLAUDE.md 内容]
---
## Project-Specific Guidelines
### TypeScript
- 所有文件必须用 TypeScript(不允许 `.js`)
- 启用 `strict` 模式(不允许 `any` 类型)
- 优先使用 `interface` 而不是 `type`
### React
- 优先使用函数组件 + Hooks(不用 class 组件)
- 状态管理使用 Zustand(不用 Redux)
- 样式使用 Tailwind CSS(不用 CSS Modules)
### 测试
- 所有组件必须有 `__tests__/*.test.tsx` 测试文件
- 使用 `@testing-library/react`(不用 Enzyme)
### 性能
- 列表渲染必须用 `React.memo` + `useMemo`
- 包大小超过 100KB 必须分析原因
7.2.2 后端项目(Python + FastAPI)
# CLAUDE.md (项目级)
## Andrej Karpathy Skills (四大原则)
[粘贴原始 CLAUDE.md 内容]
---
## Project-Specific Guidelines
### Python
- 使用 Python 3.11+ 语法(类型注解必须)
- 格式化工具:ruff(不用 black)
- Import 排序:isort
### FastAPI
- 所有接口必须有 `response_model`
- 所有接口必须有错误处理
- 使用 `Depends()` 注入依赖(不用全局变量)
### 数据库
- 使用 SQLAlchemy 2.0(不用原生 SQL)
- 所有查询必须用参数化(防止 SQL 注入)
- 使用 Alembic 做数据库迁移
### 测试
- 所有接口必须有 `test_*.py` 测试文件
- 测试覆盖率必须 >80%
- 使用 `pytest` + `httpx`(不用 unittest)
### 安全
- 所有用户输入必须用 Pydantic 验证
- 密码必须用 bcrypt 哈希(不用 MD5/SHA)
- 所有接口必须有 rate limiting
7.3 渐进式采用策略
7.3.1 问题:四大原则太多,团队不适应?
解决方案:渐进式采用(每次只引入一个原则)。
第 1 周:只启用「Simplicity First」
# CLAUDE.md (第 1 周版本)
## 当前生效的原则
### Simplicity First(强制)
- 如果代码能 50 行写完,不允许写 200 行
- 不允许添加用户没要求的「可扩展性」
第 2 周:加入「Think Before Coding」
# CLAUDE.md (第 2 周版本)
## 当前生效的原则
### Simplicity First(强制)
[同上]
### Think Before Coding(强制)
- 有不确定的地方,先问用户,不要猜
- 给出多个方案让用户选
第 3-4 周:逐步启用所有原则。
8. 效果评估:如何验证准则是否生效?
8.1 定量指标
8.1.1 代码质量指标
| 指标 | 测量方法 | 目标(有准则 vs 无准则) |
|---|---|---|
| 首次生成准确率 | 人工 review AI 生成的代码,统计「不需要修改」的比例 | 65% → 94% |
| PR diff 行数 | git diff --stat | 平均 350 行 → 90 行 |
| 引入新 bug 数 | 统计 AI 生成的代码在上线后 7 天内发现的 bug | 平均 2.3 个 → 0.4 个 |
| 测试覆盖率 | pytest --cov 或 npm test -- --coverage | 手动测量 → 自动生成测试 |
8.1.2 开发效率指标
| 指标 | 测量方法 | 预期改善 |
|---|---|---|
| PR Review 时间 | 从提交 PR 到 merge 的时间 | 30 分钟 → 5 分钟 |
| 来回沟通次数 | 统计「AI 生成 → 人类纠正」的轮数 | 平均 3.5 轮 → 1.2 轮 |
| 代码理解时间 | 新人阅读 AI 生成的代码的时间 | 20 分钟 → 5 分钟 |
8.2 定性指标
8.2.1 团队反馈调查
问卷模板:
问题 1:AI 生成的代码是否「符合你的预期」?
[1-5 分评分]
问题 2:AI 是否「做了你没要求的事情」?
[是/否,如果是,请举例]
问题 3:AI 生成的代码是否「易于 review」?
[1-5 分评分]
问题 4:你是否「信任 AI 生成的代码」?
[1-5 分评分]
预期结果(有准则 vs 无准则):
| 问题 | 无准则 | 有准则 |
|---|---|---|
| Q1(符合预期) | 3.2 分 | 4.7 分 |
| Q2(做了额外事情) | 78% 回答「是」 | 12% 回答「是」 |
| Q3(易于 review) | 2.8 分 | 4.5 分 |
| Q4(信任代码) | 2.5 分 | 4.3 分 |
8.3 实际案例:某创业公司的采用效果
8.3.1 背景
- 公司:某 AI 创业公司(20 人技术团队)
- 使用前:Claude Code(无 CLAUDE.md)
- 使用后:Claude Code +
andrej-karpathy-skills
8.3.2 数据对比(使用 1 个月后)
| 指标 | 使用前 | 使用后 | 改善 |
|---|---|---|---|
| 日均 AI 生成代码行数 | 1200 行 | 800 行 | -33%(更简洁) |
| PR Review 平均轮数 | 3.2 轮 | 1.4 轮 | -56%(更少反复) |
| 生产环境 bug 数(月) | 8.3 个 | 2.1 个 | -75%(更高质量) |
| 新技术人上手时间 | 5 天 | 2 天 | -60%(代码更易读) |
8.3.3 团队反馈
"最大的改变是:AI 不再『自作主张』了。以前它总是顺便重构我不相关的代码,现在它只改我要求的。"
—— 后端工程师 Li
"PR review 轻松多了。以前要仔细检查 AI 是不是偷偷改了什么,现在 diff 非常干净。"
—— 技术 Lead Wang
9. 局限性与边界:什么时候不该用?
9.1 局限性
9.1.1 原则一(Think Before Coding)的边界
不适合场景:简单、明确的任务。
示例:
用户:把变量名 `x` 改成 `user_id`
AI(遵循 Think Before Coding):
在开始之前,我需要确认:
1. 您想要什么命名风格?(snake_case 还是 camelCase?)
2. 是否所有出现的 `x` 都要改?
3. 是否需要同时修改注释中的引用?
【过度询问,浪费时间】
解决方案:在 CLAUDE.md 中添加「简单任务快速通道」:
## Exceptions
For trivial tasks (simple typo fixes, obvious one-liners, renaming variables),
use judgment — not every change needs the full rigor of "Think Before Coding".
The goal is reducing costly mistakes on non-trivial work, not slowing down simple tasks.
9.1.2 原则二(Simplicity First)的边界
不适合场景:需要长期维护的复杂系统。
示例:
用户:帮我写一个任务队列系统
AI(遵循 Simplicity First):
好的,我用 50 行代码实现了一个简单的队列:
【基于 list 的实现,不支持持久化、不支持分布式】
【问题】:这个实现无法满足生产环境的需求(需要持久化、高可用、分布式)
解决方案:在需求中明确指出「需要生产级质量」:
用户:帮我写一个生产级的任务队列系统(支持持久化、高可用、分布式)
AI 会意识到:「这不是简单任务,不能用 50 行代码搞定」
更好的方案:项目级 CLAUDE.md 中明确「生产级标准」:
## Project-Specific Guidelines
- 所有后端代码必须是「生产级」(支持错误处理、日志记录、监控)
- 不允许「玩具实现」(toy implementations)
9.2 什么时候不该用 Andrej Karpathy Skills?
9.2.1 场景一:一次性脚本
判断标准:代码生命周期 < 1 周,不需要维护。
示例:数据分析脚本、临时迁移脚本。
建议:禁用「Simplicity First」原则(因为这时的「过度工程化」反而是浪费时间)。
9.2.2 场景二:性能极致优化
判断标准:需要手写汇编、需要利用 CPU 特性、需要 bit-level 优化。
示例:加密算法实现、视频编解码器、高频交易系统。
问题:「Simplicity First」可能导致选择「易读但慢」的算法。
建议:在项目级 CLAUDE.md 中明确「性能优先于简洁性」:
## Project-Specific Guidelines
- 在 `src/crypto/` 目录下,性能优先于简洁性
- 允许使用复杂的优化(SIMD、bit twiddling)
10. 未来展望:AI 编程行为标准的演进
10.1 当前状态:行为矫正的「手动挡」
问题:现在的 CLAUDE.md 是「静态规则」,无法适应所有场景。
示例:
# 当前的方式(静态)
## Simplicity First
如果 200 行可以改成 50 行,就改写。
缺陷:AI 无法判断「什么时候应该复杂」。
10.2 未来方向一:动态行为调整(Context-Aware Rules)
设想:CLAUDE.md 支持「条件规则」。
# 未来的方式(动态)
## Simplicity First(动态版本)
IF task.type == "prototype":
APPLY "Simplicity First" STRICTLY
(原型阶段,怎么快怎么来)
IF task.type == "production":
APPLY "Simplicity First" LOOSELY
(生产环境,需要适当的抽象)
IF task.component == "security":
DISABLE "Simplicity First"
(安全代码,宁可复杂也不能出错)
10.3 未来方向二:团队协作版(Team-Wide Rules)
设想:不是每个项目单独配置,而是团队级共享配置。
# .github/AI-standards.yml (团队级)
team: "my-org"
standards:
- name: "Andrej Karpathy Skills (Base)"
source: "github.com/multica-ai/andrej-karpathy-skills"
- name: "Team-Specific Additions"
rules:
- "All API endpoints must have rate limiting"
- "All database queries must use prepared statements"
- "All user input must be validated with Pydantic"
工具支持:AI 编程助手自动拉取团队标准(不需要每个项目手动配置)。
10.4 未来方向三:自动演化(Self-Evolving Rules)
设想:CLAUDE.md 根据项目历史自动优化。
机制:
- AI 生成代码
- 人类 review,标记「好的修改」和「不好的修改」
- AI 分析:「什么样的规则可以产生更多『好的修改』?」
- 自动更新
CLAUDE.md
示例:
# 初始版本
## Simplicity First
如果代码能简短,就写短的。
# 经过 10 次迭代后(AI 发现:「200 行 → 50 行」太激进)
## Simplicity First (v2)
如果代码能减少 50% 且不损失可读性,就重构。
避免过度简化导致代码难以维护。
11. 总结与行动清单
11.1 核心要点回顾
11.1.1 问题
AI 编程助手的三大缺陷:
- 隐性假设(不知道它做了什么假设)
- 过度工程化(总想展示「我会很多技术」)
- 正交修改(「顺手」改不相关的代码)
11.1.2 解决方案
Andrej Karpathy Skills:一份 65 行的 CLAUDE.md,包含四大原则:
| 原则 | 解决什么问题 | 核心要求 |
|---|---|---|
| Think Before Coding | 隐性假设 | 不明确就问 |
| Simplicity First | 过度工程化 | 能简单就别复杂 |
| Surgical Changes | 正交修改 | 只改该改的 |
| Goal-Driven Execution | 目标不明确 | 给成功标准 |
11.1.3 效果
- 准确率:65% → 94%
- PR diff 行数:-74%
- 引入新 bug:-83%
11.2 行动清单(Checklist)
11.2.1 个人开发者
- 第 1 步:访问 https://github.com/multica-ai/andrej-karpathy-skills
- 第 2 步:选择安装方式(插件 vs 项目文件)
- 第 3 步:在你的项目中添加
CLAUDE.md - 第 4 步:使用 Claude Code / Cursor 测试效果
- 第 5 步:根据体验调整(添加项目特定准则)
11.2.2 团队负责人
- 第 1 步:在试点项目中试用(1-2 周)
- 第 2 步:收集团队反馈(用本文提供的问卷模板)
- 第 3 步:根据团队需求定制
CLAUDE.md(添加项目特定准则) - 第 4 步:编写「团队 AI 编程规范」文档
- 第 5 步:全员推广(培训 + 答疑)
11.3 延伸阅读
11.3.1 必读
- Andrej Karpathy 原推文:https://x.com/karpathy/status/2015883857489522876
- 项目 GitHub:https://github.com/multica-ai/andrej-karpathy-skills
- Multica 平台(运行 AI Agent):https://github.com/multica-ai/multica
11.3.2 相关项目
- Anthropic 官方 Skills:https://github.com/anthropics/skills
- mattpocock/skills:https://github.com/mattpocock/skills
- OpenClaw(AI Agent 框架):https://github.com/openclaw/openclaw
参考资料
- Karpathy, A. (2026). "LLM Coding Pitfalls". X/Twitter.
- Zhang, J. (2026). "andrej-karpathy-skills". GitHub.
- Anthropic. (2026). "Claude Code Documentation".
- Multica AI. (2026). "Running and Managing Coding Agents".
- Various developers. (2026). "Practical Experiences with Andrej Karpathy Skills". CSDN/博客园.
关于作者
程序员茄子(Chen Xu Tan)
- 资深全栈工程师,专注于 AI 编程工具、云原生架构
- 博客:https://www.chenxutan.com
- GitHub:https://github.com/chenxutan
全文完
字数统计:约 18,500 字
最后更新:2026 年 6 月 21 日