AI 让“写出一个程序”变得太容易了
手写过代码的人都知道那种一坐就是大半天的痛苦。
你以为的程序员:
成竹在胸,手指在键盘上翻飞,噼里啪啦敲代码,运行、调试、编译、发布一气呵成
实际上的程序员:
对着各种东西发呆,沉思半晌打开 Google 搜关键词,CV 大法抄代码,手动改一下,调试,然后——
诶?为什么语法检查不通过(少了缩进、括号)
啊?怎么这提示参数类型不对
嗯?xx 行怎么抛了个异常出来
(反复改,反复调试)
以前很多问题卡在“不会写代码”。
可能是不懂另一门语言,也可能是不知道某个功能究竟应该怎么实现。
现在有 AI 了,“再也不用”亲力亲为,甚至可以端杯茶坐在那看它写代码、反复调试。
最后它给你交付了一个能工作的版本。
收工~
于是出现一种很自然的开发模式:
有需求 → 问 AI → 复制代码 → 能跑 → 下一步
这种方式对于写自用的小工具非常有效。
但问题也恰恰从这里开始:“能跑”只是工程的起点。
“能跑”与“能用”不是一回事
什么叫能跑?
程序能够正常启动,在你当前的环境下正常实现需求,没有产生肉眼可见的报错——这就算能跑。
程序和程序员至少要有一个能跑
什么叫能用?
不妨从几个实际问题切入:
- 换一台电脑还能不能运行?(系统环境)
- 依赖没装怎么办?(运行环境)
- 输入异常怎么办?(用户操作)
- 网络断了怎么办?(网络通信)
- 权限不足怎么办?(访问权限)
- 软件运行久了会不会出问题?(资源管理)
- 出 Bug 之后还能不能定位?(调试与日志)
当然,不可能要求一个小工具把所有异常情况都考虑得面面俱到。
但至少应该对这些问题中的一部分有所意识,并根据实际需求做出取舍,才能逐渐从“写出了一个能跑的程序”,走向“写出了一个能用的程序”。
而这恰恰是 AI 编程时代容易被忽略的地方:
AI 很擅长解决“当前这个问题怎么实现”,但不一定主动替你考虑“这个东西以后怎么办”。
你得知道自己在让 AI 干什么
现在的确没有必要从头手写每一行代码。除非它足够简单到可以随手写
毕竟 AI 都已经把代码写出来了,这时候再自己对着键盘一顿输出,多少有点像:
AI:我已经给你把饭煮好了。
我:谢谢,但是我决定自己从种水稻开始。
但问题在于,你可以不亲自写代码,却不能完全不知道代码在干什么。
至少得知道一些基本的东西:
- 这个函数是干什么的?
- 为什么要引入这个库?
- 这段代码的数据从哪里来,又到哪里去?
- 为什么这里要这样处理?
- 出现问题的时候,应该怀疑哪一部分?
否则很容易出现这种情况:
“AI,帮我写一个采集 XX 网站内容的脚本。”
AI 哐哐写了一大堆。
能跑吗?能。
收工~
过了一段时间。
为什么上次还能用的,现在不行了?
让我看看代码,看看报错……
403是什么鬼啊
然后你发现:坏了,看不懂。
只能继续丢给 AI,让它自己改。烧了大量 Token 之后,问题还是没解决。
但假设你了解一些基本知识,有针对性地去提问,最后可能会发现:
原来只是对方屏蔽了你的 IP。
这其实不是 AI 编程本身的问题。
以前我们自己写代码的时候,至少会被迫理解自己写下的东西;现在代码可以由 AI 一次性生成,很容易直接跳过这个过程。
不是说需要重新成为一个能手写所有代码的程序员,而是最好成为一个看得懂自己项目的程序员。
这也是为什么我觉得,AI 编程时代反而更需要一些基础的编程知识。
不是为了和 AI 比谁打字快,而是为了在它一本正经地给你生成几百行代码的时候,你至少知道它到底在干什么。
不要把 AI 的技术方案当成标准答案
2024年我写过一个图片站的第三方客户端(闭源,开发过程以后有机会可以讲讲),当时使用的是 aardio(业务层)+ Webview2(展示层)。
代码基本上都是我自己写的,项目本身也并不复杂。最后编译打包出来,大概 2 MB 左右。
今年年初的时候有个人私信我,说因为我迟迟没做他想要的功能,所以自己用 Vibe Coding 模仿了一个。
然后我读了一下他给我发的源码(以下只是我的回忆,细节可能有出入)。
看到工程是 Python 的,我想:“Python生成起来简单,能理解”。
结果在项目里看到了 Django。我不懂,AI 告诉我这是一个“全功能 Web 开发框架”。
当时我整个人都被气笑了。不就是调用几个RESTful API、再做个前端展示图片嘛,犯得着上这么重量级的框架?
不仅如此,里面还充斥着各种冗余、意义不明的代码,甚至还有变量赋值之后就再也没被读取过的情况。
这放 Golang 里会被编译器喷成筛子
当然,这并不是说 Django 不好,也不是说代码越少就一定越好。
问题在于:技术方案应该和问题的规模匹配。
AI 经常能给出一套“看起来很完整”的方案。
但完整 ≠ 合适。
技术选型应该考虑:
- 项目规模
- 运行环境
- 依赖数量
- 部署方式
- 后期维护成本
- 实际需求
如果只是做一个简单的小工具,却因为 AI 给出的“标准方案”看起来专业,就顺手引入一整套复杂技术栈,最后很可能是:
为了修一个自行车轮胎,先建了一套汽车维修厂。
AI 给出的技术方案可以作为参考,甚至可以作为探索方向。但最终还是得问一句:
为什么我要用这个?
而不是:
AI 都这么写了,那应该就是这么写的吧?
AI 最容易制造的东西:技术债
Vibe Coding 的典型过程:
先加个功能。
AI 加几行。
再加一个。
继续修补。
直到最后:
- 重复代码越来越多
- 模块之间互相耦合
- 配置和逻辑混在一起
- 牵一发而动全身
单次修改可能都没什么问题,但项目整体却越来越难维护。
这也是 AI 编程很容易出现的问题:它很擅长解决眼前的问题,却不会天然替你维护整个项目的长期结构。
举个很简单的例子。
假设代码中有一个会被反复使用的 API URL,而它以后很可能需要修改。
如果没有提前告诉 AI 应该怎么组织,它很可能会直接把这个 URL 写进当前的业务逻辑里。
对 AI 来说,一处和几十处其实没有本质区别——当前需求能解决就行。
但人不一样。
当项目越来越大,你很难永远记住:
这个 URL 到底在哪些地方出现过?
哪天 API 地址发生变化,漏改一处,就可能直接导致某个功能悄悄失效。
这时候就体现出模块化和配置管理的价值了:
- 可以复用的逻辑集中到一个地方
- 经常变化的配置与业务逻辑分离
- 重复使用的变量统一管理
- 必要时使用配置文件或环境变量
这样修改 API URL 时,只需要改一个地方,而不是在整个项目里玩“大家来找茬”。
当然,模块化也不是越彻底越好。
如果一个只有几十行的小脚本,为了一个 URL 专门再抽象出三层配置、五个接口,那就又走向了另一个极端。
所以这里真正重要的不是“一定要模块化”。
而是要意识到代码除了今天能不能运行,还有明天能不能修改的问题。
而这恰恰是 Vibe Coding 最容易忽略的地方。
调试不是“让 AI 再改一次”
调试是写代码时必不可少的环节,如何用正确的姿势调试也很重要。
低效的做法:
报错 → 让 AI 自己调试 → 改代码 → 还是报错 → 再改。
更可靠的方式:
观察现象 → 提出假设 → 做实验调试 → 排除可能性 → 定位原因。
例如一个问题出现时,先判断根源来自:
- 配置?
- 自己的代码?
- 第三方库?
- 运行环境?
- 操作系统?
然后再让 AI 辅助分析。
举个之前遇到过的例子。
我曾经碰到过一个浏览器插件开发者,基本上是 Vibe Coding。这个项目有一个很有意思的问题:
从
www域名访问官网没问题,但直接从根域名访问时,页面里的 JS 加载失败,网站直接寄了。
我反馈这个问题时,还附上了控制台的报错截图(很明显的 CSP 策略配置错误)。
结果一开始对方的排查方向是:
- 清空缓存刷新一下?
- 检查一下是不是广告拦截扩展?
经我提醒才发现,问题其实出在 CSP(Content Security Policy)配置上。
网页打不开,可以有无数种可能。
但如果知道 CSP 是干什么的,再结合现象和控制台的提示,问题的范围一下就缩小了。
这就是为什么调试并不只是“看报错然后修代码”。
真正重要的是:从现象中提取信息,然后建立一个合理的排查路径。
AI 可以帮你分析报错,可以帮你查文档,可以帮你提出可能的原因,甚至可以帮你写一个用于验证假设的小测试。
但如果你自己完全不知道问题可能出在哪一层,那么 AI 很容易变成一个“这个也试试?那个也改改?”的随机改代码机器。
幽默的是,它真的有可能把问题改好,只是你不知道它为什么好了。
然后下次再遇到类似问题,依然只能重新问 AI。
知道什么时候不要改代码
有些问题根本不是代码问题:
- API 版本不对
- 配置错误
- 权限问题
- 环境问题
- 浏览器策略
- 需求本身没想清楚
这时候继续让 AI 生成代码,往往只会让项目越来越复杂。
所以遇到问题时,第一反应不是“让 AI 改代码”,而是先判断问题到底属于哪一层。
如果连问题出在哪里都还没搞清楚,就开始修改代码,很容易变成对着症状打补丁。
知道什么时候应该改代码很重要,知道什么时候不应该改代码,同样是一种工程能力。
AI 时代还需要学习编程吗?
说到这里,可能有人会问:
既然 AI 都能写代码了,那我们还学编程干什么?
我觉得答案其实很简单。
以后未必需要每个人都具备从零手写一个完整项目的能力,但至少应该知道一些基本的编程知识、计算机原理和工程常识。
不是为了和 AI 比谁写代码更快,也不是为了证明自己比 AI 更会写代码,而是为了:
- 看得懂 AI 生成的代码;
- 知道它为什么这么写;
- 判断它给出的方案是否合理;
- 出问题时知道应该从哪里查;
- 知道什么时候应该改代码,什么时候应该去查配置、文档或者运行环境。
AI 可以替你完成大量具体的实现工作,但问题怎么描述、方案怎么选择、结果怎么验证,以及出了问题之后该怎么排查,这些事情并不会因为 AI 会写代码就自动消失。
恰恰因为写代码变得如此廉价,这些能力反而显得更加重要。
写代码越来越容易,工程经验反而越来越重要
虽然我本人比较抵触 Vibe Coding,但并不认为 Vibe Coding 是一件坏事。
恰恰相反,它把过去大量机械性的工作交给了 AI,让一个有想法的人可以非常快地把东西做出来。
以前可能要花半天搜索资料、抄代码、改参数、处理语法错误;现在把需求描述清楚,AI 很可能几分钟就能给你一个能跑的版本。
这本身就是非常巨大的进步。
但“能跑”只是起点。
当项目从几十行变成几千行,从自己用变成给别人用,从一次性脚本变成需要长期维护的软件,真正需要考虑的东西就会越来越多:
- 它为什么这么设计?
- 换个环境还能不能运行?
- 出问题了怎么定位?
- 以后改起来会不会很痛苦?
- 这个方案到底有没有必要这么复杂?
这些问题,AI 可以帮你回答,但不能替你承担判断。
当代码已经不再稀缺的时候,知道该写什么、为什么这么写,以及什么时候根本不该写,可能才是更重要的能力。