为什么我不用 AI 辅助编程(Vibe Coding)

2 分钟
AI

为什么我不用 AI 辅助编程(Vibe Coding)

简短版:

作者 Jacob Harris 阐述了他作为资深开发者不使用 AI 辅助编程(vibe coding)的几大原因:

  1. 我很抠门 — 不愿为"思考"永久付费,积分用完就卸载了
  2. 我老了 — 引用《人月神话》中"没有银弹"的概念,LLM 解决的是偶然复杂性,但本质复杂性(设计优雅系统)不会消失
  3. 我喜欢混乱 — LLM 无法理解其自身视角的局限,无法做元认知;以 DOGE 对社保数据的错误解读为例
  4. 阻力是一种礼物 — 编码的困难是架构问题的信号,AI 消除阻力反而让人跳过深度思考;而且软件开发是协作过程,AI 取代的是人与人之间的连接
  5. 我非常在乎 — 热爱编程本身,不愿把创造乐趣交给机器;LLM 不会真正"在乎"错误和后果
  6. 还有一堆其他原因 — 讨厌 AI 的谄媚语气、享受未完成的爱好项目的过程、以及 LLM 产业的伦理问题

文章最后反思:如果 AI 泡沫破裂,希望我们能将软件开发重建为"构建更美好世界的人性化实践"。

作者: jacobharr.is(2026年3月5日)

作为一名开发者,我从不来不喜欢 AI 辅助编程的各种个人原因汇总。


最近网上关于 AI 辅助编程(vibe coding)的讨论很多,关于大语言模型(LLM)将如何彻底改变软件开发领域,各种声音不绝于耳。每个新模型都会把我们带入纯粹生产力的境界,让我们以思考的速度交付软件,消除产品开发中的所有摩擦和开销。大概是这样说的吧。

也许吧。我只能听你们说了。反正我不用 AI 辅助编程。

如果它对你有用,那很好!我在这里并不是要深入辩论 LLM 的优劣,只是它对我个人来说从来没有真正"来电"。这篇文章是我不用 AI 辅助编程的各种原因的汇总。

我很抠门

我不是个纯粹主义者。我尝试过在 IDE 里集成的那些 LLM。对于一些简单到容易描述但又烦人到不想自己动手做的任务,它们确实有用。比如,把一网格方图缩小尺寸。我可以去查 ImageMagick 的命令行参数,但那是问 AI 的完美场景。之后我还试过一个 AI 工具来分析我项目里的代码,还有其他几个小任务,然后一切就突然尴尬地戛然而止了——系统提示我的积分用完了,如果要继续就得提供信用卡购买更多 token。

要知道,我家两边往上数几代人都是出了名的抠门。不管是大西洋这边还是那边,几百年来我们一分钱掰成两半花,到处淘便宜货。举个例子,我有个远房祖先在菲利普国王战争期间,为了取回撤离房子时落下的一块奶酪,冒着生命危险冲出安全堡垒,最后丢了性命。所以你们得相信我:为一个让我"思考"的服务永远付费,这种想法简直荒谬得可笑、恐怖得离谱,我连卡都懒得给。我合上笔记本,卸载了 IDE,甚至用回了 Emacs。然后我意识到,没有它我根本就没觉得缺了什么。

我老了

年纪大确实帮了我的忙。我写代码已经很久了,尤其在这个把有5年经验的开发者就叫"高级工程师"的行业里。经验有时候是焦虑的解药(只要不是关于年龄歧视的焦虑——在这个行业里,有5年经验就能被称为高级工程师)。AI 的炒作让我想起了早些年低代码/无代码工具的突破。我不怀疑 AI 对开发者来说是有用的工具。我知道有些任务上它能帮上忙,作为更好的工具。但这些论点总是让我再次想到偶然复杂性和本质复杂性。

弗雷德·布鲁克斯(Fred Brooks)在我还是个年轻程序员的时候就已经老了。作为 IBM System 360 系列主机(及其配套操作系统)的项目经理,他亲眼见证了如今软件项目常见的各种翻车方式在当年还是新鲜事物的时候。他把这些观察收集进了《人月神话》这本书,这本书至今应该仍是软件工程课程的必读书目。我的版本是后来重印的,里面收录了他后来的一篇论文《没有银弹》。在那篇文章里,布鲁克斯审视了新工具对开发者生产力的影响。

要像程序员一样思考,你必须明白现实世界是复杂的。编程最好被理解为强加简化的表示——我们称之为抽象——到我们混乱的现实之上,通过降低复杂性让它变得可理解。这让我们能把具体的情境泛化成可以层层堆叠的层次。比如,把花生酱涂在面包上的具体动作,可以泛化为 spread(substance) 方法,它可以接受花生酱或奶油奶酪作为参数。然后我们可以用这些 spread 方法来构建更高层次的函数,比如 create_pbj() 等等。

用现代高级编程语言写代码,就像站在一座抽象的金字塔顶端,一行代码可能触发数百万次跨多个系统的操作。非常令人兴奋!

那么,如果我们继续前进,把编程行为本身也抽象掉呢?这就是代理式 AI(agentic AI)的梦想,让成群的代理被分配任务,在没有监督的情况下自行实现。听起来很棒!但这只是在解决布鲁克斯所说的偶然复杂性——写代码这件事本身带来的复杂。自那篇文章发表以来,软件开发在这类复杂性上已经取得了巨大进步。我们不用再写底层机器码,而可以用现代动态解释型语言,它们会被编译成汇编。不用从头写快速排序,我只需要调用标准库里的 sort 方法。不用从头搭建整个 Web 应用,我可以用现成的框架。想要重命名或重构代码,编辑器就能帮我完成。AI 似乎是这一趋势的延续,有些编辑器甚至已经用不可预测的 AI 代理取代了那些可预测的重命名和重构工具。当然,这看起来像掷骰子,但严重故障能有多常见呢?

然而,即便更好的工具已经削弱了偶然复杂性,本质复杂性依然存在。设计优雅、清晰、可维护的抽象和系统,这项工作依然复杂。而这种复杂性不会消失。这类工作需要技能、经验和从过往系统故障中获得的来之不易的智慧。而且,我不确定 LLM 那种花哨的自动补全方法,是否真的能很好地应对这类复杂性——它通常不是那么直接就能解决的。也许通过提示词引导,它可能走向偏好的方案,但到了那个地步,做引导的人还不如自己设计方案,因为 LLM 根本无法解释它为什么选择某条路径。本质复杂性往往是怪异、罕见、混乱的。也许我错了,模型在这些混乱情况上也越来越好了,但我发现这通常需要一种特定的心态和方法。对我来说幸运的是,我喜欢混乱的东西。

我喜欢混乱

到目前为止我一直在说软件如何抽象流程,但我们也利用抽象的还原性作为理解世界的工具。在经典著作《国家的视角》(Seeing Like a State)中,詹姆斯·斯科特(James Scott)描述了启蒙运动后的核心工程:通过抽象和分类使其人口和财产变得可读(legible)。测量即修改。

例如,一个国家可能开始看待森林不再是复杂的生态系统,而只是评估其中可用于造船的木材百分比。这种视角让国家可以据此采取行动,比如把那些森林替换成单一树种的单一栽培林。一片森林被抽象成了一个种船桅的系统。

这种做法催生了官僚制度和纸质表格,后来演变成了网页表单和数据库。作为程序员,我们需要把世界的混乱数据简化,才能对其采取行动。我们期望日期是精确的。我们期望名字是相对简单的。我们期望数据在录入时是完整的,并且在时间上保持一致。每个程序员、每个系统设计,都是一系列普罗克汝斯忒斯式的选择,决定我们要在系统中反映现实的哪些方面,可以丢弃哪些。我不是在批评;这种方法是构建不被无尽特例(我们称之为"边缘情况",因为它们应该是外围的罕见路径)所拖累的系统的唯一方式。

但这种过程如此本能,以至于我们有时会忘记它也是人为的,尤其当它描述的是人的时候。把性别字段强制设为只能接受"男"或"女",并不会让性别本身变成二元的。我们对种族的定义是社会建构,一直在变化。我们简化的模型可能给我们提供洞见(过去20年自闭症诊断增加了300%!),但无法捕捉这些洞见背后的深层因素(这可能只是因为我们对自闭症定义的改变和筛查的增加)。退一步审视任何模型是如何构建的,以及它不捕捉什么类型的知识,这是很重要的。每个抽象也是一种遮蔽。

作为数据记者,我学会了如何"采访"数据,并对发现答案可能产生误导的所有方式保持高度严谨。偏执是数据记者最好的朋友,如果你想避免尴尬地发更正声明的话。你需要思考的不仅是数据说了什么,还有它没有包含的所有东西。

不幸的是,这种元认知(metacognition)是 LLM 永远无法做到的。模型就是它们的现实。正如罗宾·斯隆(Robin Sloan)在他那篇有力的文章《语言模型在地狱吗?》(Are Language Models in Hell?)中精辟地指出的,AI 模型从简化后的数据中构建,并以简化的方式看待世界。你和我看到一段文字时能感知到它的语境(比如文本格式、标题、作者简介、文章被引用的网站),而 LLM 只在一个由字母构成的纯世界里运作(技术上它们接收的是子词 token,这就是为什么早期模型数不清 strawberry 里有几个 r)。让 LLM 认识到它对现实的视角存在局限性,就像问一条金鱼水怎么样。

写这一节时,我一直在想 DOGE 在政府社保局找欺诈的拙劣尝试。在一个例子中,DOGE 查看了社保局数据库,发现里面有超过900万条出生日期在120多年前但没有记录死亡日期的记录。埃隆·马斯克宣称唯一的解释就是有数百万人正在欺诈性地领取福利金。他对问题的原因和严重程度都判断错了。DOGE 本可以质疑数据质量,本可以检查实际支付的款项,本可以问社保局的任何专家。但他们没有,他们把数据当作既定事实,跳到了错误的结论——他们一遍又一遍地重复这个模式(就像另一个关于付款欺诈的例子):

"这些付款是有效的," 代理副局长肖恩·布鲁恩(Sean Brune)在一封调查其中一个问题的备忘录中写道。(财政部发言人拒绝置评。)

但据熟悉鲁索先生言论的人士透露,他不信任职业公务员。(鲁索未回应置评请求。)相反,他坚持让阿卡什·博巴(Akash Bobba)——一位曾在 Palantir 实习、后成为 DOGE 首席程序员之一的21岁年轻人——自己进行分析。

DOGE 团队以他们自己疯狂的方式,为自己复制了导致 LLM 跑偏的相同工作条件。他们拒绝考虑数据之外的其他解释。他们不与圈子之外的任何人交流。他们抓住了一个简化的解释,因为它完全符合他们对无能政府雇员和无处不在的欺诈的世界观。

这不是罕见的情况。我自己也非常害怕看起来像个白痴,所以我不想把数据分析外包给 LLM。但当然很多人会。我担心这个问题只会越来越严重。

阻力是一种礼物

LLM 驱动开发的吸引力在于,它本该消除阻力。鼓吹者们描绘着开发团队一天发布几十个功能的画面,使用多组以越来越奇怪的拓扑结构自主运作的代理团队。我理解,软件开发可能乏味且令人沮丧。能以相对疯狂的速度产出代码,把玩精致的产品而不是原型,一定很让人兴奋。

但我需要阻力。

当我第一次学习新语言或框架时,我 struggle 于做最基本任务的阻力。很难受!当我面对新的、不熟悉的代码仓库或数据源时,我需要留出几个小时来仔细审视。我经常发现自己要做细读,逐行查看特定文件,直到理解它们的上下文以及开发者做出的选择。我知道我可以直接让 LLM 给我总结项目来节省时间,但我发现我需要这个过程来真正沉浸在代码中。我需要它不仅仅是理解开发者做了什么选择,而是理解他们为什么做这些选择,以及这些选择如何反映了他们所使用语言的约束和惯用法。我从失败中学习,如果 LLM 把那些工作从我手中夺走,我不会真正理解我在做什么。

即使在熟悉的语言和自己的代码中工作时,我仍然严重依赖阻力作为线索。当写代码变得困难时,这告诉我当前架构的方向错了,我应该认真考虑重新设计,让未来的扩展更容易。当这种情况发生时,我通常会出去散个长步(或干脆下线),给我的大脑空间,从一个新角度审视问题。真的很有效。我发现这些停顿如此有效,以至于即使前路看起来清晰时,我也会强迫自己这样做。在大型软件项目中,我会等到写好架构决策记录(ADR)之后才开始编写新功能,描述我想做什么。这些文件迫使我捕捉此刻我的想法、我对问题的假设以及我方法的后果。有时候,这甚至会让我意识到我太迷恋最初的直觉,没看到它会如何走向歧途,而且它总是一个记录"他们当时在想什么?"的好方式,留给将来接手我工作的任何人。

LLM 驱动的做法面对阻力的方式是:直接编码穿过去,不做任何重新思考。而且 LLM 会照做。它可能会写出能用的代码。性能指标会正常,测试会通过(尤其如果测试也是 LLM 写的)。但它不会知道为什么选择那条路径。它感受不到阻力,也无法解释一个架构方案是否比另一个更清爽。如果编写提示词的工程师缺乏判断好方案和坏方案的洞察力,他们就会陷入一个动态:反复让 AI 编码穿越阻力。这可能导致一丛奇怪的抽象,而未来团队唯一的设计文档就是几年前用于 AI 模型的提示词 markdown 文件。祝你好运,想从那份文件里重建架构决策吧!

值得注意的是,我看到的大多数 AI 辅助编程的成功故事,要么来自他们要求 LLM 构建的东西本身就是专家的开发者(因此能够引导它的工作),要么是失败代价低的情况。对于其他一切,我们还得想办法判断那只猫头鹰的其余部分是不是好货、能不能安全使用。

如果我不提另一件让我困扰的事,那就失职了。当 LLM 推广者把阻力当成问题时,我在广告、现场演示和 LinkedIn 帖子中看到的大多数 LLM 营销,描绘的都是一个孤独的工程师(或也许一个小团队)英雄般地用 AI 辅助编程快速搞出某种应用或网站并迅速上线(我们的速度和 KPI 爆表了!)。但行业真正希望开发者用 LLM 做的是工作,而那里的阻力通常是既定流程和实践,用来防止缺陷甚至概念不清晰的特性进入生产。 inevitably,把 LLM 驱动的速度放在首位的需求被用来针对人本身——其他工程师、产品或项目管理、测试、合规或设计的团队成员。因为那些角色也被视为阻力。谁还需要用户研究,我们可以用 AI 人格?谁还需要设计,我们有 AI 工具生成网页布局?谁还需要项目经理,当我们是我们代理军队的主管?如果我们不需要等另一个开发者审查我们的 PR,直接自动合并且通过测试和扫描的代码呢?如果我们不需要在工作时间花任何时间跟别人说话,只活在纯粹编码的境界里呢?

但软件开发是一个协作过程,团队的每个成员都在帮助产品变得更好。移除那些角色或用 LLM 影响的幽灵取代他们,肯定能让团队更快,但这不意味着他们交付的产品会更好。而且这个过程肯定会更孤独。

我非常在乎

也许我不使用 LLM 最简单的原因就是:我太热爱编程了,不想把它交给机器。就像如果我是艺术家或音乐家,我不会求助于 AI 一样,编程是我表达创造力的一种方式,我不会放弃这种快乐。虽然有时非常令人沮丧,但把一个模糊的想法塑造成一个真实的系统,尤其是如果涉及优雅的实现或有趣的问题时,会有一种深刻的喜悦。有些晚上,我合上工作笔记本,打开个人笔记本,投入某个我想做的新有趣东西中。而当我作为团队的一员专业地构建软件时,那更棒!我喜欢协作和共同塑造软件的过程,尤其是人们会挺身而出、对问题负责的那种方式。当团队只是对提示词负责,而 LLM 助手在做实际工作时,我不认为这种动态是一样的。或者当 LLM 助手在取代团队的部分成员时。

所有权很重要。在过去几十年里,我工作过的角色培养了我强烈的个人责任感。作为数据记者,代码中的错误可能导致尴尬的更正或毁灭性的诉讼。在公民科技领域,错误可能意味着提供服务和福利的灾难性失败,无论是对整个弱势群体还是对一个人。我不会说我从没犯过错,但我非常在乎把事情做对,因为我非常在乎工作的使命。我很幸运能与许多同样在乎、想为人们尽力而为的人一起工作。LLM 不会在乎。当然,它可以令人信服地假装在乎,但它仍然只是心灵的仿制品,把更可能与其他词关联的词串在一起。它不会被自己的错误所困扰,也不会试图做得更好,因为它没有内在意识,更不用说良心了。它永远无法被追责,因此我也绝不能把我的道德责任推卸给它。

当 LLM 表现好时,它是一个将取代所有程序员的天才。当 LLM 删除了你的所有基础设施或在测试上"撒谎"时,这是你的错。毕竟,你只需要以正确的方式构建你的提示词和工作流,就能促使 LLM 给出正确的输出。哎呀,再试一次。又一次。我读过的很多 LLM 建议都强调,你必须在一开始就给完所有必要的指令、修正案和附则,否则系统就会做错事。这种思维模式与敏捷编程形成了重大背离,敏捷编程强调频繁的路线修正、反馈,并信任你的团队会做正确的事。相反,我们似乎正在退回到一种类似于20世纪50年代早期计算机分时系统的使用模式。只是在这里,孤独的程序员不再是递交一沓打孔卡片,而是递交法律文件来转换成程序。

我开玩笑的;这里并没有法律责任。考虑到相似的人口统计学特征,这可能并不令人惊讶,但 LLM 供应商正在重复与特斯拉相同的动态。新功能在没有安全测试的情况下推送给用户,而同样奇怪的是,LLM 的支持者们——就像特斯拉的超级粉丝一样——经常把灾难性后果归咎于自己和他人,说用户本应该在写提示词方面做得更好。我真的不知道该怎么看待这件事,但它让我困扰的是,科技正在把一种资本主义标准化,在这种资本主义中,更多的风险由消费者承担,因为企业和政府都已放弃了他们的责任。我们在 lawn darts 杀死一个孩子后就禁止了它,但聊天机器人把用户推向死亡和精神病却被接受为 AI 创新的代价。当 AI 辅助编程本身导致某人因系统故障而死亡,而不是尴尬致死时,情况会改变吗?

编码也是我艰难时期的慰藉。有研究表明玩俄罗斯方块是避免 PTSD 的有效方法。理论认为这种疗法有效,是因为激活大脑中负责排列和旋转形状的区域,阻碍了创伤记忆的形成。我很幸运没有遭受 PTSD(我也没有轻视那些遭受 PTSD 的人),但我确实也与这个概念有共鸣。编程就像一个复杂的谜题,有时是我黑暗时期的慰藉。正如上面的例子暗示的,我对 DOGE 了解很多,因为在过去的一年里,我一直在构建和维护一个系统来追踪他们的肆虐。与一个有期限的项目不同,这是一个组装数据集的工作,旨在为一个想要保持隐匿的组织提供清晰度。这是一次有意义的锻炼,也是我把自己绝望转化为某种我希望会有用的东西的方式。这不是我第一次用代码来缓解悲伤,它之所以有效,是因为这就是工作,而如果我只关注产品,这个过程就会大打折扣。

还有一些其他傻乎乎的原因

这篇文章已经比我预期的长得多,尤其因为它最初只是 Bluesky 上的几条短帖。在结束之前,再快速说几个原因!

首先,我绝对讨厌 AI 聊天机器人默认的那种谄媚语气。作为一个在东海岸城市长大的人,当一个我不认识的人对我异常友好时,我会非常怀疑,因为这通常意味着他们要么要对我进行诈骗,要么要向我传教。看 LLM 聊天记录让我起鸡皮疙瘩。是的,我知道我可以让 LLM 采用完全不同的语气,但不知怎么的,这让这个想法感觉更糟。

像许多开发者一样,我有一个装满未完成爱好项目的文件夹。比如那个我想写的 Spelling Bee 克隆版,但要用 Clojurescript 写,这样我可以用 Blabrecs 代码生成非单词,让它超级令人沮丧。好吧,我猜那只有我觉得好笑。你得在场才能懂。从 LLM 的角度看,这些是失败的文件夹,我确实可以用 LLM 每天做一个应用或完成任何我想做的挑战。然而,过程远比产品重要(再说一次!)。不是每个奇思妙想都需要变成现实。通常,我从头脑风暴的乐趣和学习到足以知道自己不需要继续完成的过程中得到更多。有时候很容易忘记这一点。

这篇文章本来不是要讨论在工作中使用 LLM 的道德问题。不是因为我无所谓,而是因为许多其他人已经比我写得更有力,关于这项技术的棘手影响。而在这个 LLM 正在向学校投掷炸弹或按需生成儿童色情的时刻,我真的不舒服使用它们。而且我也不能不提这一点。虽然在资本主义下可能没有合乎伦理的消费,但我至少要试一试。我们不能用让如此多人痛苦的工具来建设一个更美好的世界。

奇怪的是,似乎没有人比 LLM 的支持者更痛苦。如果开发者利用他们新获得的效率提升,终于过上十年前极客们假装崇拜的那种每周工作4小时的生活,我可能会被说服。但反常的是,硅谷的许多人似乎把外包工作给 AI 代理,然后用他们新获得的空闲时间做更多的工作。他们不用时间来放松、创作艺术或寻找快乐,而是拥抱996工作制和一个连弗雷德里克·泰勒都会吓得脸白的超量化工作场所。LLM 革命最终可能会降临到我头上、夺走我的工作,但我宁愿不要先把自己累死。

然后呢?

我不假装知道未来。也许技术会进步到我会后悔缺乏经验和熟悉的程度。或者,也许它会停滞不前,整个金融纸牌屋会倒塌。如果后者发生,我希望我们能将软件开发重建为构建更美好世界的人性化实践,一次一行代码。


此文自动发布于:github issues