作者 Jacob Harris 写了一篇长文解释为什么他不 "凭感觉编程"(Vibe Coding)。这不是对 LLM 的否定,而是对个人工作方式的诚实盘点。
我是个守财奴
Jacob 试过 IDE 集成的 LLM。对于描述简单但动手嫌烦的任务(比如批量缩小图片),它们确实好用。但当他用 AI 工具分析项目代码时,系统通知:额度用光,请绑定信用卡购买更多 Token。
"当我发现为了让自己能'思考',居然还要无休止地给一个服务交钱时,我浑身不自在。"他卸载了 IDE,用回了 Emacs,然后发现:没有 AI,他根本没觉得少了什么。
年纪大了
在这个把5年经验就称为"高级工程师"的行业里,Jacob 写代码已经很多年了。这波 AI 热潮让他想起早年那些"低代码/无代码"工具的重大突破宣传。
Fred Brooks 在《没有银弹》中探讨了新工具对开发者生产力的实际影响。编程最好被理解为:在混乱的现实之上强加一种简化的模型——"抽象"——通过降低复杂性来让世界变得可理解。
如果我们继续往下走,把"编程"本身也抽象掉呢?这就是 AI 智能体的终极梦想。但这解决的只是 Brooks 所说的偶然复杂性——编写代码本身那些繁琐、笨重的地方。即便更好的工具削弱了偶然复杂性,本质复杂性还在那儿。设计出正确、优雅、清晰且易于维护的抽象架构和系统,依然是一项无比艰巨的工作,这种复杂性哪儿也去不了。
LLM 那种花哨的"高级自动补全",面对这种很难直接找到标准答案的复杂性,到底能发挥多大作用?也许通过精心设计提示词可以引导它,但到了那个地步,负责引导的人还不如自己干脆把方案设计出来——因为 LLM 根本无法向你解释它为什么选择了某条特定的路径。
我爱死这些混乱了
James Scott 在《国家的视角》中描述了后启蒙时代的核心动机:通过抽象和分类,让人口和财产变得清晰可辨。能量化的东西,就能被改造。一个国家看待森林时,可能不再将其视为复杂的生态系统,而是仅仅通过"能用于造船的木材比例"来评估。这种方法催生了官僚机构和纸质表格,进而演变成了今天的网页表单和数据库。
作为程序员,为了对世界采取行动,我们必须减少现实数据中的混乱。我们期望日期必须是精确的,期望人的名字相对简单规范,期望数据在输入时是完整的且随着时间推移保持一致。每一个程序员和每一次系统设计,都在做出一种削足适履的强制妥协:我们决定系统应该反映现实的哪些方面,又该丢弃哪些方面。
但是,这个过程如此根深蒂固,以至于我们有时会忘记它同时也是一种人为的造作,尤其是在用它来描述人的时候。强制性别字段只接受"男"或"女",并不能迫使性别的本质变得非黑即白;我们对种族的定义是一种不断变化的社会建构。我们简化的模型可能会给我们提供洞见,但却无法捕捉到这些洞见背后的潜在因素。
每一次抽象,同样也是一次遮蔽。
LLM 的局限:它无法质疑模型本身
Robin Sloan 在《语言模型是在地狱里吗?》中指出:AI 模型的构建基础和它们看待世界的方式,都被极度剥离了细节。当你我看着一段文字时,我们能看到它的上下文——文本格式、标题、作者简介、提供链接的网站等——而 LLM 仅仅在一个纯粹由字母构成的世界里运转。要求 LLM 去认识到它所看到的现实是有局限性的,就像是问金鱼水温怎么样一样,对牛弹琴。
Jacob 举了 DOGE(政府效率部)在社会保障局审查欺诈时的例子:DOGE 发现数据库里有超过900万条记录的出生日期在120多年前,却没有记录死亡日期。马斯克断言,唯一的解释就是数以百万计的人在欺诈性地领取福利。但 DOGE 本可以质疑数据质量,本可以去查查实际是否有钱打进了这些账户,甚至本可以找个 SSA 专家解释一下。他们没有,他们直接照单全收了字面数据,并草率地得出了错误的结论。
"以他们自己狂野的方式,DOGE 团队正在重演导致 LLM 走偏的同款逻辑。他们拒绝考虑任何在数据字面意思之外的替代解释,死死咬住一个极其简化的解释,仅仅因为这太合他们胃口了。"
摩擦是上天的恩赐
LLM 驱动开发的魅力在于消除一切摩擦。但 Jacob 需要这种摩擦。
当写代码变得非常困难时,这说明在当前的架构下正走向一条歧路。它在提醒:应该认真考虑重新设计,以便未来的扩展能更顺畅。遇到这种情况,他通常会出去散个长步,给大脑留点空间,退一步换个角度思考问题。这招真的管用。
在开发大型软件项目时,在开始为一个新功能写代码之前,他会先强制自己写一份架构决策记录(ADR),描述想做什么。这些文档逼着记录下这一刻的想法、对问题的假设,以及方案可能带来的后果。有时候,写着写着就意识到,对最初的直觉太盲目自信了,以至于都没发现它会把项目带进沟里。
而 LLM 驱动开发对待摩擦的态度,就是不管三七二十一,闭着眼睛直接写过去。LLM 会极其配合。它大概率能写出能跑通的代码,性能指标可能不错,测试也能通过。但它根本不知道自己为什么选择了那条路,它感受不到摩擦,也无法向你解释一种架构方案是否感觉比另一种更清晰优雅。
软件开发是协作过程
大多数 LLM 营销都在刻画一位孤胆英雄般的工程师,英勇地利用 LLM 驱动编程,以迅雷不及掩耳之势喷射出一堆应用。但行业真正想要的是开发者在日常工作中使用 LLM,而实际工作中的"摩擦"通常是指那些旨在防止缺陷或糟糕创意流入生产环境的既定流程和规范。
对"LLM 驱动速度"的狂热追求,最终会把矛头指向人本身——其他工程师、产品经理、测试人员、合规审查员、设计师。因为这些职位,现在也被视为了"摩擦"。既然我们能捏出 AI 用户画像,还要什么用户调研?既然 AI 工具能直接吐出网页排版,还要什么设计师?如果我们不再需要等另一个开发者来审查我们的代码,只要通过了测试和扫描就自动合并,那该多爽?
但是,软件开发是一项协作的过程,团队里的每一个成员都在为打造优秀产品贡献力量。砍掉这些角色,或者用沾染着 LLM 气息的代码幽灵去替代他们,肯定能让团队跑得更快,但这绝不意味着他们交付的产品会更好。而且,这个过程绝对会变得无比孤独。
我极其在乎
Jacob 不使用 LLM 的最简单的理由,或许就是他太热爱编程了,以至于一点也不想把它拱手让给机器。就像如果他是个画家或音乐家就不会求助于 AI 一样,编程是他表达创造力的一种方式,他绝不让出这份纯粹的快乐。
责任感太关键了。作为一名前数据记者,代码里的一个 Bug 可能会导致极其难堪的报纸更正,或者引来灭顶之灾般的诉讼。在公共科技领域,错误可能意味着为公众提供服务和福利的系统彻底崩溃。他不敢说自己从未犯错,但他真的极其在乎把事情做对,因为他在乎这份工作的使命。
而 LLM 是不可能"在乎"的。它可以装得非常逼真,但它依然只是一个试图模仿人类心智的赝品,所做的只是把那些在统计学上更容易同时出现的词组串在一起罢了。它不会因为犯错而感到懊恼,也不会努力试图改进,因为它没有内在的意识,更别提什么道德良知了。它永远无法被追责,因此,他也永远不能把道德责任外包给它。
写在最后
Jacob 不会假装自己能预知未来。也许这项技术真的会发展到不可思议的地步,以至于他会后悔当初没有积累足够的经验去熟悉它。又或者,它也许会陷入停滞,整个建立在炒作之上的金融纸牌屋轰然倒塌。如果那一天真的到来,他希望我们能把软件开发重新建设成一种充满人性关怀的实践。
作者:Jacob Harris(原文由宝玉 @dotey 翻译分享)