即刻App年轻人的同好社区
下载
App内打开
小盖fun
1天前
强烈安利这个讨论 AI Coding 方法的演讲。

AI Coding 工具正在同时被过度低估和过度吹捧。

关于 Vibe Coding,看到的都是类似的说辞:编程已经没有门槛,用自然语言说出自己的想法,就能够写出一个软件。

另外一方面,真正用 AI 写过成体系代码的工程师都会发现,AI 确实非常强,但它也容易把代码库变成一坨没人敢动的屎山。

前段时间在 AI Engineer 大会上,资深工程师 Matt Pocock 做了一个分享,标题挺反共识的,叫 Software Fundamentals Matter More Than Ever。

软件工程基本功在 AI 时代不仅没过时,反而比以前更值钱了。

这句话第一眼看上去像是老工程师的精神胜利法,但听完他的论证再回头看自己用 AI 写代码踩过的坑,会发现讲的全是实话。

下面我分享一下我的感受。

1
很多人对 Vibe Coding 的理解是,随性地跟 AI 聊,用自然语言表达想法。哪里有 bug 或者跑不通,继续让 AI 改就行,反正 AI 已经很强了。

如果只是做一个小工具,用户量不大,那这套打法绝对没问题。但如果你想做的是一个大中型系统,那完全就是另外一回事了。

懂代码的人深入看一眼就会发现问题。Vibe Coding 第一遍 AI 生成出来的代码还行。第二遍质量下降一点。

第三遍更差。几轮下来代码库的可维护性会变得很差,逻辑散落、命名混乱,连 AI 自己再回来读都得绕半天。

《程序员修炼之道》这本老书里有个词准确地描述了类似的现象:软件熵。

熵增是宇宙基本规律,万事万物都倾向于变得混乱。软件也一样,每次改动只盯着眼前这一处,不考虑整个系统的设计,代码就会一点点烂下去。

AI 生成代码的速度比人快十倍,这意味着熵增的速度也快了十倍。

Vibe Coding 这套打法的底层假设是一句话:代码很便宜。但这个假设错得离谱。代码从来不便宜,烂代码反而比以前更贵了。

为什么这么说,因为 AI 在好代码库里能跑得飞起,在烂代码库里寸步难行。

想象两种场景。一种是代码库结构清晰、命名一致、模块边界明确,AI 接到任务能很快找到该改哪里、不会改坏什么。

另一种是代码像一锅乱炖,同一个概念有三种叫法,逻辑散落在十几个文件里,AI 每次改动都得先猜半天,改完还经常牵一发动全身。

在第一种代码库里,AI 是杠杆,把产出放大十倍。在第二种代码库里,AI 是放大器,把混乱放大十倍。

这就是整件事的核心:AI 是复杂度放大器,不是复杂度清洁工。

那问题来了。既然 AI 会天然放大复杂度,那真正该做的事情是什么?

答案是主动给代码库加秩序。

这时候。那些老掉牙的软件工程原则和方法,在 AI 时代不是变得过时了,而是第一次变成了真正的生产力。

2
很多人用 AI 写代码的第一感觉是,怎么 AI 做出来的不是我想要的。

明明指令也下了,要求也说了,做出来的东西就是差点意思。然后再补一句 Prompt 调整,再差点,再补一句,几轮下来开始怀疑人生。

软件这行有句老话,没人真正知道自己想要什么。

解决方案有两个,都是开工前的功夫。

第一个叫 Grill Me。

AI 反过来盘问你。Prompt 简单到就一句话:围绕这个计划的每个细节相关地审问我,把设计树的每个分支都走一遍,把依赖关系一个个理清,直到我们对要做的事达成共识。

这个仓库在 GitHub 上拿了一万三千多颗星,可见多少人有同样的痛点。

实际用起来什么效果,AI 会问你四十个、六十个、有时候一百个问题。问到后来自己都觉得烦,但就在这种烦中,原本以为想清楚了的需求,会被它逼出一堆没考虑到的角落。

《人月神话》的作者曾经讲过一个观点:两个人一起设计一个东西,他们之间会有一个看不见的共同理解,那个理解不在任何文档里,就在两个人的脑子里。

如果这个共同理解没建立,两个人各自走各自的方向,最后做出来的东西必然对不上。

人和 AI 之间也一样。你以为说清楚了,AI 以为听明白了,其实双方脑子里想的根本不是同一个东西。

Grill Me 干的事就是把这个隐形的共识显形化,让双方的脑子在动手之前先对齐。

第二个方法叫 Ubiquitous Language,通用语言。

这是 DDD 里的老概念。DDD 是什么,我不展开了,不熟的同学可以去搜一下。最近 Vibe Coding 比较多,我又再次意识到十年前学的 DDD 有多重要。

举个例子。一个电商项目,运营那边把订单叫做单子,客服那边叫订单,技术那边在代码里写 Order,数据库表叫 trade_record。这次 Prompt 用了订单,AI 就写一个 order_service。

下次 Prompt 用了交易,AI 又写一个 trade_handler。过几轮回头看代码,发现同一件事在三个文件里有三种命名,调用关系绕来绕去。重构一次得改半天。

通用语言的做法很简单,维护一个 Markdown 文件,列清楚项目里所有关键概念的精确定义,哪些词不要用,命名规则是什么。然后让 AI 每次工作前先读这个文件。

效果挺明显的。观察 AI 的思考过程会发现,术语对齐之后,AI 想问题的方式都不一样了,输出更精准,写出来的代码命名也更一致。

把这两件事放一起看,会得到一个挺反直觉的结论:和 AI 协作里最贵的成本,不是写代码的时间,是消除歧义的时间。

前面花十分钟跟 AI 对齐清楚,后面能省两个小时的返工。这笔账怎么算都划算。

但人有种本能,看到 AI 能写代码,就想赶紧让它开始写,先跑起来再说。

这种心态在 AI 时代会被反复教训。

3
意图对齐之后,下一步是怎么让 AI 实际干活。

这里有两个关键的节奏控制方法,垂直切片和 TDD。

先说垂直切片。

很多人用 AI 的姿势是这样的:给我做一个任务管理系统,要有用户登录、任务列表、提醒、协作。

然后 AI 开始一通生成,前端、后端、数据库、接口,一口气出来几十个文件。

这种打法有点像先横着铺架构,前端、后端、数据库、接口都先摆出来,再一层层往里填。问题是哪一层都没填完,哪一层都跑不通,想验证某个具体功能能不能用都不知道从哪儿下手。

更靠谱的打法叫垂直切片。

从一个具体的用户场景切入,比如用户能创建一个任务并在列表里看到它。

围绕这个场景,从前端的按钮到后端的接口到数据库的存储,竖着打通一条完整链路。这条链路能跑通了,再做下一片。

这么做的好处特别实在。每一片代码量都不大,能看懂 AI 在做什么。

每一片做完都有一个能演示的成果,业务价值看得见摸得着。出了问题改动范围有限,不会牵一发动全身。

用得好的人都在做精细手术,一片一片地打通。用得差的人都在让 AI 拿电锯推楼,看起来气势大,结果一片狼藉。

切片切对了方向,每一片里面也不能让 AI 一通乱写。这里就要用到 TDD,测试驱动开发。

AI 写代码默认是一种很冒进的状态。给它一个任务,它会一口气写一大堆代码,写完才想起来要不要类型检查一下,要不要跑个测试。

这时候已经晚了,错误已经扩散到很多地方,找起来非常痛苦。

《程序员修炼之道》里有句话说得贴切,反馈的速度就是你的速度上限。反馈跟不上代码生成的速度,迟早翻车。

TDD 干的事是给 AI 装一个限速器。先写一个测试描述期望行为,让 AI 实现这个测试能过的最小代码,跑通,再写下一个测试。

AI 被强制一小步一小步走,每一步都有验证,跑偏了立刻就能发现。

这里有个心态上的变化值得说说。以前是人写代码再补测试,测试是写完之后的事情。

现在更像是人设计测试和行为,AI 去把实现填满。测试从事后检查变成了事前约束,从安全网变成了方向盘。

AI 不缺速度,AI 缺的是约束。约束是人加的。

4
活动现场,Matt 问现场的程序员,有多少人觉得自己比以前更累。台下很多人举手了。

AI 不是号称可以提高效率吗,怎么用了 AI 反而更累。

原因其实很简单。AI 产出代码的速度,已经超过了人脑处理这些代码的速度。能写出来不等于能看懂,能跑通不等于能维护。

而代码库的组织方式,直接决定了这种过载有多严重。

如果代码库里全是浅模块,AI 写得越多,人需要装进脑子的东西就越多。

每个模块接口都不一样,调用关系绕来绕去,想看懂 AI 改了什么,得把整张地图重新理一遍。AI 在跑,人在喘。

解法是回到一个老概念,深模块,Deep Modules。这个概念出自斯坦福教授 John Ousterhout 写的《软件设计的哲学》。

什么叫深模块。一个模块对外暴露的接口越少越简单,内部封装的复杂度越多,这个模块就越深。

举个例子。要发邮件,深模块的做法是对外就一个函数 sendEmail(收件人, 主题, 正文),调用方填三个参数就完事。

这个函数里面要做的事其实一大堆,连服务器、认证、组装邮件头、处理重试、关闭连接,但这些细节全部藏在模块内部,外面看不见。

浅模块的做法是把这些细节一个个暴露出来,对外给六七个函数,调用方得自己按顺序调用。

注意,深模块不是说一个函数里塞很多东西,那是反面教材。

深模块讲的是整个模块对外的接口少而干净,内部该拆几十个小函数就拆几十个小函数,但拆出来的小函数是模块内部的事,不暴露给外面。

AI 天生爱生成浅模块。让它写代码,它倾向把内部步骤一个个变成对外函数,看着 DRY,实际上把内部复杂度泄露给了调用方。

深模块的好处是人可以把模块内部当成灰盒看。接口设计清楚了,行为有测试盖着了,里面怎么实现的日常不用盯每一行,需要的时候再掀开看。

这部分脑力就省下来了,省下来的脑力放在更上层的事情上,模块边界画得对不对,接口够不够清晰,整体架构有没有走样。

人的大脑能装的东西是有限的。AI 把代码生产速度推上去之后,这个有限性就成了瓶颈。

深模块的本质是给大脑减负,让人不用把整个系统的复杂度都装进脑子才能干活。

到这里,AI 时代开发者的角色就清楚了。

AI 是手脚极快的实施兵,能把活干得又快又多。但实施兵需要有人指挥,得有人在更上面盯着系统该往哪儿长。这个人就是开发者。

这种分工下,开发者每天该投入的不是敲键盘的时间,是想清楚系统该怎么设计的时间。

写到这儿,开头那个反共识的结论可以收一下了。

AI 正在把程序员从代码工人推向系统设计师。生成代码这件事,AI 已经接手了大半。

人剩下的价值集中在四件事上:画清楚模块边界,控制系统的熵增,设计反馈的回路,统一整个系统的语言。说到底是一件事,管理复杂度。

会写 Prompt 只是入门,能管复杂度才是真本事。

5
前面这些原则,通用语言、垂直切片、TDD、深模块,单拎出来没有一条是新的。每一条都能在二十年前的工程书里找到出处。

这正是这场分享真正想讲的事。

Matt 在开场说过一句话,这场 talk 是讲给那些觉得自己的技能在 AI 时代不再值钱的人听的。

台下很多是干了十年、十五年、二十年的开发者,看着 AI 一夜之间能写代码,会下意识觉得自己被淘汰了。

但他要表达的其实不是替老工程师找补。他真正想讲的是另一件事。

即便 AI 的能力已经这么强,写代码的速度这么快,那些过去几十年攒下来的软件工程原则,仍然需要被一代一代的开发者认真学习、认真理解。

这些原则不是历史遗产,是真正构成判断力的基石。没有这些基石,就驾驭不了 AI 写复杂代码。

AI 时代有一件事翻转了。以前稀缺的是手快的人,能一晚上撸出来一个原型的程序员很厉害。

AI 把手快这件事变成了基础设施,稀缺性整个反转过来,反转到了对代码的驾驭上。

所以这场分享真正想说的是,AI 不是让软件工程让这门功课变得比以前更重要。

老工程师过去几十年学的那些东西没白学,年轻开发者今天该学的那些东西也没法跳过。

AI 能帮人写代码,帮不了人去理解什么是好代码。

编码容易,测试也容易。架构、设计和品味,才是真正有价值的事。
03

来自圈子

圈子图片

科技圈大小事

100万+人已经加入