能跑起来就是成功吗?聊聊 AI 编程时代容易被忽略的工程常识

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 可以帮你回答,但不能替你承担判断。

当代码已经不再稀缺的时候,知道该写什么、为什么这么写,以及什么时候根本不该写,可能才是更重要的能力。

4 个赞

简单地说,就是自己作为最高层的planer。

楼主说的有道理,但是不能完全赞成.
古法编程的经验很丰富,但是vibe coding的经验不够丰富,观念未免有失偏颇
模型够强,那问题就会变少,解决问题的能力也就变强.
强到一定程度的时候,用户就可以当不懂技术的manager了(当然现在确实没有到这个阶段,但是agent也没有那么不堪)技术债和屎山是永远都有的

1 个赞

我承认自己没有深入使用过 Agent,所以这里暂且不讨论 Agent 当前具体能做到什么程度。

模型能力持续提升这一点我完全认可。如果只是个人项目,代码质量、架构选择甚至后续维护成本,本质上都是自己承担,确实可以更倾向于效率优先。

但如果项目是公开发布,甚至涉及商业化,就会引入另一个问题:工程责任。

开发者无法预知所有用户的使用方式,也无法保证 AI 生成的方案在所有边界条件下都可靠。小问题当然可以继续让 AI 修复,但如果涉及数据损坏、安全漏洞、服务中断等问题,事后修补的成本和影响可能不是简单修复代码能够解决的。

我觉得“未来人可以像 manager 一样管理 AI”这个方向是有可能的,但这里有一个前提:AI 需要具备足够完善的验证、测试、风险控制和责任闭环能力。

在这个前提实现之前,人仍然需要对 AI 生成的结果负责。因此我认为工程能力不会消失,只是重心可能会从“亲自写每一行代码”转向“设计系统、判断方案、验证结果和控制风险”。这也是我文章里想讨论的核心。

2 个赞

期待的文章居然这么快就端上来了。文章很长,但很好读,我直接一口气看完。

文章提到的编程基础、计算机基础、工程常识、调试能力,我觉得都很有用。问题就在于每一项展开都很大,少则一本书,多则本科几年的学习。

所以接下来看楼主怎么讲,是亲手做科普,还是指出一条适合 AI 编程的学习路径,让大家知道碰到什么问题,该补哪块知识。

这和以前学编程不一样的是,以前是为了自己写代码,而现在有 AI 参与,重点是能看懂、判断、排查和验证。

楼上有人担心楼主 Vibe Coding 经验不够多,我觉得这个要求没必要拉这么满,不用要求一个作者把这个领域讲得完全正确、完整。只要他讲的东西有用,也把自己的经验边界说清楚,从他的视角给出一条可参考的路径,就很有价值。

至于以后模型将会发展得足够聪明,让不懂技术的普通人也能像 manager 一样指挥 AI 把软件做好,我觉得这个可能性可以保留。什么时候能到,不知道。至少现在还没到。

这个系列我继续蹲。

:doge: 个人观点:只要有能对代码负责的人,那就是“合格”的代码;只要有能对程序运行结果负责的人,那就是“合格”的程序。

写写简单小脚本我会全用ai,写其他的我也排斥vibe,我无法对我使用ai生成的代码以及运行后果负责。

1 个赞

感谢支持

我 Vibe Coding 经验不足确实是事实,基本还停留在对话写代码的阶段;而且作为非科班出身,古法编程的经验也算不上有很多,也就只是各种技术栈都或多或少接触过,像Web(原生 js html php)、桌面(aardio python golang C++),做过几个小项目而已。

但正因如此,我能够提供一个非常宝贵的视角,讲述一个野生开发者如何在实践中摸索出自己的一套方法论,而这套方法论早在 Vibe Coding 出现前就成型了

有个感受:AI 把「写出来」的成本打下来了,但「判断对不对」的成本反而上去了。能看懂、敢负责、出了问题能兜底的人,价值反而更高了。

我只用gemini帮忙写一些函数,还没遇到什么问题…
程序的架构全都是自己一手掌控,ai就负责打杂(况且也没有ai能帮我免费干这个)

1 个赞

看完感觉楼主其实主要还是在讨论 AI 早期那种 Vibe Coding。你提到的那些坑,像是AI 乱改、堆技术债、只看眼前需求、出了问题就继续让 AI 猜等等等。这些我都很赞同。

但现在 AI Agent 这边已经开始往另一套玩法走了。像 Matt Pocock 那套 skills,已经把 grilling、domain modeling、spec、ticket、TDD、debug、code review、深模块维护这些东西都塞进 Agent workflow 里了。

所以现在单纯粗暴地让 AI “帮我写个功能”,和让 Agent 按照一套工程流程把这个功能做完,实际体验差很多。前一种很容易 Vibe,后一种至少会逼着它留上下文、做验证、跑测试、根据反馈继续改。效果实在不对的时候,还可以直接换一个干净上下文窗口重新来,让模型重新检索和理解一遍,反而能避开前面一路积累下来的错误上下文。

当然如果需求本身错了,Agent 可以非常认真地把错东西做得看起来是的对的。例如工程约束写错了,它也会照着执行,这种时候还是需要楼主说的那种工程常识来兜底,不然错的东西做得再漂亮也还是错的。

所以我现在觉得,AI Coding 的门槛正在慢慢从“会不会写代码”转到“会不会给 Agent 建立一个靠谱的工程环境”。把现在的 Agent + Skills 也算进去的话,感觉楼主对于 Vibe Coding 问题的审视还是可以再往前看一步。

是的,我只有早期 Vibe Coding 的经验,观点肯定有局限性。

不过我从来没有否定过它,只是单纯因为个人立场比较抵触而已

老项目有历史包袱,直接换成一套 Agent + Skills 的工作方式,成本和风险都不低。新项目就没这个问题,正好可以从需求、spec、context、skills 到测试、review,整套在 Agent 里跑一遍,看看实际效果。

我觉得这类东西挺适合也非常值得去拿真实项目去验证,光看文章、评论或者看别人演示其实很难判断到底有没有用。尤其是干净的上下文窗口、skills 这些东西,真正用起来以后,跟单纯聊天让 AI 写代码的区别还是挺明显的。

最后能不能跑通、能不能维护,再用项目结果说话就行。看看最后能不能说服自己。

总的来说,AI需要的是你从0-1搭出来一个框架,他朝里面当裱糊匠还是很专业的,但是要让AI自己去搭框架,以当前AI的能力(也可能是我没用过超贵的顶级AI),总是容易写出一团不知道是啥的东西……

好奇两个问题:
1、以上这些能不能用一个skill让agent自己完成?
2、不同模型写出来的能跑通的代码质量差别有多大?

用 Django 没毛病。它并不是一个非常重的 Web 框架。模块化做得非常好,你不用的功能就不需要为付出代价。而且默认的安全性吊打一切 Web 构架包括其它语言的。小项目你本来就没几个 QPS 用啥都没错。重业务的也非常需要它的 migrations. 想高并发的话,用 Django 也没错,只要去掉从 django settings 里面去掉 session app 或者写中间件对于特定 URL bypass 掉 session 读写,用单机把 QPS 拉到 1000+ 也不是问题。

现在的 AI 的在审美和经验经常比五年以内的程序员强不少。可以说,从古法编程时代走过来的五年经验程序员,已经价值归零了。这就是最近程序员大规模失业的一个重要原因。

这次 AI 浪潮,会让不少小众的技术栈消失,因为以前很多小众技术栈想要解决的入门难、门槛高等等问题,在 AI 面前根本不是问题。反而是正确性、稳定性、正交性会决定性吸纳 AI 来采用。

这么说吧,C# 和 TypeScript 这种为了让人类写得爽的编程语言,会在三年内被淘汰——既然代码是 AI 写的,那写得爽就不再是卖点。