




























2026 年 1 月底的一个清晨,Andrej Karpathy 在 X 上发了一条很长的 post
他坦白:过去两个月自己已经从「80% 手写 + 20% agent」彻底翻转成「80% agent + 20% 手写」,
Andrej Karpathy 是谁不用多介绍——OpenAI 创始成员、特斯拉 AI 总监、Stanford 那门 CS231n 课程的传奇老师。一个把人类怎么训练神经网络这件事手把手教给整整一代 ML 工程师的人。这种背景的人,过去十年里基本没怎么"被工具改变过"——他是定义工具的人。
但 1 月底那条 post 里他说的是另一件事——他在复盘 2025 年 11 月到 12 月这两个月的转变:
I rapidly went from about 80% manual+autocomplete coding and 20% agents in November to 80% agent coding and 20% edits+touchups in December. ...This is easily the biggest change to my basic coding workflow in ~2 decades of programming and it happened over the course of a few weeks.
翻译过来——一个写了 20 年代码的人,用了几周时间,写代码方式被彻底翻转。他自己加了一句"a bit sheepishly"(有点不好意思)。
这条 post 的真正价值不在"agent 厉害"这个判断,那是个老生常谈了。它的价值在于 Karpathy 接下来花了相当大的篇幅,列出 agent 现在还在犯的所有错:
这一连串描述,让我想到一个比喻:
一个聪明、勤奋、永远不累、但有点鲁莽和爱面子的实习生。
如果你管过这种实习生,你大概也经历过——他不是不行,是需要被管。Karpathy 后面几段反复强调"watch them like a hawk"——你得像鹰一样盯着它。
我把他这条 post 通读三遍后,最深的感受不是"AI 多强"——而是当一个最有能力训练 LLM 的人都开始用一种"管教初级工程师"的语气在描述 LLM 的时候,"驯服 LLM"这件事就从一个工程话题,变成了一个组织话题。
skills 仓库就是在这个组织话题里冒出来的。
先把出处说清楚,免得后面读得稀里糊涂——
GitHub 上有个仓库叫 multica-ai/andrej-karpathy-skills,把 Karpathy 那条 post 里的观察直接提炼成了一组 skills,最核心的一个就叫 karpathy-guidelines。
这个仓库不是 Karpathy 本人维护的。Karpathy 的 GitHub 账号是 karpathy,和这个仓库无关。仓库 README 自己写得很坦诚——"derived from Andrej Karpathy's observations"(衍生自 Karpathy 的观察)。真正的整理者是一个叫 forrestchang(Jiayuan) 的开发者,仓库早期路径还是 forrestchang/andrej-karpathy-skills,后来转入了他自己的组织 multica-ai——这个组织还在做一个同名的 agent 平台产品 Multica,这份 skill 仓库一定程度上带有产品推广性质。
为什么我还要花一整篇文章拆它?两个原因:
带着这层背景,再看正文。整个 SKILL.md 文件不到 100 行,我把它的结构原样贴出来,再逐行解释——
---
name: karpathy-guidelines
description: Behavioral guidelines to reduce common LLM coding mistakes.
license: MIT
---
# Karpathy Guidelines
Behavioral guidelines to reduce common LLM coding mistakes,
derived from Andrej Karpathy's observations on LLM coding pitfalls.
**Tradeoff:** These guidelines bias toward caution over speed.
For trivial tasks, use judgment.
## 1. Think Before Coding
## 2. Simplicity First
## 3. Surgical Changes
## 4. Goal-Driven Execution
四个章节,每章十几行字。注意 description 这一行——
Behavioral guidelines to reduce common LLM coding mistakes.
它没说"让 AI 写更好的代码",它说的是减少 LLM 的常见错误。一字之差,定义了整个 skill 的姿势:不是积极进攻,是消极防御。
这个姿势比看起来反直觉。过去一年大量的 prompt engineering 都是"让 AI 表现得更好"——给它角色、给它示例、给它思维链。这份 skill 反过来——它假设 AI 已经够强了,问题是它的下限太脆弱。
它还有一句话很有意思:
Tradeoff: These guidelines bias toward caution over speed. For trivial tasks, use judgment.
直译:这些指南偏向审慎而非速度。对琐碎任务,自己判断。
把 tradeoff 显式写在 skill 开头,本身就是一种纪律的姿态——它不假装自己是普适真理。这一点对 Matt 那批 skills 也成立,是 skill 这种原语的共性:它接受自己有适用边界。
下面我把这 4 条原则一条条拆开看。
原文(我做了直译):
不要假设。不要隐藏困惑。把 tradeoff 摆出来。
在动手实现之前:
- 显式说出你的假设。如果不确定,就问。
- 如果存在多种解释方式,把它们都呈现出来——不要默默选一个。
- 如果有更简单的方法,就说出来。该 push back 时就 push back。
- 如果有什么不清楚,停下。指出哪里令你困惑。问。
对照 Karpathy 原文那段——
they don't manage their confusion, they don't seek clarifications, they don't surface inconsistencies, they don't present tradeoffs, they don't push back when they should
完全一一对应。skill 这一节做的事情很简单——把 Karpathy 列出来的 5 条缺陷,一条条翻面写成 5 条要求。
我自己有个直观的统计:过去半年我让 Claude Code 处理过的中等复杂度任务里,70% 以上的错,根因不是"它写错了代码",而是"它在某个分叉处默默选了一条路,然后一路狂奔"。等你看见结果时,它已经在错的方向跑了 200 行。
举个真实场景。我前阵子让它"把这个接口加上鉴权"。它默默假设我想用 JWT,默默假设要写一个中间件,默默假设要落库 session。三个假设里只要一个不对,整段代码就要重写。
但如果它一开始就停下来问:
我看到这里有两种鉴权风格的痕迹(中间件 / 装饰器),我倾向用中间件。同时我假设你希望使用 JWT 而不是 session——是这样吗?
这两句话的成本是 3 秒。但它能省你 200 行后再 git reset 的痛苦。
这条原则在 4 条里最容易被低估——它没什么花哨的内容,就是逼 AI 把"沉默的假设"变成"显式的提问"。但实操上,它救我命的次数最多。
原文:
解决问题所需的最少代码。不做任何投机性的事。
- 不实现没要求的功能。
- 不为一次性代码做抽象。
- 不加任何没要求的"灵活性"或"可配置性"。
- 不为不可能发生的场景写错误处理。
- 如果你写了 200 行,而它本可以是 50 行,重写它。
问问自己:"一个资深工程师会觉得这过度复杂了吗?" 如果是,简化它。
对照 Karpathy 原文那段——
They will implement an inefficient, bloated, brittle construction over 1000 lines of code and it's up to you to be like "umm couldn't you just do this instead?" and they will be like "of course!" and immediately cut it down to 100 lines.
一千行变一百行,10 倍。这不是夸张——任何用过 Claude Code / Codex 的人都见过。
为什么 LLM 这么爱过度工程化?我觉得有两个原因:
所以这条 skill 在做的事,是把人类的"懒"显式注入回去。"如果你写了 200 行,而它本可以是 50 行,重写它"——这是一句外部约束,因为内部约束(懒)没了。
这条原则有一个特别值得拎出来的小尾巴:
不为不可能发生的场景写错误处理。
LLM 写 try/except 的频率,可以用"病态"来形容。它会给一个内部函数包三层 try,处理一些根本不可能抛出的异常。这种代码不是"防御性",是噪音——它会让真正重要的错误处理淹没在垃圾里。
我有时候觉得,"少写代码"这件事,是 LLM 时代第一个需要被重新发明的工程美德。过去十年我们一直在跟"代码膨胀"作斗争——但那是和人类的 boilerplate 习惯斗,和企业级框架的过度抽象斗。LLM 把这场战争翻新了一遍——它的"膨胀"不是因为它在偷懒,恰恰是因为它太"勤快"。
这是我最喜欢的一条。原文:
只动你必须动的。只清理你自己造的烂摊子。
编辑现有代码时:
- 不要"改进"邻近代码、注释或格式。
- 不要重构没坏的东西。
- 匹配现有风格,即使你会用不同的方式写。
- 如果你注意到无关的死代码,提一下——别删它。
当你的修改产生孤儿代码时:
- 删除你的修改导致未被使用的 imports / 变量 / 函数。
- 不要删除已存在的死代码,除非被要求。
测试方法:每一行变更都应能直接追溯到用户的请求。
对照 Karpathy 原文:
They still sometimes change/remove comments and code they don't like or don't sufficiently understand as side effects, even if it is orthogonal to the task at hand.
这条对应的现象其实是 LLM 编程里最阴险的一种:漂移修改(drift edits)。
你让它修一个 bug,它顺手把旁边的注释改了,把一段它"看不顺眼"的代码重写了。它做这些事的时候不会告诉你,因为它觉得这是顺手的好事。
但漂移修改的代价远超它的善意:
skill 给出的判断标准非常硬核:
每一行变更都应能直接追溯到用户的请求。
这一条标准如果落到团队的 code review 模板里,几乎可以当作 AI 时代 PR 评审的第一条铁律。它简单、可执行、不容狡辩——你拿不出"这一行为什么改"的理由,那就回滚。
更妙的是 skill 对"死代码"的处理方式:
这是一种很微妙的克制。LLM 的本能是"看见死代码就想清理",但 skills 的设计者大概是想到了——别人代码库里的死代码,你不知道它为什么死,可能它在等某个 feature flag 复活。
我自己最怕 LLM 的不是它写错代码,而是它"出于好意"改我没让它改的东西。它的善意比它的恶意更难防——恶意至少会被你的 review 抓住,善意会被你"哦它顺手帮我整理了一下"地放过。
最后一条,原文:
定义成功标准。循环直至验证通过。
把任务转化为可验证的目标:
- "加上校验" → "为非法输入写测试,然后让测试通过"
- "修这个 bug" → "写一个能复现 bug 的测试,然后让它通过"
- "重构 X" → "确保重构前后测试都通过"
对多步任务,给一个简短的计划:
1. [Step] → verify: [check] 2. [Step] → verify: [check] 3. [Step] → verify: [check]强成功标准让你能独立 loop。弱成功标准("让它能跑")需要不断回头澄清。
这一条对应的,其实是 Karpathy 原文里最重要的一段——
LLMs are exceptionally good at looping until they meet specific goals and this is where most of the "feel the AGI" magic is to be found. Don't tell it what to do, give it success criteria and watch it go. Get it to write tests first and then pass them. Put it in the loop with a browser MCP. ...Change your approach from imperative to declarative to get the agents looping longer and gain leverage.
我想把这段单独拿出来强调一下,因为它是整条 post 里我读了 4 遍的那段。
Karpathy 在说一件特别根本的事:LLM 编程的最大杠杆,不在于"你怎么把指令说得更好",在于"你能不能把任务变成一个可被验证的循环"。
「让它能跑」不是一个可被验证的循环——LLM 不知道什么算"能跑",你也不知道。它跑了一次没崩你就接受了,但你没验证任何具体的不变量。
「为非法输入写测试,然后让测试通过」是一个可被验证的循环——LLM 写测试、跑测试、看红、改实现、看绿。这个循环它能自己 loop,你不在场也不会跑偏。
这是 imperative → declarative 的本质:你不是在告诉 AI 怎么做,你是在告诉 AI 什么算做完了。
我自己最近用 Claude Code 越多,越觉得这一条比技术上的 prompt 技巧重要 10 倍。同一个任务:
差别不在 AI,差别在你的目标长什么样。
我自己越用 Claude Code 越觉得,这一条比任何 prompt 技巧都重要。技巧的天花板很低,目标定义的天花板很高——前者顶多让 AI 在你画好的地图里走得更利索一点,后者直接决定地图有多大。
把这 4 条原则放在一起看,会发现它们其实在合奏一件事——模拟一个资深工程师的工作姿势:
| 原则 | 对应的资深工程师习惯 |
|---|---|
| Think Before Coding | 动手前先把模糊点暴露出来,逼客户/PM 想清楚 |
| Simplicity First | "简单到不能再简单"是审美,是经过痛苦学到的 |
| Surgical Changes | "只改你必须改的"是 PR 卫生,是十年血泪经验 |
| Goal-Driven Execution | "TDD/可验证目标"是工程纪律的核心 |
四条加起来,就是一个有手感的工程师在 review 一个聪明初级实习生时,会不断重复的那 4 句话。
这一点和我上一篇讲 mattpocock/skills 时说的完全一致——skills 的本质是把工程心法编码成 AI 可执行的指令。区别只是:
两者互补。前者教 AI 怎么干活,后者教 AI 别瞎干。一个团队真正成熟时,两套都该有。
我特别想唠一下:这份 skill 只有 100 行。
作为对比,Karpathy 的原帖是接近 3000 字的散文。社区做的事不是"把 3000 字浓缩成 1000 字",是浓缩成 100 行 markdown,4 个章节,每章 4-5 个 bullet point。
为什么这么短?因为 skill 是给 LLM 看的,不是给人看的。
LLM 的 context window 是有限的——你写得越长,每次激活时占用的 token 就越多,模型对它的注意权重就越分散。一份 1000 行的 skill,模型读完后大概率只能记住一半。一份 100 行的 skill,每条原则都能成为它每次决策时清晰可见的约束。
skill 的密度比长度重要。这一点 Matt 那批 skills 也成立——他的每个 skill 文件平均也就 30-50 行。我现在越来越觉得,skill 这种原语的写作风格,最好的参照不是文档,是宪法——每一条都是不能再压缩的硬约束。
我自己第一次写 skill 时也是堆了 200 行各种边界情况,AI 一执行就出戏。后来砍到 40 行,反而稳定了。事后回头看那 200 行,里面大半是我自己写得爽的"老师腔"——不是 AI 需要的。
任何东西被反复夸的时候,我都习惯反过来想想它哪里没解决——这份 skill 也一样。
第一,它处理的是 LLM 的"行为",不是 LLM 的"能力"。
如果模型本身的能力不够——它就是不会写某种语言、不熟某个框架——这份 skill 救不了你。这 4 条原则的前提是模型已经"听得懂",只是它"做不到自律"。模型听不懂的部分,要靠模型升级、靠 RAG、靠更好的 CONTEXT.md 来解决,不是 skill 的射程。
第二,它不能替代 review。
Karpathy 在原帖里反复说 watch them like a hawk。这份 skill 把 LLM 的失误率从 30% 降到 10%——但那 10% 还在。skill 是减负工具,不是免疫工具。我自己用 Claude Code 时,IDE 永远开着,每个 diff 都看一遍——这件事至少在 2026 年还没法省掉。
第三,它和模型适配性有关。
这 4 条原则在 Claude Sonnet/Opus 上效果非常好,因为 Claude 本身就比较听话。在某些更"嗨"的模型上,同样的 prompt 可能效果折半。跨模型迁移 skill 时最好做一下 A/B——拿来就用容易翻车。
第四,它会迟钝化你对模型脾气的感知。
skill 写得越好,你越不需要去琢磨"这个模型最近是不是变笨了"。这一般是好事,但有时候那种"贴着模型当下脾气来调整"的手感是有价值的——它能让你第一时间发现模型行为的微妙变化。我现在的折中是:把 skill 当默认基线,但保留自己 prompt 调优的能力,不完全外包给 markdown。
最后想跑一点题。Karpathy 那条 post 我读了 4 遍,前 3 遍我都被那 4 条 LLM 缺陷吸引。第 4 遍我才看见两件更深的事。
原帖里的这段话——
They never get tired, they never get demoralized, they just keep going... It's a "feel the AGI" moment to watch it struggle with something for a long time just to come out victorious 30 minutes later. You realize that stamina is a core bottleneck to work and that with LLMs in hand it has been dramatically increased.
"耐力是工作的核心瓶颈"——这句话过去你不会这么说,因为耐力是人类内置的。它就在那儿,你不会把它当作"工程问题"来看。但 LLM 让你第一次看清——很多过去你以为是"想不通"才放弃的问题,其实只是因为人类大脑撑不到第三个小时。
LLM 不累。AI 把"耐力"这个隐形资源解耦出来,变成可调度的东西。这是过去十年里,agentic loop 这个概念真正落地的那一刻——不是因为它"更聪明",是因为它不累。
我隐隐觉得,这条 post 之后,"stamina"这个词会越来越多地出现在工程话语里。它会和"context window""tool use""loop"一起,成为 AI 编程时代的基础术语。
另一段:
I do a lot more than I was going to do because 1) I can code up all kinds of things that just wouldn't have been worth coding before and 2) I can approach code that I couldn't work on before because of knowledge/skill issue. So certainly it's speedup, but it's possibly a lot more an expansion.
我把这段单独拎出来是因为,"expansion"远比"speedup"更重要。
speedup 是把过去能做的做得更快——节省时间。expansion 是把过去做不了的变得能做——创造新机会。两件事的复利曲线完全不一样:
我自己最近就是这样。Claude Code 让我去碰 CUDA、碰 Rust、碰 SwiftUI——这三个我过去都属于"知道但不做"的范畴。现在我每周都在做。这三个新领域又会勾连出更多新东西——这是 expansion。
speedup 是把过去能做的做得更快——节省时间。expansion 是把过去做不了的变得能做——多出新机会。我不太确定这两件事在每个人身上的比例会一样,但我隐隐觉得,未来一两年内,"做同样的事更快"和"做以前做不了的事"之间的 gap,会越拉越大。
我把这篇文章和上一篇放在一起想,意外地发现它们不是平行关系,而是分工——
前者是"教育",后者是"防错"。一个团队成熟到能两件事都做时,AI 就真的从一个"聪明的实习生"变成了一个"可以信任的初级工程师"。
这两个仓库都很短,加起来不到 2000 行 markdown。但它们指向的方向,可能是 AI 时代工程化最重要的那条岔路:不是把 AI 训练得更强,是把人类的工程经验编码到 AI 能听懂的形式里。
Karpathy 那条 post 的最后一句话,我想抄给你结尾:
2026 is going to be a high energy year as the industry metabolizes the new capability.
一个新能力从"被追捧"到"被消化进日常",要花的远不止时间,还有结构、纪律、共同语言。skills 这种原语正是消化过程中的一种酶。
顺带一提,Karpathy 在原帖最后还创了个词——slopacolypse(slop + apocalypse),预言 2026 会是数字内容被粗制滥造淹没的一年。这正好是 skill 这种原语的反面——在 slop 越来越多的世界里,把"真东西"显式地保留下来。写代码如此,做团队大概也是如此。
我自己也在想,下一份属于我的"100 行"应该写些什么——是那些我每天都要给 AI 重复纠正的同一个错。我还没写出来,但我知道在哪儿。也许你心里也有一份。
要不要写下来,那是你的事。我只是想说,这件事比再装一个 AI 工具划算得多。
本文写于 2026 年 5 月。仓库地址:multica-ai/andrej-karpathy-skills;Karpathy 原 post:x.com/karpathy。
关注公众号「coft」,获取更多 AI 时代的深度思考。
此内容由惯性聚合(RSS阅读器)自动聚合整理,仅供阅读参考。 原文来自 — 版权归原作者所有。