关于 karpathy
Karpathy Guidelines 是面向编码 Agent 的技能,用于在现有代码库中实施变更。它强调先读上下文、限制改动范围、核实假设,并设定可验证的完成标准。
主要功能
- 01修改前先阅读代码
- 02改动严格限定于需求
- 03依据代码核实假设
- 04设定具体成功标准
- 05避免添加推测性内容
适用场景
- 01实施指定的代码变更
- 02审查拟议的代码修改
- 03编码前检查实施规范
安装
复制下面的命令,在终端中运行。
$
npx skills add https:/ / github.com/ tmdgusya/ engineering-discipline --skill karpathy安装后在 Claude Code 中输入/karpathy确认已加载。
详细介绍
Karpathy 指南
一套用于代码实现的预防性思维准则。在编写代码前和编写过程中启用,以避免 LLM 生成代码时最常犯的错误。
这与性能无关(那是 rob-pike 的内容),也与调试无关(那是 systematic-debugging 的内容)。它关注的是编写代码这一行为本身——先读后写,只修改要求的内容,验证而非假设,并在开始前明确“完成”的标准。
硬性门槛
这些规则没有例外。
- 先读后写。 不要修改你尚未读过的文件。不了解调用方,就不要修改函数。不了解模块的作用,就不要修改模块。
- 将范围限定在请求内。 修改被要求的内容,不多不少。不要“顺手”改进,不要趁机重构,也不要添加未被要求的功能。
- 验证,不要假设。 如果你认为某个函数会执行 X,就去读它。如果你认为某个类型有字段 Y,就去确认。如果你认为某个测试覆盖了场景 Z,就去找出该测试。假设是 LLM 编码错误的主要来源。
- 开始前定义成功标准。 编写任何代码之前,先明确“完成”的具体且可验证的标准。如果无法定义,说明你还不理解这项任务。
何时使用
- 实现任何功能或变更之前
- 修改现有代码时
- 代码审查期间(作为思维检查清单)
- 发现自己尚未阅读周边上下文就开始生成代码时
何时不使用
- 没有现有代码可供阅读的全新项目(但第 1 和第 3 条门槛仍适用于依赖项)
- 纯文档变更
- 性能优化(改用
rob-pike)
五条规则
规则 1:进行精准修改
每项变更都应是实现目标所需的最小修改。
编写前,请自问:
- 解决这个问题所需的最小改动是什么?
- 我是否触及了不需要修改的文件?
- 我是否添加了未被要求的代码?
除非明确要求,否则禁止添加:
- 为未修改的代码添加类型注解
- 为未修改的函数添加文档字符串
- 为未修改的逻辑添加注释
- 为不属于任务范围的场景添加错误处理
- 重构周边代码
- 过程中发现的“改进”
一项任务,一项变更。如果发现其他需要修复的问题,记下来——现在不要修。
规则 2:阅读现有代码
LLM 会根据模式生成代码。代码库也有自己的模式,而这些模式往往并不一致。
修改任何文件之前:
- 阅读该文件
- 确认它采用的约定(命名、错误处理、模式、结构)
- 在修改中严格遵循这些约定
修改任何函数之前:
- 找出所有调用方
- 理解其契约(输入、输出和副作用)
- 确保你的修改不会破坏契约
添加新文件之前:
- 检查其他位置是否已有类似功能
- 遵循项目的文件组织模式
- 使用与相邻文件相同的命名约定
不要凭空创造新模式。遵循已有模式。
规则 3:验证假设
每个假设都可能引入 Bug。最危险的假设,是那些看起来显而易见的假设。
导致失败的常见假设:
| 假设 | 验证方式 |
|---|---|
| “这个函数返回 X” | 阅读该函数 |
| “这个字段始终存在” | 检查类型定义和上游生产方 |
| “这个测试覆盖了那个场景” | 阅读该测试 |
| “这个导入路径正确” | 检查该路径下的文件是否存在 |
| “这个 API 接受这些参数” | 阅读 API 定义或文档 |
| “这个库的工作方式是这样” | 查看版本和文档 |
| “这个配置值已设置” | 检查实际配置 |
有疑问时,就用 grep 搜索。即使确信,也要用 grep 搜索。
规则 4:定义成功标准
编写代码前,先明确“完成”的含义。
格式:
Done when:
- [ ] <specific, verifiable condition>
- [ ] <specific, verifiable condition>
- [ ] <specific, verifiable condition>
不好的标准:
- “功能可用”(无法验证)
- “代码整洁”(主观)
- “测试通过”(哪些测试?验证什么?)
好的标准:
- “有效负载合法时,POST /api/users 返回 201;缺少 email 时返回 400”
- “user.test.ts 中现有的测试仍然通过”
- “新增测试覆盖 issue #42 中的 null-brand 边界情况”
如果无法写出具体标准,说明你还不理解任务。请返回并澄清。
规则 5:不要解决不存在的问题
大模型喜欢预判未来需求。这会让代码变得不必要地复杂。
克制以下冲动:
- “如果有人传入 null 怎么办?”——当前代码中可能发生这种情况吗?如果不可能,就不要添加保护。
- “这应该可以配置”——现在需要配置吗?如果不需要,就直接写死。
- “我们可能需要支持多个后端”——现在有多个后端吗?如果没有,就不要抽象。
- “这可以做成通用工具”——它在多个地方使用了吗?如果没有,就针对当前场景实现。
- “我来加一个功能标志”——有人要求添加功能标志吗?如果没有,就直接修改代码。
根据今天的需求构建。明天的问题留到明天,届时再结合具体情况处理。
反模式
| 冲动 | 违反的规则 | 应对方式 |
|---|---|---|
| “我正好在这里,顺便快速重构一下” | 规则 1 | 一项任务,一处改动。记下来以后再处理。 |
| “我知道它是怎么工作的,直接修就行” | 规则 2 | 先阅读代码。你的认知可能有误。 |
| “它大概接收一个字符串” | 规则 3 | 检查类型。“大概”意味着你并不确定。 |
| “能用就算完成了” | 规则 4 | 开始前先定义具体标准。 |
| “我来让它便于未来扩展” | 规则 5 | 着眼于当前需求。可扩展性留作未来的任务。 |
| “这附近的代码很乱,我来整理一下” | 规则 1 | 这不是你的任务。另开一个 issue。 |
| “我来加一些有用的日志” | 规则 1 | 有人要求添加日志吗?如果没有,就不要添加。 |
警示信号
如果发现自己有以下想法,请停下来重新阅读规则:
- “这很明显,不用读代码”
- “我顺便再加几样东西”
- “最好能处理边界情况 X”(却没有检查 X 是否会发生)
- “我也来加强这里的类型安全”
- “我知道这个函数的作用”
- “这里需要更好的错误处理”(却没有证据表明错误确实会发生)
- “命名不一致,我来把整个文件里的命名都改一下”
精简检查清单
实施过程中,请按此清单检查:
- 修改文件前,我已阅读这些文件
- 我的改动仅限于所请求的范围
- 我已验证对类型、API 和行为的假设
- 开始前,我已定义具体的成功标准
- 我没有解决假设性的未来问题
- 我遵循了项目现有约定,没有另创新规
- 每一行新增代码都是完成任务所必需的
完成标准
符合以下条件,说明实施过程有条理:
- 所有改动都在请求的范围内
- 未经验证的假设均未被采纳
- 已定义并满足成功标准
- 没有添加臆测性的代码
- 遵循了现有约定
如果有任何一项未达成,就需要修改实施结果。
后续步骤
实施完成后:
- 如果仍有 AI 生成代码的坏味道 → 使用
clean-ai-slop执行修正 - 如果发现 Bug → 使用
systematic-debugging进行调查 - 如果需要关注性能 → 优化前使用
rob-pike
评论
支持 Markdown