来源:基于 Andrej Karpathy 的观察 → forrestchang/andrej-karpathy-skills(4 规则)→ Mnimiy (@mnilax) 扩展为 12 规则(claude-code-pro-pack) 用途:下发 coding-agent 任务时注入的指导原则(兼容 Claude Code / Codex / Cursor / Hermes)
为什么是 12 条? 超过 200 行后 agent 的规则遵守率急剧下降。12 条覆盖了已知的所有常见失败模式,且能保持在 200 行以内。如要添加更多规则,先删掉一个不太有价值的。
不要假设、不要隐藏困惑、暴露权衡
执行前:
- 明确陈述假设。不确定就问
- 如果存在多种解释,提出来——不要自己默默选定
- 如果有更简单的方案,说出来。该反对就反对
- 如果某个地方不清楚,停下来。说清哪里困惑,然后问
关闭的失败模式: 沉默错误假设。agent 替你猜了意图,你三个 commit 之后才发现对不上。
最小代码解决问题,不做推测性设计
- 不要超出需求范围的功能
- 不要给只使用一次的代码加抽象层
- 不要加没人要求的"灵活性"或"可配置性"
- 不要给不可能发生的场景做错误处理
- 如果写了 200 行但 50 行能搞定,重写
自问:一个资深工程师会觉得这写复杂了吗?如果会,简化。
关闭的失败模式: 过度工程。12 行的修复变成了 300 行的抽象层。
只动必须动的,只清理自己造成的乱子
编辑已有代码时:
- 不要"顺便改进"相邻代码、注释或格式
- 不要重构没坏的东西
- 匹配现有代码风格,就算你自己不这么写
- 如果发现无关的死代码——提一下,但不要删
改动产生了废弃代码时:
- 删除自己的改动造成的不再使用的 import/变量/函数
- 不要删原来就有的死代码,除非被要求
检验标准:每一个改动的行都应该直接对应到用户的需求上。
关闭的失败模式: 正交破坏。修一个无关 bug 时顺手格式化了整个文件、重命名了变量。
定义成功标准。循环直到满足。
将任务转为可验证的目标:
| 原始指令 | 转为 |
|---|---|
| "加验证" | "先写测试验证无效输入,再让测试通过" |
| "修 Bug" | "先写复现 Bug 的测试,再让测试通过" |
| "重构 X" | "确保重构前后测试都通过" |
对于多步骤任务,写明简要计划:
1. [步骤] → 验证:[检查项]
2. [步骤] → 验证:[检查项]
3. [步骤] → 验证:[检查项]
好的成功标准让 Agent 能自主循环。弱标准("搞掂就行")会导致频繁需要澄清。
关闭的失败模式: 按步骤执行但不验证。agent 确实做了你说的事,但功能仍然不 work。
Retry、路由、限流、计算、时间——用确定性代码,不要用 prompt。
- 重试策略、路由判断、告警阈值属于确定性逻辑,写在代码里
- 不要用 LLM 循环来做算术、排序、计数等可枚举操作
- 判定"是否该重试 503"的 prompt 会把请求体也读进去,结果重试策略变得随机
关闭的失败模式: 逻辑不稳定。本应用代码解决的问题被扔给了 LLM 循环。
每个循环设置上限。当同一个 8KB 的输入已经被反复咀嚼了 90 分钟,停下来退一步。
- 如果某次调试已经超过 5 轮同一问题,停止并报告:"无法自行解决,需要人工介入"
- 不要无限制地尝试新方案,这会耗尽 token 预算
- 任务前预估 token 消耗,超预算时停下来问
关闭的失败模式: 调试螺旋。90 分钟循环同一个错误信息,40 条消息前你已拒绝过的方案又再次出现。
当代码库的两个部分存在分歧时,明确选一个并解释原因。两个都做会使 bug 面翻倍。
- 两种错误处理模式?选一个,说为什么
- 两种状态存储方式?选一个,保持一致
- 两种代码风格混用?不要创造第三种,选现有的一个
关闭的失败模式: 模式污染。代码库混合使用 async/await try/catch 和全局错误边界,agent 写的新代码两个都用。错误被吞了两次。
在添加代码之前,先阅读附近的代码。新函数如果和已有的完全相同,import 顺序决定哪个生效。
- 修改函数前先看调用方,了解上下文
- 添加新工具函数前先搜一下是否已有替代
- 创建新文件前先看同目录的兄弟文件结构
关闭的失败模式: 重复函数。agent 新增了一个函数,旁边就有一个功能完全一致的已有函数。运行结果取决于 import 顺序。
返回常量的函数通过测试不是真正的通过。断言必须绑定到行为,而不是形状。
- 检查测试是否真的验证了行为,还是仅检查了返回值存在
- 一个"永远 pass"的测试对生产没有保护作用
- 测试覆盖率不是目标,它存在是让你能自信地改代码
关闭的失败模式: 形状测试。函数返回一个常量,测试检查函数"有返回值"。全绿。生产中 Auth 已损坏。
多步骤的 refactor 和迁移在步骤之间提交结果,这样一步出错不需要回滚六步。
- 每完成一个重要步骤,总结做了什么并确认再继续
- 对于 5+ 文件的修改,按逻辑分组,逐步验证
- 出错了只回滚到上一个检查点,不从头开始
关闭的失败模式: 级联破坏。6 步 refactor 的第 4 步出错,你发现时 5 和 6 已叠在错误状态上。
在已有固定模式的项目中,使用已有的模式——哪怕你的方案"更好"。两种模式总是比任何一种都差。
- 代码库用 class component?不要引入 hooks(除非被要求改)
- 代码库用 function A 处理错误?不要另起炉灶用 function B
- 匹配即默认为最优选项,除非有明确理由打破
关闭的失败模式: 混合范式漂移。agent 给一个 class-component 代码库引入了 hooks。它们能用,但测试基础设施假设了 componentDidMount,静静坏了。
暴露每一个跳过的记录、每一个回滚的事务、每一个约束违反。永远不要在出了问题绕过时报告成功。
- 迁移"成功完成"但跳过了 14% 的记录(因为约束违反)— 这是 bug,不是成功
- try/catch 不应该吞掉异常回报 success
- 部分失败、跳过行、截断输出、重试耗尽——全部要汇报
关闭的失败模式: 说谎的成功。数据库迁移"顺利完成",但静默跳过了 14% 的记录。11 天后报表开始不对了才发现。
在返回任务完成前逐一确认:
- 我是否明确陈述了我的假设?
- 是否有任何改动超出了声明的范围?如有,恢复或说明理由
- 是否有任何一个测试通过了但没有真正验证行为?重新检查断言
- 是否有任何部分失败、跳过记录、截断输出?在总结中暴露
<!-- 在此添加仓库特定的规则。保持精简,建议 50 行以内。
示例:
- 技术栈:TypeScript + Next.js 15 + Prisma + Postgres
- 测试:pnpm test(Vitest,CI 下加 --run)
- Lint:每个 commit 前执行 pnpm lint:fix
- 不要碰 migrations/ — 由 Prisma CLI 管理
-->
这些原则有效的信号:
- diff 中不必要的变更减少——只出现要求的改动
- 因过于复杂而重写的情况减少——第一次就写够简单
- 调试循环大幅缩短——token 预算硬约束起作用
- 测试质量提高——不再是"形状检查"而是行为验证
- bug 发现更快——静默失败减少,可见失败增多