我在编程和写作时不断使用 AI。我用它来研究想法、规划代码、调试、探索不熟悉的 API、审查架构、生成测试、解释奇怪的行为,以及比手动更快地写出大段代码。
我也认为它可能让你编程能力变差。
这两种说法并不矛盾。
问题不在于 AI 写代码。问题在于 AI 可能移除编程中那些迫使我们记忆、推理、挣扎并形成心智模型的部分。如果我们过于频繁地把这些部分外包出去,我们的技能就会生疏。
所以我一直在思考一个问题,它比争论开发者是否应该使用 AI 有用得多:
我们如何大量使用 AI,同时又不让自己的能力退化?
我不认为答案是少用 AI。最好的方法是有意识地使用 AI。
危险的部分不是生成的代码
开发者一直在使用抽象和工具。有人可能会说,库削弱了我们从零开始、不依赖样板代码编写一切的能力。但我们经常使用自动补全、文档、Stack Overflow、linter、框架、调试器、IDE,以及由比我们更聪明的人构建的代码审查。
没人会期望一个 Web 开发者在被允许使用fetch()之前手动实现 TCP。AI 只是另一种抽象。
但有一个关键区别:大多数传统工具移除的是机械性工作。AI 可能移除的是思考。
考虑这两种交互之间的区别:
版本 A(手动调试)
- 你遇到一个 bug,并阅读错误信息。
- 你检查相关代码并形成一个假设。
- 你测试它——结果你错了。
- 你再次检查状态。
- 你最终发现,一个
forEach()循环里的异步回调没有被 await。
这个过程可能花 20 分钟。但到最后,你已经建立了关于 JavaScript 中异步执行如何工作的持久心智模型。
版本 B(委托调试)
- 你把函数粘贴到 AI 模型里:"修好这个。"
- 五秒后:
const users = await Promise.all(
ids.map(async id => {
const response = await fetch(`/api/users/${id}`);
return response.json();
})
);
- 它奏效了。你继续往下走。你没有花时间翻遍三年前的 Stack Overflow 帖子,试图弄清楚为什么你的代码会失败。
在版本 B中,生产力大幅提升——但学习可能趋近于零。我自己也犯过这个毛病,变得过于依赖Ctrl+C&Ctrl+V。
权衡取舍:摩擦并不总是浪费时间。编程中一些令人烦躁的部分,其实在暗中迫使你的大脑去检索和处理信息。
10 个保持敏锐的刻意策略
如果便利和学习并不总是一致,解决办法不是让编程重新变得人为地痛苦。而是要决定哪些摩擦是有价值的并主动保留它。
1. 在问 AI 之前先做预测
这是最容易养成的习惯。在把 bug 或堆栈跟踪发给 AI 模型之前,停 30 秒,问自己:我认为正在发生什么?
示例: “我认为这个状态更新重新触发了 effect,因为依赖数组在每次渲染时都改变了引用。”
现在当你向 AI 提问时,你不是在被动接收答案——你是在用证据检验一个心智模型。识别比回忆容易得多;没有预测,很容易读到一个自信的解释,心想“嗯,有道理,”然后立刻忘掉。
2. 先要解释,再要解决方案
不要这样提问:
❌“修复这段代码。”
试着这样提问:
💡“解释是什么导致了这个 bug。先别修。”
💡“给我三个可能的原因,并告诉我什么证据能区分它们。”
💡“带我走一遍你会如何在不改代码的情况下调试这个问题。”
这把 AI 从代码自动贩卖机变成了调试伙伴。
3. 不要立刻复制生成的代码
复制很快,但当某个概念很重要时,读完生成的解决方案,关掉 AI 标签页,然后自己实现这个想法。
如果 AI 建议引入状态机、抽取服务,或添加记忆化层,重新实现它会迫使你把核心概念转化为自己的心智模型。这比复制粘贴更难——而这正是它有效的原因。
4. 把 AI 当作审查者,而非作者
最有效的工作流之一:
- 你来写实现。
- AI 来审查它。
- 你来决定哪些反馈重要。
Review this function for correctness, readability, edge cases, and unnecessary complexity.
Don't rewrite it unless necessary.
这让你在使用 AI 作为自动化的第二双眼睛时,仍然对生成解决方案负责。
5. 让自己解释生成的代码
拿一段 AI 生成的代码,问自己:“我能在同行代码评审中解释这里的每一行吗?”
如果答案是否定的,那你就在背负自己并不理解的技术债。继续追问:
- 为什么需要这个特定的依赖?
- 这个检查保护的是什么不变量?
- 如果两个网络请求同时执行会发生什么?
一直追问下去,直到这个实现不再感觉像魔法。
6. 保留一些不依赖 AI 的任务
你不需要彻底戒掉 AI 一个月。但短暂、无辅助的时间段很有启发性:
- 不用自动补全写一个工具函数。
- 自己调试一个小问题,使用
console.log或断点调试器。 - 在问模型怎么想之前,先在纸上勾勒出架构。
把它想象成测试备份。你不会希望第一次发现自己离开 AI 就不会写代码,是在一场现场面试、一次故障或一次关键系统崩溃的时候。
7. 让 AI 根据你的弱点出练习题
当你注意到自己反复向 AI 询问同样的主题——比如async/await、SQL 连接、React 生命周期或 Git rebase——就用这些数据来训练自己:
“我已经多次需要异步 JavaScript 状态方面的帮助。给我三道难度递增的练习题,测试我是否真正理解它。除非我要求,否则不要给我答案。”
现在你的助手变成了个性化的导师,而不是拐杖。
8. 区分“我能理解这个”和“我能产出这个”
掌握有多个层次:
- 认出一个正确的解决方案。
- 在别人解释时理解一个解决方案。
- 修改一个已有的解决方案。
- 借助文档产出一个解决方案。
- 凭记忆产出一个解决方案。
- 把概念教给别人。
AI 让第 1 层和第 2 层变得毫不费力,制造出一种我们已经达到第 4 层或第 5 层的错觉。认清自己真实的能力边界在哪里,可以防止过度自信。
9. 不要过早外包架构
如果你开始做一个功能时做的第一件事就是向 AI 提问“我应该如何架构这个?”,你就跳过了关键的初始设计阶段。先回答这些问题:
- 这个状态由谁拥有?
- 需要存在哪些边界?
- 能起作用的最简单实现是什么?
一旦你有了草稿,就把 AI 引入进来:“这是我正在考虑的架构。我遗漏了哪些边缘情况或结构性缺陷?”
10. 把责任留在键盘的这一侧
如果你交付 AI 生成的代码,它仍然是你的代码。
当生产环境在凌晨 2 点崩溃时,模型不会被呼叫。它不会向利益相关者捍卫架构。它不会在六个月后维护这个代码库。而你会。
当你对自己交付的一切负责时,生成的代码就不再是一个绝对的答案,而变成了一个需要被批判性评估的提案。
结论
未来不属于拒绝使用 AI 的开发者,也不属于盲目把每一个想法都委托给 AI 的开发者。
真正的技能在于知道哪里该自动化,哪里该思考。
让 AI 消除样板代码、搜索陌生的领域、解释复杂的概念,并审查你的工作。但偶尔,让你的大脑去做那些繁重的工作:预测、回忆、调试、设计,以及解释。
工具提升我们的产出,但理解提升我们的能力。目标不只是因为 AI 能构建就去构建——而是去构建我们以前无法构建的东西,同时比开始时理解得更多。