从默默猜想到自查自纠:一份 CLAUDE.md 如何管住 Claude Code 的编码风格
【免费下载链接】andrej-karpathy-skillsA single CLAUDE.md file to improve Claude Code behavior, derived from Andrej Karpathy's observations on LLM coding pitfalls.项目地址: https://gitcode.com/GitHub_Trending/an/andrej-karpathy-skills
你只要说一句"加个算折扣的函数",AI 上来就是策略模式、抽象类、配置类,100 行的活儿写出 1000 行,还默默把细节全假设了,一个问题都不问。这正是 andrej-karpathy-skills 要解决的问题:把四条行为准则压进一个 CLAUDE.md,让 Claude Code 的编码行为收敛下来。
项目来历:Karpathy 对 AI 编码陷阱的观察
Andrej Karpathy 在观察 LLM 编码时总结过一组经典毛病:模型会替你做出错误假设然后一路狂奔,不寻求澄清、不说明取舍,100 行能完成的事膨胀成 1000 行,还会顺手改动它并不理解的代码和注释。这个项目(仓库名 andrej-karpathy-skills)把这一观察提炼成四条原则,写进单一CLAUDE.md文件,MIT 协议,可以直接放进任何项目使用。
四条准则自检清单:让 Claude Code 编码更靠谱
先别猜,开口问 🤔
不要假设,不要藏着困惑,更不要默默挑一种解释然后闷头执行。
- 动手前把你依赖的假设明确说出来,没把握就问
- 存在多种理解时,全部列出来让你挑,而不是自己拍板
- 如果觉得有更简单的做法,直接讲,该反对就反对
- 卡住了就停下来,说清楚哪里不清楚,再继续
自检标准:如果每个假设你都能写出来,才可以开工;写不出来,就先回去提问。
只做被要求的,一件都不多
写解决问题的最小代码,不为"将来也许"提前铺路。
- 不加需求之外的功能
- 不为一次性代码建抽象
- 不塞没人要的"灵活性"和"可配置性"
- 不处理不可能发生的场景
- 写了 200 行而 50 行就能解决,重写
自检标准:问自己"资深工程师会不会说这过度设计了?"会,就简化。
像外科手术一样下刀 🎯
只动必须动的地方,只清理你自己制造出来的烂摊子。
- 不"顺手改进"相邻的代码、注释和格式
- 不重构没坏的东西
- 匹配现有风格,哪怕你会用别的写法
- 发现无关的死代码,提一嘴,别删
- 只删除因你这次改动而变得无用的导入、变量、函数
自检标准:你改动的每一行,都应能直接追溯到用户的原始请求。
先定义"做完"长什么样 🏁
别接指令式任务,先把它翻译成可验证的目标,然后循环直到通过。
| 指令式说法 | 可验证目标 |
|---|---|
| "加个验证" | 为无效输入写测试,然后让测试通过 |
| "修这个 bug" | 先写一个能复现 bug 的测试,然后让它通过 |
| "重构 X" | 确保重构前后的测试都通过 |
多步任务先列个简短计划,每步都带验证动作:
- [步骤] → 验证:[检查点]
- [步骤] → 验证:[检查点]
- [步骤] → 验证:[检查点]
自检标准:标准越强,AI 越能独立循环;如果你发现自己总在被追问"做成什么样",说明目标定义得不够清楚。
实战对照:两个 AI 编码翻车现场的前后差异
场景一:"加个导出用户数据的功能"
❌ 常见的翻车姿势:AI 直接假设"导出全部用户到本地 JSON 文件",然后开写:
def export_users(format='json'): users = User.query.all() with open('users.json', 'w') as f: json.dump([u.to_dict() for u in users], f) return f"Exported {len(users)} users"导出范围、文件位置、字段取舍、隐私风险,全被默默定了,你 review diff 时才发现。
✅ 准则下的行为差异:AI 动手前先摆出待澄清的清单——
- 范围:全部用户还是筛选后的子集?(隐私问题)
- "导出"指浏览器下载、带邮件通知的后台任务,还是返回数据的 API?
- 导出哪些字段,哪些是敏感的?
- 用户量级多大?这决定方案选型
然后给出最简方案(比如一个返回分页 JSON 的 API 端点)让你选。说白了,区别在于:前者是"我替你决定",后者是"选项给你,你定"。
场景二:"加个计算折扣的函数"
❌ 常见的翻车姿势:直接上策略模式——抽象基类、百分比/固定额两个策略类、配置 dataclass、计算器包装类,约 40 行,用的时候还得再写 30 行初始化。
✅ 准则下的行为差异:
def calculate_discount(amount: float, percent: float) -> float: """Calculate discount amount. percent should be 0-100.""" return amount * (percent / 100)什么时候才引入复杂度?等真的需要多种折扣类型那天再重构。值得注意的是:过度抽象那版并不"错",它遵循标准设计模式,错在时机——过早加复杂度,代码更难懂、更难测、写起来更慢。
接入步骤:三种把准则装进 Claude Code 的方式
推荐:装成 Claude Code 插件
在 Claude Code 内先加市场,再装插件,装一次,所有项目通用:
/plugin marketplace add forrestchang/andrej-karpathy-skills/plugin install andrej-karpathy-skills@karpathy-skills适合人群:以 Claude Code 为主力、不想每个项目单独配置的开发者。
替代一:项目级放置 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适合人群:想自己微调准则、或使用的工具只认根目录指令文件的人。追加之后可以再加一个"Project-Specific Guidelines"小节,写死模式、测试要求等项目专属规则,和这四条准则合并使用。
替代二:在 Cursor 里用
仓库自带 Cursor 项目规则:把.cursor/rules/karpathy-guidelines.mdc拷到你项目的.cursor/rules/目录(没有就建),打开项目即自动生效。想升级为个人级技能,仓库还提供了skills/karpathy-guidelines/SKILL.md,可复制或软链到你的个人技能目录。
生效信号:怎么判断准则真的起效了
用上一段时间,你开始注意到这些变化:
- 你开始注意到 diff 里"意外改动"变少了——只出现你要求的修改
- 你开始注意到因过度复杂而重写的次数变少了——代码第一版就是简单版
- 你开始注意到澄清问题提前了——在实现之前问,而不是出错之后才挖
- 你开始注意到 PR 更干净了——没有顺带的重构,也没有自我加戏的"改进"
需要留意:这套准则的取舍是"谨慎优先于速度"。改错别字、一行就能搞定的小活不必走全流程——它的目标是降低复杂任务上的高成本错误,不是拖慢简单任务。
收尾:让 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."
这也是为什么"定义成功标准,循环直到验证通过"是四条准则里分量最重的一条:它没有要求 AI 变得更听话,而是把协作模式从"执行指令"切换成"追求可验证的目标"。目标清晰,模型的循环迭代能力才真正被释放;目标模糊,跑得再快也是偏航。把今天的问题简单解决掉,别为明天的问题提前付复杂度。
延伸阅读:仓库里的EXAMPLES.md收录了四条准则的前后对照代码与反模式分析,README.zh.md是项目的完整中文说明,CURSOR.md则讲清了 Cursor 场景下的接入细节。
【免费下载链接】andrej-karpathy-skillsA single CLAUDE.md file to improve Claude Code behavior, derived from Andrej Karpathy's observations on LLM coding pitfalls.项目地址: https://gitcode.com/GitHub_Trending/an/andrej-karpathy-skills
创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考