一天一个开源项目(第108篇):Andrej Karpathy Skills - 用一个 CLAUDE.md 文件修复 LLM 编码的四个顽疾

引言

"LLMs excel at looping until they meet specific goals --- so provide success criteria rather than imperative instructions."

这是"一天一个开源项目"系列的第108篇文章。今天带你了解的项目是 andrej-karpathy-skills

这个项目非常特别:它的核心不是一个工具、框架或库------就是一个 CLAUDE.md 文件

故事起点是 Andrej Karpathy 在大量使用 Claude Code 之后发的一个 X 帖子,记录了他发现 LLM 在编码任务中反复出现的失效模式:不问清楚就动手、把简单问题工程化成复杂方案、顺手改了不该改的代码......

multica-ai 团队把这些观察提炼成了四条可操作的行为准则,打包进一个 CLAUDE.md 文件------你把它放进项目,Claude Code 就会改变行为方式。同时提供 Claude Code 插件和 Cursor 规则两种格式,覆盖主流 AI 编码工具。

这个项目很好地回答了一个常被忽视的问题:与其教 LLM 具体做什么,不如告诉它怎么思考

你将学到什么

  • Karpathy 观察到的 LLM 编码四大失效模式是什么
  • 四条行为准则的具体内容与实际案例
  • 三种安装方式:独立 CLAUDE.md / Claude Code 插件 / Cursor 规则
  • 为什么"给出成功标准"比"给出操作步骤"更有效
  • 如何验证这套准则是否真的在起作用

前置知识

  • 使用过 Claude Code 或 Cursor 等 AI 编码工具
  • 有一定的日常开发经验,能感受到 LLM 编码的痛点

项目背景

项目简介

andrej-karpathy-skills 的核心是一份行为配置文件。它的设计哲学来自一个关键洞察:

LLM 编码的问题,往往不是能力不够,而是行为没有约束。

模型有能力写简单的代码,但没人告诉它"不要写复杂的"。模型有能力先问清楚需求,但没有压力让它问。模型知道不该动无关的代码,但"顺便改一下"的习惯很难克制。

这份 CLAUDE.md 文件把这些约束显式化,让每次对话都带着这些行为准则进入上下文。

项目同时提供了三种分发格式,适配不同的使用场景和工具链。

作者/团队介绍

  • 维护方multica-ai(Multica AI 团队)
  • 灵感来源:Andrej Karpathy 在 X 上分享的 LLM 编码使用笔记
  • 原始作者 :该 CLAUDE.md 内容最初由 forrestchang 整理,multica-ai 将其扩展为插件生态

关于 Andrej Karpathy:OpenAI 联合创始人之一,前特斯拉 AI 负责人,现独立研究者,以 nanoGPT、Neural Networks: Zero to Hero 等教学项目在 AI 社区广为人知。他对 AI 工具的实际使用反馈,在业内有很强的参考价值。

项目数据

  • 📄 核心文件: CLAUDE.md(行为准则)
  • 🔌 Claude Code 插件 + Cursor 规则
  • 📖 附带: EXAMPLES.md(四原则的对比示例)
  • 📄 License: MIT
  • 🌐 仓库: multica-ai/andrej-karpathy-skills

主要功能

核心作用

这份 CLAUDE.md 直接对抗 LLM 编码中最常见的四个失效模式:

markdown 复制代码
LLM 编码常见失效
  ├── 静默假设(不问清楚直接动手)
  ├── 过度工程化(把简单问题变复杂)
  ├── 扩大改动范围(顺手改了不相关代码)
  └── 模糊执行(缺乏可验证的完成标准)
        ↓ CLAUDE.md 注入四条行为准则
  行为改变
  ├── 编码前先思考(Think Before Coding)
  ├── 简单优先(Simplicity First)
  ├── 外科手术式修改(Surgical Changes)
  └── 目标驱动执行(Goal-Driven Execution)

快速开始

方式一:Claude Code 插件(推荐,全局生效)

bash 复制代码
/plugin marketplace add forrestchang/andrej-karpathy-skills
/plugin install andrej-karpathy-skills@karpathy-skills

安装后对所有项目生效,无需在每个项目中单独配置。

方式二:项目级 CLAUDE.md(只对当前项目生效)

bash 复制代码
cd your-project
curl -o CLAUDE.md https://raw.githubusercontent.com/forrestchang/andrej-karpathy-skills/main/CLAUDE.md

如果项目中已有 CLAUDE.md,可手动将内容合并进去。

方式三:Cursor 规则

仓库中已包含 .cursor/rules/karpathy-guidelines.mdc,设置了 alwaysApply: true。将该文件复制到你的项目中即可:

bash 复制代码
mkdir -p .cursor/rules
cp path/to/karpathy-guidelines.mdc .cursor/rules/

验证是否生效:打开 Cursor → Settings → Rules,查看规则是否出现在列表中。

验证准则是否在起作用的信号

  • 实现前 Claude 会主动提问而不是直接开始写
  • PR diff 里的改动更干净,只涉及被请求的部分
  • 不再出现"顺便优化了一下"的代码变动

四条准则详解

准则一:编码前先思考(Think Before Coding)

针对的问题:LLM 在遇到模糊需求时倾向于做出隐性假设并直接执行,而不是把不确定性暴露出来。

错误行为示例

makefile 复制代码
用户: 给我导出用户数据的功能
LLM: [直接开始写代码]
     → 假设导出 CSV,假设所有字段,假设同步下载
     → 但用户实际需要的是后台任务 + 特定字段 + JSON 格式

正确行为(准则要求先把不确定性表面化):

markdown 复制代码
用户: 给我导出用户数据的功能
LLM: 在开始之前,有几个问题需要确认:
     1. 范围:导出所有用户还是按条件过滤?
     2. 格式:CSV / JSON / Excel?
     3. 交付方式:浏览器直接下载、后台任务发邮件,还是 API 接口?
     4. 字段:需要哪些字段?是否包含敏感数据?

另一个典型案例------"让搜索更快"有三种完全不同的含义:

解释 实际需求 解决方案
响应时间 API 返回慢 加索引、缓存、优化查询
吞吐量 并发量高 水平扩展、队列
体感速度 用户觉得慢 预加载、骨架屏、即时反馈

三种解释需要完全不同的方案,任何一个都不能"默认"。

准则要求:当存在多种合理解释时,呈现所有解释让用户选择,而不是悄悄选一个。在真正困惑时停下来说"我不确定这里应该如何处理",而不是硬撑下去。


准则二:简单优先(Simplicity First)

针对的问题:LLM 有强烈的过度工程化倾向,在复杂性真正需要之前就引入抽象、框架和"灵活性"。

错误行为示例------折扣计算:

python 复制代码
# 用户要求:实现一个简单的折扣计算

# ❌ LLM 给出的"方案"(10 倍代码量):
class DiscountStrategy(ABC):
    @abstractmethod
    def calculate(self, price: float) -> float: ...

class PercentageDiscount(DiscountStrategy):
    def __init__(self, config: DiscountConfig): ...
    def calculate(self, price: float) -> float: ...

class DiscountCalculator:
    def __init__(self, strategy: DiscountStrategy): ...
    def apply(self, cart: Cart) -> float: ...

# 工厂类、配置类、注册器......

# ✅ 实际需要的(1 个函数):
def apply_discount(price: float, discount_pct: float) -> float:
    return price * (1 - discount_pct / 100)

另一个示例------"保存用户偏好设置":

markdown 复制代码
❌ LLM 实现了:
   - 带失效时间的缓存层
   - 输入验证(用户没要求)
   - 冲突合并逻辑(用户没遇到这个问题)
   - 变更通知系统(用户没提到)

✅ 实际需要的:
   - 把偏好写入数据库的一个函数

准则给出的判断标准

"一个 senior 工程师看到这段代码,会说它过于复杂吗?"

如果 200 行代码可以写成 50 行,就重写成 50 行。

核心格言

"Good code is code that solves today's problem simply, not tomorrow's problem prematurely."

过早引入的复杂性不只是浪费,还会让代码更难理解、引入更多 bug,哪怕它遵循了正确的设计模式。


准则三:外科手术式修改(Surgical Changes)

针对的问题:LLM 做"顺路重构"------修复一个 bug 时,顺便改了引号风格、加了类型注释、重命名了变量、整理了导入顺序。

这个行为看起来是好意,但实际上有两个严重问题:

  1. 让 diff 变得难以审查:reviewer 无法区分哪些改动是 bug 修复、哪些是"顺便"
  2. 引入意外 regression:每一行未经要求的改动都是潜在的风险点

正确的做法

python 复制代码
# 原始代码(有 bug,同时有一些"不完美"之处)
def calculate_total(items):
    total = 0
    for item in items:
        total += item['price']  # 单引号
    return total                 # 缺少类型注释

# ❌ LLM 的"全面改善":
def calculate_total(items: list[dict]) -> float:  # 加了类型注释
    """Calculate total price of items."""          # 加了文档字符串
    total: float = 0.0                             # 改了变量类型
    for item in items:
        total += item["price"]  # 改成双引号("风格统一")
    return total

# ✅ 只修复 bug(假设 bug 是 items 为空时的问题):
def calculate_total(items):
    if not items:               # 只加了这一行
        return 0
    total = 0
    for item in items:
        total += item['price']  # 保持原有风格不变
    return total

准则的具体要求

  • 每一行改动都要能追溯到用户的请求
  • 匹配现有代码风格,即使你更喜欢另一种
  • 不要改进"路过"的代码,除非被明确要求
  • 只清理你的改动产生的无用导入/变量,不要动原有的

准则四:目标驱动执行(Goal-Driven Execution)

针对的问题:LLM 在接到模糊任务时,会给出看起来很全面但缺乏可验证性的计划。

模糊计划的示例

markdown 复制代码
任务: "重构 auth 模块"

❌ 模糊计划:
   1. 审查现有代码
   2. 识别问题
   3. 改进结构
   4. 运行测试
   → 没有任何一步有明确的完成标准

准则要求把任务转化为可验证的目标

yaml 复制代码
任务: "修复登录 bug"

✅ 目标驱动计划:
   步骤 1: 写一个复现 bug 的失败测试
           验证点: 测试确实在当前代码上失败
   步骤 2: 实现修复
           验证点: 刚才写的测试现在通过
   步骤 3: 运行完整测试套件
           验证点: 没有新的回归
   → 每步都有明确的"完成"定义

另一个示例

markdown 复制代码
任务: "重构 auth 模块"

✅ 具体化后:
   1. 所有现有测试通过(记录基线)
   2. 抽取 TokenService(验证:独立单元测试通过)
   3. 重构 AuthController 使用 TokenService(验证:集成测试通过)
   4. 所有原有测试仍然通过(无回归)

Karpathy 的核心洞察

LLM 最擅长的事是"循环直到满足特定目标"------因此,提供成功标准比提供操作步骤更有效。

命令式指令("先做 A,然后做 B,然后做 C")在出错时会让 LLM 不知道该怎么处理。声明式目标("这个测试要通过"、"这个接口要可调用")让 LLM 可以自主决定路径,同时有清晰的完成标准。


为什么是一个文件,而不是一个工具?

这个项目的设计选择本身就值得深思。面对 LLM 编码的行为问题,可以有很多种解决方案:

  • 构建一个代理框架来约束行为
  • 开发后处理工具来检测和修正
  • 训练一个更好的模型

andrej-karpathy-skills 选择的是最简单的那个:一个文本文件,放进项目里,让 LLM 自己读自己执行。

这个选择本身就是对"简单优先"原则的最好示范------用最少的机制,解决今天的问题。而且,文本文件有一个工具无法比拟的优势:可以随时阅读、理解和修改,没有任何黑盒。


项目地址与资源

官方资源

  • 🌟 GitHub : github.com/multica-ai/...
  • 📄 原始 CLAUDE.md : 直接 curl 下载即可使用
  • 📖 示例文档 : EXAMPLES.md(四原则的对比示例,推荐阅读)

适用人群

  • Claude Code / Cursor 日常用户:希望减少 LLM 的过度工程化和不必要的代码改动
  • 团队工程效能负责人:在团队 CLAUDE.md 中集成这套行为规范,统一 AI 辅助编码的行为基准
  • 追求代码可审查性的开发者:厌倦了 LLM 生成的"超级 diff",想要干净的、只包含请求变更的 PR

总结与展望

核心要点回顾

  1. 来源:直接提炼自 Karpathy 对 LLM 编码失效模式的一手观察,有真实使用基础
  2. 四条准则
    • 编码前先思考:把隐性假设变成显性问题,而不是悄悄选一个
    • 简单优先:写解决今天问题的最少代码,不预建"灵活性"
    • 外科手术式修改:每行改动都能追溯到请求,不做顺路重构
    • 目标驱动执行:给成功标准,不给操作步骤
  3. 三种安装格式CLAUDE.md(项目级)/ Claude Code 插件(全局)/ Cursor 规则
  4. 核心哲学:LLM 最擅长循环直到达成目标------给目标,不给步骤
  5. 自我示范:用最简单的方式(一个文件)解决问题,自身就是"简单优先"原则的体现

一句话评价

andrej-karpathy-skills 做了一件看似微小但影响深远的事:把"怎么用好 LLM 写代码"的工程智慧,压缩进一个任何人都能读懂、放进任何项目的文本文件------而这个文件本身,就是它所倡导的简单哲学的最好证明。


欢迎来我的个人主页找到更多有用的知识和有趣的产品

相关推荐
涛声依旧-底层原理研究所1 小时前
残差连接与层归一化通俗易懂的详解
人工智能·python·神经网络·transformer
fantasy_arch2 小时前
pytorch人脸匹配模型
人工智能·pytorch·python
科技那些事儿2 小时前
实时洞察,视觉赋能:国内情绪识别API公司推荐及计算机视觉流派深度解析
人工智能·计算机视觉
德思特2 小时前
从 Dify 配置页理解 RAG 的重要参数
java·人工智能·llm·dify·rag
火山引擎开发者社区2 小时前
ArkClaw AI 盯盘管家 —— 从手动口令到自动推送,4 套预置定时任务模版一键启用
人工智能
sxgzzn2 小时前
新能源场站数智化转型:基于数字孪生与AI的智慧运维管理平台解析
大数据·运维·人工智能
北巷`2 小时前
CC Workflow Studio 解析与落地方案
人工智能·团队开发
十铭忘2 小时前
连续扩散语言模型
人工智能