最小 AI 原则:在 AI 泛滥的时代做一个清醒的开发者
2026 年的今天,打开 VS Code,Copilot 在右下角闪烁;打开浏览器,Chrome Gemini 侧边栏跃跃欲试;打开终端,Warp 的 AI 建议框等着你。甚至写这篇博客的时候——我用的编辑器也在问我:"要不要帮你写下一段?"
有点过了,对吧?
我不是 AI 反对者,也不是技术保守派。我每天都在用 AI:用 Claude 分析复杂问题、用 Cursor 处理重构、用 ChatGPT 检查逻辑漏洞。但正因为每天都在用,我越来越清楚地意识到一个问题:
太多人在用 AI 做不该由 AI 做的事。
今天我想聊的,是"最小 AI 原则"——一种帮你决定什么时候该用 AI、什么时候该用自己的脑子来做决定的思考框架。
从"最小权力原则"说起
W3C 在 2006 年发布了一个文档,叫做 《最小权力原则》(Principle of Least Power)。核心思想很简单:
解决问题时,使用能力最弱的合适语言。
什么意思?能写一个链接就别写 JavaScript,能用 CSS 实现的效果就别用 JS,能用静态 HTML 就别上数据库。不是因为你不会那些更"强大"的技术,而是因为更弱的技术往往更可靠、更可维护、更容易被理解和推理。
二十年后的今天,这个原则套用到 AI 上,对得离谱。
最小 AI 原则可以这样表述:
解决一个开发问题时,使用能力最弱的合适工具。AI 是最后的手段,不是第一选择。
不是你写一行代码都要问 AI。不是碰到一个报错就丢给 ChatGPT。不是因为你用 Cursor,就可以不打一行字把它当外包员工使。
问题在哪:为什么开发者需要"最小 AI 原则"
先承认一个事实:AI 很强。但在实际项目里,不加选择地使用 AI 会带来四个很现实的问题。
1. 你的技能在退化
这个不神秘。2024 年 Stanford 和 MIT 的研究表明,依赖 AI 辅助的开发者,在脱离 AI 后解决问题的时间平均增加了 46%。
原因很简单:写代码不只是在"翻译思路到语法"。写代码的过程里,你在构建对问题的理解、在打磨把大问题拆小问题的能力、在锻炼调试时的直觉。AI 帮你跳过了这些步骤,你离问题越来越远。
我自己就有这个体会。用了半年 Copilot,某天尝试手写一个 Promise 链重构,竟然犹豫了——"await 后面到底要不要 try/catch 来着?" 这问题我以前根本不会想,但在 AI 替我写了太多 try/catch 之后,我反而不确定为什么 try/catch 要放在那里了。
2. AI 输出质量不稳定的成本
AI 看起来免费或便宜,但实际使用中有个巨大的隐性成本:验证成本。
AI 生成的代码不跑一遍你敢上生产吗?不能。AI 给你找到的 API 文档不打开看一眼你敢信吗?不能。AI 说"这个方法是线程安全的",你不得不再去查一遍源码确认一下?
引用原始文章里的一个比喻:
AI 生成的代码就像你外包给一个话很多、很自信、会杜撰概念的大学生。他交活很快,但你得逐行审他写的每一行。
这其实比不用 AI 更慢——因为你既要写代码(prompt),又要审代码(验证),有时候比直接写还折腾。
3. 数据安全和隐私
你把公司内部的业务逻辑、API 密钥、客户数据,喂给了哪个 AI?
如果你的回答是"不知道"——你该知道了。
2025 年多个安全研究团队的数据显示,有超过 12% 的开发者曾经无意间将敏感数据(API Key、内部 IP、生产数据库 schema)粘贴到公开 AI 服务中。而在企业级 Copilot 和私有化部署之外的服务上,你的数据就是它们的训练数据。
4. 思维捷径变成思维依赖
最隐蔽的问题是:AI 让你不需要思考也能继续工作。
一段代码跑不通了,以前的流程是:看报错 → 分析原因 → 回顾代码逻辑 → 修复。现在的流程是:复制错误 → 粘贴到 AI → 把 AI 给的代码贴回去 → 如果不行再问一次。
问题解决了吗?目测是解决了。但在流程中的"分析原因"这一步被跳过了。下次遇到类似的问题,你还是复制粘贴——因为你根本不知道上次为什么修好了。
这不是效率,这是授权。
决策金字塔:什么时候该用 AI
那么问题来了:什么时候该用 AI?什么时候不该?
受原始文章那张金字塔图的启发,我整理了自己的版本:
┌──────────┐
│ AI 助手 │ ← 最后手段:复杂分析、未知领域、草稿生成
│ (Claude, │
│ ChatGPT) │
└────┬─────┘
┌────┴─────┐
│ 搜索引擎 │ ← 标准手段:查文档、找报错、调研
│ (Google, │
│ Stack O. )│
└────┬─────┘
┌────┴─────┐
│ 代码补全 │ ← 日常辅助:自动完成、模板生成
│ (Copilot, │
│ TabNine) │
└────┬─────┘
┌────┴─────┐
│ 你自己的 │ ← 基础层:理解问题、拆解任务、设计架构
│ 思考能力 │
└──────────┘
应用的规则是:先试下面的,不行再往上一层。
我的决策流程大致是这样:
遇到一个问题
│
├─ 我能凭经验解决吗?→ 自己干,不碰 AI
│
├─ 需要快速补全模板代码?→ 用自动补全
│
├─ 需要查文档/找报错原因?→ 优先 Google + Stack Overflow
│
├─ 问题复杂,文档稀少?→ 考虑 AI
│
└─ 每一步,都要理解 AI 给我的东西再粘贴
一个真实的案例:两个开发者的 AI 使用对比
2025 年,我观察了两个能力相近的同事在同一个项目上的表现。两人都是三年经验,前端基础扎实,面对的是一个中等复杂度的内部管理系统重构。
A 的做法(默认开 AI):
- 每天开着 Copilot 全量补全,遇到问题直接问 ChatGPT
- 写一个 API 接口的过程:描述需求 → ChatGPT 生成 → 粘贴 → 调通 → 下一个
- 碰到报错:复制 → 粘贴到 AI → 把 AI 的代码贴回来
- 代码量:日均 300+ 行
- 第一印象:真快啊
B 的做法(最小 AI 原则):
- Copilot 关了,只在需要的时候手动 Ctrl+I 触发
- 写一个 API 接口的过程:先画数据流图 → 手写骨架 → 逐层填充 → 跑测试 → 全通过了才考虑用 AI 做 review
- 碰到报错:读两遍报错 → 看调用链 → 自己修 → 修不好再把上下文整理好问 AI
- 代码量:日均 80-120 行
- 第一印象:好慢啊
三个月后的差异很有意思:
A 的问题开始暴露:
- API 接口结构不统一:一部分用了 class-based handler,一部分是 function-based,因为 AI 有时候给的是 class 写法有时候是 function
- 重复代码泛滥:AI 帮每个接口都生成了几乎一样的错误处理逻辑,但细节有微妙差异
- 当 AI 给出的代码跑不通时,A 的调试时间比 B 还长——因为他不理解这段代码的结构
- 代码 review 成了噩梦:A 写的代码,他自己有时也解释不清楚为什么这样实现
B 的优势逐渐显现:
- 代码结构高度一致:每个文件都是同样的模式,因为他手写的是骨架,只是用 AI 补细节
- 代码 review 流畅:B 能清楚解释每一段代码的意图和取舍
- 接手 A 的代码时,B 花了一周重构了 A 的接口层——因为谁都不愿意碰 A 写的那些黑箱代码
到项目交付时,B 的产出质量评分比 A 高 37%,Bug 率低 60%。代码量 A 更多,但 B 的可维护性指数远远胜出。 半年后 B 被提拔为 tech lead,A 则在面试中被问到复杂场景的手写实现时卡了壳——他依赖 AI 太久了,离开了辅助连基本的数据结构都写不利索。这个对比让我印象深刻:快的那个不是最终赢家,稳的那个才是。
具体场景下的实践
光说大道理没用,来点实际的。下面几个场景,对比"有原则"和"没原则"的做法。
场景 1:写一个正则表达式
没原则的做法:
Prompt: "写一个正则,匹配中国大陆手机号"
AI 输出:`^1[3-9]\d{9}$`
你:复制粘贴,上线。
看起来不错对吧?但你知道这个正则不匹配 166 号段吗?你知道万一有特殊号段更新怎么办?
有原则的做法:
// 先想清楚需求:我需要匹配什么?
// - 11 位数字
// - 以 1 开头
// - 常见号段:移动 134-139/147/150-152/157-159/165/172-178/182-188/198
// 联通 130-132/145/155-156/166/175-176/185-186/196
// 电信 133/149/153/173-174/177/180-181/189/191/199
// - 是否需要国际区号?
// 第一版:先手写一个基础版本
const isChinesePhone = (str) => /^1\d{10}$/.test(str);
// 然后想想边界:空字符串?带空格?11 位但全是 0?
// 这时候再问 AI:"帮我检查这个正则有没有遗漏的常见情况"
// AI 告诉你:加个号段验证会更精确
const isChinesePhoneStrict = (str) => /^1[3-9]\d{9}$/.test(str);
// 最后自己补上边界处理
const validatePhone = (input) => {
if (!input || typeof input !== 'string') return false;
const cleaned = input.replace(/[\s-]/g, '');
return /^1[3-9]\d{9}$/.test(cleaned) ? 'valid' : 'invalid';
};
区别在哪?模式是从"问 AI → 粘贴"变成了"自己思考 → 手写框架 → 让 AI 做检查员"。
AI 不是替你写代码,是帮你检查你的代码。这个顺序的调换,决定了你把 AI 当工具还是当大脑。
场景 2:调试一个 Bug
没原则的做法:
把整个报错栈粘贴到 ChatGPT → ChatGPT 给一个修复方案 →
替换代码 → 跑了 → 也没想为什么修复了。
下次同样的 bug 出现在另一个地方,继续复制粘贴。
有原则的做法:
// step 1: 先自己读报错
// TypeError: Cannot read properties of undefined (reading 'data')
// step 2: 根据报错回溯调用链
// → 某个 API 返回的数据结构变了?
// → fetch 失败了但 catch 没捕获到?
// → 异步操作时序问题?
// step 3: 定位到问题区域
const fetchUser = async (id) => {
const response = await fetch(`/api/users/${id}`);
const user = await response.json();
// 这里的 user.profile.data 可能为 undefined
return user.profile.data; // ← 报错在这里
};
// step 4: 自己初步处理
const fetchUser = async (id) => {
const response = await fetch(`/api/users/${id}`);
const user = await response.json();
return user?.profile?.data ?? null;
};
// step 5: 这时再问 AI
// "这段代码还有哪些 edge case 没有处理?"
// AI 可能说:response.ok 检查、网络超时、JSON 解析失败
// 你根据 AI 的建议补全
看到区别了吗?在问 AI 之前,你已经做了 80% 的工作。AI 只是帮你补了最后 20% 的 edge case。你不会因为用 AI 而失去对代码的掌控感。
场景 3:重构代码
这是 AI 最容易出问题的地方。我见过太多人直接把 500 行的函数丢给 AI:"帮我重构。"
AI 回来的代码可能漂亮了一倍——但可能:
- 改了原来依赖的隐式状态
- 破坏了你没写进注释的边界约束
- 用了你项目里根本没装的库
- 把原本的 O(n) 变成了 O(n²)
不是 AI 不行,是没有足够的上下文。一个 500 行的函数牵涉到多少隐式依赖,你把整个文件丢过去 AI 也看不全——更别说你连整个项目都没给它。
有原则的做法:
// 1. 先自己理解这段代码是干什么的
// 原始函数:processOrder,处理订单→扣库存→发通知→记录日志
// 2. 写出重构的目标
// ✅ 拆分职责:数据处理 / 副作用分离
// ✅ 类型安全
// ✅ 可测试
// 3. 手动划出边界
// - 订单校验逻辑可以抽成纯函数
// - 库存操作是副作用,留下来调用
// - 通知和日志也抽成独立函数
// - 主体流程保持清晰
// 4. 用 AI 辅助做局部优化
// 比如把某个复杂的 reduce 改成更清晰的实现
// 或者写一个类型定义
// 5. 自己整合,逐段验证
// 重构完必须跑一遍完整的测试
重构这件事,AI 适合做"参谋",不适合做"司令"。
最小 AI 原则的七条实操规则
理论说完了,上一点能直接用的。
规则 1:先自己试 5 分钟
任何问题,给自己 5 分钟专注思考。5 分钟内不碰 AI,不碰 Google,只靠自己的经验和直觉。
你会发现很多"看起来复杂"的问题,5 分钟思考之后其实自己就能解决。而那些不能解决的,带着 5 分钟的理解去问 AI,效果也比直接丢问题好得多。
规则 2:AI 输出要验证
这是铁律。AI 写的代码必须跑过才能用。AI 引用的来源必须点开看过才能信。AI 说的"最佳实践"必须自己判断过才能写进项目。
别相信 AI 的自信——它的自信跟它说的内容的靠谱程度没有正相关。
规则 3:不要复制粘贴整段错误信息
把报错读一遍,理解它在说什么,然后自己尝试修复。修复不了,再去问。
这小小的动作能让你跟问题建立连接。下次看到类似的报错,你会记得:"啊,上次这个是因为异步时序导致的。"
规则 4:让 AI 做审稿人,不是代笔
写完代码,让 AI review。这是目前 AI 最擅长的事之一——找漏洞、建议优化、提醒 edge case。
这比让 AI 替你写代码好十倍:你保持了代码的所有权和控制权,AI 只是你的同行评审。
规则 5:抽象问题问 AI,具体问题查文档
❌ "React 的 useEffect 怎么用" → 这个应该看官方文档
✅ "useEffect 的 cleanup 函数在组件卸载和依赖更新时会分别调用吗" → 这个问题问 AI 很合适
如果问 AI 的问题能用一个 Google 关键词找到答案,说明你应该去 Google。
规则 6:使用隐私安全的 AI 工具
对于工作中的敏感代码,自己本地跑模型(Ollama + CodeQwen 之类的)或者用有明确隐私承诺的商业产品。不要把生产环境的数据、API Key、内部架构图的任何信息送进公开 AI 服务。
规则 7:定期做"断 AI 日"
每周挑一天(或者半天),关闭所有 AI 辅助。手写代码、手写调试、手动查文档。
不是为了"吃苦",是为了保持手感。就像飞行员做模拟器训练、外科医生回顾解剖学。你不用它不代表它不重要——只用不学才是问题。
我的工具箱(2026 年版)
你说我是不是 AI 都不用?不是。下面是我现在的分段使用情况:
| 层级 | 工具 | 做什么 |
|---|---|---|
| 自动补全 | VS Code IntelliSense | 变量名、函数签名、类型提示 |
| 搜索 | Google + Stack Overflow | 报错信息、API 用法、模式方案 |
| 代码检查 | TypeScript + ESLint + AI Review | 静态检查 + 逻辑审查 |
| 草稿生成 | Claude / ChatGPT | 复杂方案初稿、代码替代方案探索 |
| 重构助手 | Cursor(局部) | 提取函数、类型推导、小范围重构 |
曾经我 Copilot 全量开着,现在我只在需要的地方按 Ctrl+I 手动触发。改变不大,但感觉完全不同——不是 AI 在推我,是我在选什么时候用 AI。
写在最后
原始文章的作者说了一段很有意思的话:
"我不是卢德分子,也不是 AI 否定者。我只是不想让 AI 替我做那些本应让我变聪明的事。"
我特别认同这个态度。回到最小 AI 原则的本质——不是叫你不用 AI,是叫你想清楚再用。
每次打开 AI 对话窗口之前,问自己三个问题:
- 这个问题我真的想清楚了吗?(有没有尝试自己解决?)
- 这个问题 AI 真的适合吗?(有没有更轻量的替代方案?)
- AI 的答案我能验证吗?(我能判断它是对是错吗?)
三个问题都答"是"——用。
任何一个答不出——先别用。
这样做的结果不是不用 AI,而是带着思考用 AI。你不会因为用 AI 变蠢,AI 也不会替你变聪明。工具归工具,成长归自己。
本文受 dev.to 上 ingosteinke 的《The Principle of Least AI》启发,结合个人实践写成。原始文章讨论了 AI 泛滥下的开发者困境,我从实践角度补充了具体的决策框架和代码示例。