在Vibe Coding里,程序员把"我思"交出,换来"它跑起来了"的信号,可这信号无法替代统觉、综合与理解,它正在批量生产没有主体的代码和程序员,这究竟意味着什么?
一
康德把知识分成两个来源。直观接收杂多,知性提供范畴。知识是两者结合。没有概念的直观是盲的,没有直观的概念是空的。
Vibe Coding在制造一种新的断裂。不是盲目的直观,也不是空洞的概念。是概念和直观被隔开了。两头都在,就是没在同一个主体里合上。
这不是一个比喻。程序员描述一个需求,AI吐出代码,程序员运行,报错,把错误丢回去,AI改,程序员再运行。循环几次,代码跑起来了。程序员做了什么。他没有设计系统,没有画架构图,没有想过模块怎么划分,没有想过接口怎么定义。他接收了一堆代码,按"能不能跑"这个信号决定接受还是拒绝。
他接收的这堆代码,就是孤立的、未经他理解的、彼此之间缺乏内在关联的碎片集合。
二
传统编程里,程序员同时握着两样东西。一样是"做什么",一样是"怎么做"。两权合一,代价自付。他在写代码的过程中,把概念和直观结合起来。他看到自己写的每一行,理解它为什么这样写,知道它在整个系统里的位置。代码是被他统摄过的对象。
Vibe Coding交出去的是"怎么做"。程序员以为自己只交出了翻译权。但他实际交出的,是结构性决策权。AI在生成代码的时候,同时决定了模块怎么分、依赖怎么排、错误怎么处理、变量怎么命名。这些决定,程序员事后才看到产物。而且越来越多的时候,看都不看就接受了。
他保留了概念,prompt。他失去了直观,对实现的直接接触。概念和直观之间的通道,被AI截断了。
三
杂多需要一个主体来综合。康德叫它先验统觉。"我思"必须能够伴随我的一切表象。否则那些表象就不是我的表象,只是一堆与我无关的碎片。
传统编程里,"我思"伴随代码的每一步。程序员知道为什么这里要加判断,知道那个抽象是为了什么,知道这个接口为什么这样设计。代码是被"我思"统摄过的对象。
Vibe Coding里,这个统摄没有发生。但问题不是"我思"被掏空了。程序员还在思。他想清楚了要什么,写下了prompt,运行了代码,判断了结果。他的"我思"一直在场。
问题是,"我思"只停在prompt这一层。代码那一层,他没有思过。他看到的是运行结果,不是逻辑结构。代码对他来说,不是"我的"代码,是"它"生成的代码。统觉在概念端在场,在直观端缺席。概念和直观之间的综合,没有发生。
"它跑起来了"这个信号,替代不了综合。康德会说,概念和直观被隔开了。两头都在,就是没在同一个主体里合上。
四
代价去了哪。
程序员当下获得了确定性,代码能跑。代价没有消失,它被推迟了、被分散了、被隐藏了。
第一层,认知代价转嫁给未来的自己。当下不审、不理解的代码,bug出现的时候,程序员面对的是一个自己不理解的黑盒。修复成本指数级上升。
第二层,结构代价转嫁给代码库的熵。AI每次生成都是在局部做正确的事。但每次局部正确都在累积全局的结构性债务。这跟Goodstein序列的悲剧类似。每一步看起来都遵循规则,整体走向不可逆的崩溃。
第三层,责任代价转嫁给带宽不足的审核者。质量把控的责任从写代码的人转移到了审代码的人。但审核者的带宽没有增加。
第四层,行业基线。当足够多的人开始Vibe Coding,整个行业的代码质量基线被系统性拉低。它转嫁给下一个接手代码库的人,转嫁给使用软件的用户,转嫁给五年后整个行业的维护成本。
五
有人会说,Vibe Coding不是单向的权力转移,是双向的。人收束AI的输出,AI也收束人的意图。
这个说法不对。或者说,不够准。
AI没有意图,没有定义权,它没有"侵蚀"人的能力。真正发生的是,人在使用AI的过程中,主动把自己的定义权一点点交出去,然后自己承受这个交出的后果。
不是AI侵蚀了人,是人在自我侵蚀。AI只是一个工具,侵蚀的动作是人在做。
这个区别很重要。它决定了责任归属。如果说双向侵蚀,责任是模糊的。如果说自我侵蚀,责任是清楚的。是你自己交出去的。
Karpathy的翻车不是因为他不够聪明。是在Vibe Coding的结构里,没有任何一个行动者完整持有定义权,因此没有任何一个行动者能承担完整责任。"它跑起来了"这个信号太弱,无法替代真正的理解。
六
知乎上那些解决方案,spec coding、上下文管理、原子化commit,试图重新建立定义权的边界。
但每一个约束都需要一个维持者。Spec coding需要人写spec,上下文管理需要人维护上下文,原子化commit需要人拆分提交。每一个约束都是一个新的收束操作,每一个收束操作都产生新的代价。而这些代价的接收端,还是程序员自己。
这是自指困境。收束体试图通过增加约束来对抗自身的熵增,但每个约束本身就是一个新的收束操作,产生新的代价。约束越多,代价越大。最终约束本身变成了熵增的主源。
这和九头蛇的结构是同构的。你砍一个头,它生出更多。你加一个约束,它产生更多代价。
但这里有一个前提需要审视。约束是外部强加的吗。老程序员的代码直觉也是约束,只是内化了。它不再是需要外部维持的收束操作,它已经变成了习惯。约束变成习惯,代价变成技能,这是熟练度发生的路径。
但这条路径并非免费。它不是编程独有的,它是所有技能习得的普遍条件。外科医生、音乐家、棋手,全部遵循这三条:反馈周期短,能看到全貌,重复次数够。
Vibe Coding恰好在这三条上都反向。反馈是"跑不跑",全貌是"我prompt里说了什么",重复是"每次都换一批代码"。
但这还不是"结构上被阻断"的精确含义。精确含义是:Vibe Coding切断了行动和后果之间的直接映射。 你写的是prompt,AI生成代码,代码运行,报错。你看到的是"它跑不跑",不是"它为什么跑"。后果和行动之间的映射被AI截断了。你无法从后果反推行动的正确性,因为行动和后果之间隔着一个你不理解的黑箱。
内化的前提是反馈回路闭合。Vibe Coding的反馈回路被AI截断了。截断不是疏忽,是结构性的。只要AI在行动和后果之间充当黑箱,内化就无法发生。
这不是"可能做不到",是"结构上做不到"。宿命不是因为没有人在做,是因为结构不支持人在做。
七
程序员的带宽是有限的。代码库的复杂度是无限的。用有限的带宽去约束无限的复杂度,必然失败。
这不是因为程序员不够努力,不是因为工具不够好。这是结构性的。《确定性的代价》这本书中早就证明:有限者不能直接承载无限。它必须通过分形结构,把无限分解为层层嵌套的有限份额。
但Vibe Coding做的事情是反过来的。它把复杂度的生成权交给AI,让复杂度以无限的速度膨胀,然后用程序员有限的带宽去审核。这不是分形结构,这是单层结构。单层结构里,无限除以无限是未定式。审核者不知道自己审核了多少,不知道自己漏掉了什么,不知道系统的复杂度到底有多大。
Vibe Coding的结构性缺陷,不是它不够好,而是因为:它是单层的。
八
传统屎山是单一模糊意图。一个人写的,水平有限,但至少有一个主体在统摄。接手的人可以通过梳理代码反推那个意图,虽然痛苦,但有可能。
Vibe Coding屎山是多源异质意图的拼接。prompt的作者是一部分主体,AI的采样过程是一部分主体,审核者的放行是一部分主体。三部分谁也不认识谁,谁也不为整体负责。代码不是无主体,是主体不可逆地碎片化了。
这个区分影响诊断。如果问题是无主体,那就没得救。如果是碎片化,至少知道病灶在哪。三个来源之间的整合断了。
理解从来是分层的。传统编程里,你调mbedtls的加密函数,你没读过源码,但你理解它的契约。你靠接口和文档跨层沟通。理解是分布的,不是集中在一个人脑子里。
Vibe Coding的问题是理解被压缩到了prompt这一层。下面全是黑盒。盲区不是更多,是位置更危险。失效的地方,就是你不知道的那一层。
九
康德的框架给Vibe Coding的分析补上了最根本的一层。这不只是定义权的问题,这是概念和直观被隔开的问题。
定义权的让渡,本质上是综合环节的外包。程序员把概念和直观的结合交出去了,换来了"它跑起来了"这个信号。但这个信号不是知识,它只是杂多的一个外部标记。它不能替代综合,不能替代理解。
Vibe Coding生产的是屎山,但屎山还不是它最深的危机。它最深的危机是,它正在批量生产一种新的主体形态:概念端在场,直观端缺席的程序员。
代码不是无主体,是主体碎片化了。prompt的作者是一部分主体,AI的采样过程是一部分主体,审核者的放行是一部分主体。三部分谁也不认识谁,谁也不为整体负责。
程序员不是感官接收器。他的"我思"一直在场,只是停在了prompt这一层。下面那一层,他没有思过。他的统觉在概念端亮着,在直观端熄灭了。
而你无法用半盏灯去维护一座屎山。因为维护需要理解,理解需要综合,综合需要概念和直观在同一个主体里合上。那个"我"不在场的时候,一切都在场,唯独没有人在。
系列深度文章的导读入口:
请关注作者不失联,谢谢。