人工智能没有智慧,你也不会有
AI 写代码不读代码,vibe coding 项目为何几个月后烂成无法维护的乱麻
中文
复制
过去一个月里,我听到过这些说法:
- 我从2025年起就没写过代码;
- 代码评审已死;
- 人们不再读代码了。
行业确实在变,但那些不再读代码、写代码的人和组织,是在拿自己冒险。
事实是,靠 vibe coding 做出来的项目会随着时间推移烂成一团无法维护的乱麻。原因很简单,却很难解决:代码的可维护性和良好的架构没有可用的度量,因为糟糕的架构或不可维护的代码,要过几个月甚至几年才能看出后果。
坏代码当然可以定义:难读、难懂、难以应对未来任何变化。这种代码里,改一处会以极不确定的方式弄坏程序,或者在离改动很远的地方弄坏逻辑,像“蝴蝶效应”。这种代码里,加一个功能是件大工程,因为要在多处改动,还总会漏掉某处,于是产生不一致。这种代码里,设计的不变量并不清晰,而作者早已不在,没人再守着它们不被违反、维持某种一致性。这种代码难测,需要 mock,暴露实现细节,测试因此脆弱,最终反而挡住了有意义的重构。
然而我们确知一点:发现坏代码需要时间。几个月,几年。当然,有经验的软件工程师有一副好鼻子,能嗅出代码异味,在坏后果显现之前很久就采取行动。
熟练的开发者、专家,靠的是用汗水和眼泪换来的直觉——长时间加班调试和修复线上问题,发誓再也不犯过去那种蠢错误。这种直觉没法真正写成一套死规则,因为一切都取决于上下文。让新手更高效的规则和配方,对专家并不适用。专家不遵守规则,他们制定规则。
于是问题就来了……
首先,AI 的训练目标里压根就没有“代码可维护”这回事。比如,任何强化学习都需要一个能即时测量的奖励信号,而不是几个月甚至几年后才见分晓的东西。AI 从面向初学者的规则手册里学规则,从现实世界的代码里找模式——而说实话,现实世界里的大部分代码都挺烂的。可维护的代码没法定义适应度函数,至少我们找不到,否则早就写进 linter 里了。
你有没有注意到 AI“简化”代码的水平有多差?对,就是那些 SOTA 模型。它连函数都定义不好,只会把函数拆成更小的函数,而这些小函数根本不可复用。从一个更大的函数里抽出一个小函数,如果理解大函数还得去读被抽出来的小函数的实现,那就是个糟糕透顶的选择。定义可复用、能让代码更清晰的函数是一门艺术,需要功力。大多数开发者按 Dreyfus 模型还停留在 “高级初学者”阶段,定义不出好的、能让代码更清晰的、可复用的函数,AI 目前也做不到。
如果人还能掌控局面、还能从这些错误里学到东西,那也不算太糟。但我们看到一种趋势:人们开始依赖 AI 来写代码,甚至读代码。
这些人永远到不了精通,因为他们不再做选择,不再为编码中的错误负责,也不再从错误中学习。现在犯错的是 AI,AI 不会从这些错误里学习,依赖 AI 写代码的人也不会。
唉。
别误会,我认为 LLM 是个好工具。我不是卢德分子,我在日常工作里已经用上了 AI,还把自己学到的东西教给同事。那些无聊透顶、消耗灵魂的破事,我很乐意交给 LLM 去处理。效率上的提升我也确实享受到了。但说到底,它只是个工具,和所有其他革命一样,它的光芒终会褪去;在我看来,已经开始了——现在的科技新闻实在无聊得很。
人类其实很不擅长预测。我相信未来会让我们所有人大吃一惊。不过,我还是要做一个自己的预测……
未来会有越来越多的公司自豪地把“NO-AI”政策当作竞争优势来炫耀。而且他们是对的。
“可自动化流水线总是更高效啊”,人们这么说。但软件行业是个例外:我们一直在做大规模自动化,我们做的每一件事都是自动化,LLM 并不是实现它的唯一手段,而且视具体情况而定,它甚至可能是一种干扰。“编程问题并没有被解决”,在任何有意义的意义上都没有。当然,你可以让 LLM 给你造一个 C/C++ 编译器,或者你直接 clone GCC 或 LLVM,还能免费得到一个更好的 C/C++ 编译器。也许有比重新发明同样的 CRUD 应用更好的方式来花我们的时间和资源(人类的需求和欲望是无穷的,永远不缺新的目标可做)。
如果人们和公司不开始负责任地使用它,后果将会到来。