我开始重新理解 AI 编程:不是让 AI 多写代码,而是让 AI 少犯错
最近我看到一个很有意思的项目: andrejkarpathyskills。
最近我看到一个很有意思的项目:
andrej-karpathy-skills。
它的核心并不是教你怎么写更复杂的 Prompt,也不是告诉你怎么让 AI 一次性生成几千行代码,而是反过来提醒我们:
真正好用的 AI 编程助手,不是“写得多”,而是“想清楚、改得准、少折腾”。
这个项目受 Andrej Karpathy 的一些观察启发,整理了一套适合 Claude Code、Cursor 等 AI 编程工具使用的规则。它通过一个 CLAUDE.md 或插件的方式,把这些规则注入到 AI 编程助手的工作习惯中。:contentReference[oaicite:0]{index=0}
我看完之后,最大的感受是:
我们以前使用 AI 编程,太关注“让它做什么”;但真正应该关注的是“让它怎么做”。
一、为什么 AI 编程经常让人又爱又恨?
现在很多开发者已经离不开 AI 编程工具了。
比如:
- 让 AI 帮你写一个接口;
- 让 AI 帮你修一个 Bug;
- 让 AI 帮你重构一段代码;
- 让 AI 帮你分析一个 Android 项目;
- 让 AI 帮你补测试、写文档、生成脚本。
一开始你会觉得很爽。
以前半天才能写完的东西,现在几分钟就能出来一个版本。
但用久了之后,你会慢慢发现一些问题:
AI 很容易自作主张。
你只是让它修一个 Bug,它可能顺手把旁边的代码也“优化”了。
你只是让它加一个简单判断,它可能给你抽象出一套策略模式、工厂模式、配置中心。
你只是让它改一处逻辑,它可能连注释、格式、命名都给你改了一遍。
更麻烦的是,有时候它并没有真正理解你的项目上下文,却会表现得非常自信。
它不会说“我不确定”。
它不会主动告诉你“这里有两个理解方向”。
它不会提醒你“这样改可能会影响旧逻辑”。
它往往会直接开干。
这就是 AI 编程最危险的地方:
它不是不会写代码,而是它太敢写代码。
二、Karpathy 提醒我们的核心问题
README 里引用了 Andrej Karpathy 对 LLM 编程问题的观察。
大意是:
AI 模型会替你做错误假设,然后不假思索地执行;它们不会管理自己的困惑,不会主动寻求澄清,不会展示权衡,也不会在应该提出异议的时候反驳你。:contentReference[oaicite:1]{index=1}
这句话非常关键。
因为在真实开发里,最可怕的不是“代码写错”。
代码写错,编译器、测试、运行日志可能还能发现。
最可怕的是:
方向错了,但代码看起来很完整。
比如:
你让 AI 修改支付逻辑。
它根据表面代码猜了一个实现方式,然后改了一堆。
结果编译通过,页面也能打开,但实际支付场景里的某个老渠道挂了。
这类问题很难第一时间发现。
因为 AI 生成的代码往往“看起来没问题”。
而这正是我们需要给 AI 设置规则的原因。
三、这个项目提出的 4 个核心原则
这个项目把规则总结成了 4 个原则:
- 编码前思考
- 简洁优先
- 精准修改
- 目标驱动执行
这 4 点看起来很简单,但如果真的落实到 AI 编程工作流里,会极大改变 AI 的行为方式。
四、原则一:编码前思考
第一条是:
不要假设,不要隐藏困惑,要呈现权衡。
很多时候,我们给 AI 的需求其实并不完整。
比如你说:
帮我修复登录失败的问题。
这句话对人来说,也需要继续问:
- 是哪个登录方式?
- 失败表现是什么?
- 是接口失败,还是页面跳转失败?
- 是所有用户失败,还是部分用户失败?
- 最近有没有改过相关代码?
但 AI 很容易直接开始猜。
它可能看到了一个 LoginActivity,然后就开始修改。
它可能看到一个 token 判断,就认为问题出在 token 失效。
它可能看到一个空指针风险,就直接加判空。
结果改完之后,真正的问题还在,甚至引入了新问题。
所以“编码前思考”的价值就是:
先把问题想清楚,再动代码。
一个好的 AI 编程助手,在面对不确定问题时,应该先说:
- 我看到这里可能有两种原因;
- 我需要先确认一下调用链;
- 这个改法有风险,可能影响旧流程;
- 更简单的方式是先加日志定位,而不是直接重构;
- 如果目标只是修 Bug,不建议顺手改架构。
这才像一个靠谱的工程师。
不是一上来就写代码,而是先判断问题边界。
五、原则二:简洁优先
第二条是:
用最少的代码解决问题,不要过度推测。
这一点我特别有共鸣。
很多 AI 写代码时,最大的问题不是写得少,而是写得太多。
一个简单的按钮防重复点击,它可能给你写一个通用防抖框架。
一个简单的错误提示,它可能给你设计一套 ErrorHandler。
一个一次性的转换逻辑,它可能给你抽象出接口、实现类、枚举、配置项。
看起来很高级,实际上很麻烦。
项目 README 里提到,不要添加需求之外的功能,不要为一次性代码创建抽象,不要添加没有要求的“灵活性”和“可配置性”。:contentReference[oaicite:2]{index=2}
这句话非常适合贴在每个 AI 编程工具的提示词里。
因为很多项目不是死于代码太少,而是死于代码太复杂。
尤其是老项目。
比如 Android 老项目里,本来就有很多历史逻辑、兼容逻辑、业务分支。
你让 AI 一顿“现代化重构”,很可能短期看起来代码变漂亮了,长期却让维护成本更高。
所以我现在更喜欢给 AI 这样的要求:
只用当前项目已有的写法解决问题,不要引入新的架构,不要新增不必要的抽象。
这句话非常重要。
因为 AI 默认喜欢“发挥”。
但真实项目里,我们很多时候不需要它发挥。
我们需要它克制。
六、原则三:精准修改
第三条是:
只碰必须碰的代码。
这一点对企业项目特别重要。
在真实开发中,很多代码不是你看起来“不优雅”就能改的。
可能某个奇怪判断,是为了兼容旧版本。
可能某个看起来多余的字段,是给后端历史接口用的。
可能某个重复逻辑,是因为两个渠道的业务规则看似相同,实际不同。
如果 AI 没理解这些背景,却顺手帮你“优化”,那风险就很大。
README 里明确说,编辑现有代码时,不要改进相邻代码、注释或格式;不要重构没坏的东西;要匹配现有风格;如果发现无关死代码,可以提出来,但不要直接删除。:contentReference[oaicite:3]{index=3}
这其实就是一句话:
不要做和任务无关的改动。
这个原则非常适合用于代码审查。
以后我们看 AI 生成的 diff,不应该只看“它有没有实现功能”,还要看:
- 有没有改到无关文件?
- 有没有顺手重构?
- 有没有修改格式造成大面积 diff?
- 有没有删除它不理解的旧代码?
- 每一行修改是否都能对应到本次需求?
如果不能对应,那就应该警惕。
AI 不是不能重构。
而是重构必须是明确任务。
不能把“修 Bug”变成“顺便重构”。
七、原则四:目标驱动执行
第四条是:
定义成功标准,然后循环验证直到达成。
这可能是整个项目里最值得学习的一点。
很多人给 AI 下指令,习惯说:
帮我修复这个 Bug。
但这句话太模糊了。
什么叫修复?
编译通过算修复吗?
页面不崩溃算修复吗?
测试通过算修复吗?
线上场景不再复现算修复吗?
如果没有成功标准,AI 就只能猜。
更好的方式是:
先写一个能复现这个 Bug 的测试或最小验证步骤,然后修改代码,直到这个测试通过,并确认没有影响原有测试。
这就是目标驱动。
不是告诉 AI “做什么动作”,而是告诉它“做到什么结果”。
README 里也提到,强有力的成功标准能让 LLM 独立循环执行,而弱标准,比如“让它工作”,则会导致不断澄清。:contentReference[oaicite:4]{index=4}
这个思路对我们使用 AI 非常重要。
因为 AI 很擅长循环执行。
但前提是你要给它一个明确的终点。
比如:
不要说:
优化这个页面。
而是说:
在不改变现有接口和页面结构的前提下,把这个页面首次渲染耗时从 800ms 降到 500ms 以内,并给出前后对比数据。
不要说:
修复支付异常。
而是说:
复现微信支付返回失败但页面仍显示成功的问题,定位原因,修改后确保失败场景展示失败提示,成功场景不受影响,并补充对应验证步骤。
这就是 AI 能听懂、也能执行的目标。
八、为什么我觉得这套规则特别适合技术人?
因为它不是一套“炫技 Prompt”。
它更像是一套“AI 编程纪律”。
现在很多人使用 AI,有一个误区:
以为 AI 越主动越好。
但在真实工程里,AI 太主动反而危险。
我们真正需要的是:
- 它能主动思考,但不要擅自决定;
- 它能提出方案,但不要隐藏权衡;
- 它能写代码,但不要过度工程;
- 它能修改项目,但不要乱碰无关代码;
- 它能循环执行,但必须围绕明确目标。
这套规则,本质上是在把 AI 从“代码生成器”训练成“工程协作者”。
代码生成器只负责输出。
工程协作者要考虑边界、成本、风险、验证和可维护性。
这就是差别。
九、对 Android 开发者有什么启发?
如果你是 Android 开发者,这套规则特别值得用。
因为 Android 项目通常有几个特点:
第一,历史代码多。
很多项目已经迭代多年,里面有大量老逻辑。
第二,业务场景复杂。
登录、支付、实名、WebView、相机、文件下载、权限、推送、渠道包,每一个模块都可能有历史坑。
第三,兼容成本高。
不同 Android 版本、不同厂商 ROM、不同权限策略,都可能导致行为差异。
第四,AI 很容易误判。
它看到一个旧写法,可能会直接建议你改成新写法。
但这个旧写法可能正是为了兼容某个特殊场景。
所以,在 Android 项目里使用 AI,最好给它明确规则:
请遵循以下原则:
1. 修改前先说明你的理解、假设和风险;
2. 只修改与本需求直接相关的代码;
3. 不要顺手重构无关逻辑;
4. 不要引入新的架构或第三方库,除非我明确要求;
5. 优先匹配当前项目已有代码风格;
6. 修改完成后给出验证步骤;
7. 如果存在不确定点,先提出来,不要直接猜。