代码在不断生长,但团队已经不懂彼此在写什么——Armin Ronacher 论 vibe coding 的隐性代价

代码在不断生长,但团队已经不懂彼此在写什么——Armin Ronacher 论 vibe coding 的隐性代价

vibe codingAI编程软件工程团队协作技术债务Armin Ronacher

数据源:HN + Lobsters

Flask 和 Jinja2 的作者 Armin Ronacher 在 7 月 13 日发表了一篇短文,标题是「The Tower Keeps Rising」。他用 Bruegel 那幅著名的《巴别塔》油画作为隐喻,讲了一个让很多工程师感到不安的观察:AI 辅助编程让个体效率飙升,但团队层面的「共享理解」正在无声地瓦解。

Bruegel 的《巴别塔》

这篇文章在 Hacker News 上拿到了 541 分、262 条评论,Lobsters 上 42 分、15 条评论,Simon Willison 也专门引用了其中关于「摩擦力同步人」的段落。在没有新功能发布、没有灾难性事故的一周里,一篇讨论软件工程哲学的文章能引起这种级别的关注,本身就说明它触及了很多人心中隐约的不安。

巴别塔故事的另一面

Ronacher 指出,巴别塔的故事通常被解读为关于骄傲与野心的寓言——人类妄图建一座通天的塔,上帝因此变乱了他们的语言。但他提醒我们注意一个被忽视的细节:在上帝干预之前,人类说出了一段关于技术升级的话——「来,我们做砖,把砖烧透了」。他们用砖代替石头,用石漆代替灰泥。但上帝评价局势时,关心的并非这些建筑材料,他关心的是:「看哪,他们成为一样的人民,都是一样的言语……如今既做起这事来,以后他们所要做的事就没有不成就的了。」

Ronacher 的解读是:他们的力量源头是协调,而非砖块。他们共享一种语言,通过这种共享语言,他们能够把各自的工作组合成任何单个人无法独立建造的东西。上帝没有拿走砖块或制砖的知识——他只拿走了他们理解彼此的能力,于是建造就停止了。

把这个逻辑平移到软件工程上,就是 Ronacher 这篇文章的核心论点:一个软件项目的「共享语言」并非 Python 或 Go,它是团队对系统概念的意义、边界在哪、哪些不变量重要、谁负责什么、以及系统为什么呈现出现在这个形状的共同理解。这种语言很少完整地写在一个地方。它一部分存在于文档和代码中,但也存在于代码审查、对话、争论、以及向别人解释一个变更的经历中。

摩擦力的消失

这篇文章最引人注目的洞察是关于「摩擦力」的。在 AI agent 出现之前,共享理解的维护有一部分是靠摩擦力驱动的。比如,要改一个由同事负责的存储层,通常需要读他的代码、问问题、可能还要协调另一个依赖这个服务的团队。这个过程很慢,其中相当一部分是浪费——但不是全部。其中有一部分就是你我的理解互通的过程,也是我们双方发现彼此是否仍然对系统运作方式持有共识的过程。

用 Ronacher 的原话来说:「这个摩擦力同步人。」

Agent 消除了大部分这种摩擦力。你可以让 agent 加上 OAuth,我可以让它加上缓存,另一个人可以让它从零重建数据库并把 UI 改成粉色。每个变更单独看都可能合理——代码能编译,测试能通过,解释可以按需生成。但我们谁也不需要跟别人说话,甚至不需要去获取那些以前会被迫学习的那部分共享模型。

Ronacher 说过很多次的一句话在这里再次出现:「agent 不会感到痛苦,只有人才会。」Agent 现在让我们能够触及那些以前需要其他人协助的系统部分,进入那些以前人会奋起反抗的代码库。

不会倒塌的塔

最让 Ronacher 感到不安的地方在于:这和圣经故事不一样。在巴别塔的叙事里,共同语言的丧失导致建造停止。但在 AI 辅助的软件工程中,建造可以在共享理解已经瓦解之后继续进行。

塔不会倒塌。所以我们注意不到失去了什么。它只是不断生长。

这正是 Lobsters 上最高赞评论的精妙之处。用户 Gaelan 只引用了 Ronacher 最后这段关于「塔不会倒塌」的段落,然后回了两个词:「So far.」(目前还没有。)

这两个词之所以有力,是因为它直指 Ronacher 论证中潜藏的那个未竟之问:如果塔不会因为失去共享理解而倒塌,那它会在什么时候、以什么方式倒塌?是当关键人员离职后没人能接手?是当积累的架构不一致导致一次无法回滚的事故?还是当公司发现迭代速度反而因为没人理解全局而变慢?

hjvt 的评论(△26)则提出了另一个角度:塔在 AI 之前就已经开始倾斜了。2012 年以后的多数商业软件质量下滑的速度之快,连非技术用户都注意到了。从这个角度看,AI agent 不是造成问题的第一个因素——它只是加速了已经存在的趋势。外包、微服务、低代码平台……每一次「消除摩擦力」的工具浪潮都在用类似的方式侵蚀共享理解,只是 AI agent 把这种侵蚀推到了一个新量级。

三十万行 Go 代码的现实

Lobsters 上 emk 的评论(△10)则从实践层面给出了一个更直白的判断。他自称对 AI 编程的容忍度比 Lobsters 上大多数人更高,但他对「no human has looked at the code」意义上的 vibe coding 的评价是:「大多数都是垃圾。」bug 成堆,三十万行 Go 代码干的事本可以用两万行干净的 Rust 完成,数据存储被损坏,甚至在群聊里会有人真诚地讨论要不要给作者做个健康检查。

emk 指出的两个例外也很有参考价值:一是架构完全可预测的 CRUD 应用(比如 Rails 那套),LLM 可以直接靠训练集给出正确答案;二是用 Fable 做的绿地原型——他承认花 20-50 美元让 Fable 自己跑一两个小时,回来就能得到一个好用的应用。但问题恰恰在于:「我走开的时候对 Fable 写的两千行漂亮代码一无所知。」

这其实回到了 Ronacher 的核心关切:个体效率的提升和团队理解的丧失是同一枚硬币的两面。你用 agent 完成了一个变更,代码在那儿,测试也通过了,但你并没有获得做这个变更本应迫使你去获取的那些系统知识。如果团队里每个人都这样做,那么整个团队对系统的集体心智模型就会逐渐退化为一堆彼此孤立、只能靠 agent 翻译的局部视角。

旧问题,新量级

把 vibe coding 放在软件工程的历史里看,它确实不是第一个「消除摩擦力」的工具。微服务架构消除了单体应用里「改一处需要协调所有人」的摩擦力,结果呢?我们得到了分布式系统的调试噩梦。外包消除了「内部团队需要理解每个模块」的摩擦力,结果呢?一些公司失去了对自己核心系统的掌控。

但 AI agent 的特殊之处在于:它消除的是认知层面的摩擦力,而不仅仅是流程层面的。微服务和外包至少还保留了「人需要理解变更」这个环节——哪怕理解是事后补的、质量参差不齐的。Vibe coding 的极致形态是:代码被生产出来,变更被合入,但没有任何人类在这个过程中真正理解过这些代码。

这让我想起 Fred Brooks 在《人月神话》里说过的那句话:软件复杂性的上限曾经是人类心智的能力。Vibe coding 可以突破这个上限——原因是这个过程本身不趋向于紧凑的抽象,而非问题真的需要那么多复杂性。没有人在逼迫系统「精简」,没有人在发现「这里其实可以复用」,没有人在积累那些只有长期与代码搏斗才会形成的架构直觉。

当塔要修缮的时候

Ronacher 文章的标题本身就隐含了一个时间维度:「The Tower Keeps Rising」——塔持续在生长。这是个进行时,不是完成时。它暗示我们还没有到达终点,还在上升的过程中。

但 Gaelan 的「So far」提醒我们,物理定律不会因为我们在软件世界里工作就失效。一座没有共享理解的代码塔,就像一个没有结构图纸的摩天楼——你可以继续往上加盖楼层,直到某个临界点。

届时谁来修缮它?谁理解那些「为什么这个模块要这样设计」「为什么这个不变量不能被破坏」「为什么这两段看起来相同的代码其实有不同的语义」?如果这些知识不存在于任何一个人的头脑中,而只存在于 agent 的训练权重和 prompt 历史里——那当塔真的开始倾斜的时候,我们能做什么?

这个问题没有简单的答案。但至少 Ronacher 让我们看到了它。在一片「AI 将十倍提升开发效率」的喧嚣中,有人停下来问:提升的是什么效率?我们因此正在失去什么?这些问题本身就值得被认真对待。

参考链接:

  • Armin Ronacher《The Tower Keeps Rising》原文
  • Hacker News 讨论:The Tower Keeps Rising
  • Lobsters 讨论:The Tower Keeps Rising
  • Simon Willison 的引用文
  • Pieter Bruegel the Elder《The Tower of Babel》维也纳版(public domain)

本文的素材来自公开信息和社区讨论。如果你对这个话题有更深入的一手经验,欢迎指出文中的不足。