如何看待王垠对 Cursor 等 AI 编程的评价「不懂计算机科学的人用好 AI 编程是妄想」?

1266 👍 / 76 💬

问题描述

原文:

全文转载:

现在网络上真是太多误导了,说 AI(LLM) 编程太厉害,一行代码没写完成了项目之类。根据我之前用 ChatGPT,Claude,Copilot,最近用 Cursor 的大量实际经验,不懂编程的人想要用 AI 作出成功的项目,几乎是妄想。
会编程,但不懂真正的计算机科学,不懂如何写出极其简单,逻辑精密的程序的人,想要靠 AI 写出“王垠级别”的代码,当然也是妄想。

Cursor 这个月给我生成了 6 万多行代码,猜我接受了多少行?不到 5000 行。经常走偏方向,大量重复同样的逻辑而不懂合理抽象,甚至把我经过反复手动调整本来正确的部分改错,把我给它纠正过的地方又改错,写一大堆复杂的测试把自己套进去,最后无法明白为什么测试“不通过”……

几天前创建的一个新项目,耗费我 20 多个小时的“口舌”,最后生成 2 万多行代码,复杂到无法修补,我不得不决定完全推翻重来,它居然还在欢呼“成功了!” 并列出一项项的“成果”,对完全没道理的基本错误视而不见。一遍遍地给它指出问题没解决,然后它一次次的回答“哦,我知道了!”,“这次我找到问题的根源了!”结果全是画饼…… 因为实在没法改对了,只能自欺欺人吧?

你说目标不要定太高太快了,要有策略。我们一点点的从最基本的小函数开始写,一步步的进行,它就能做对吗?我发现它连小块的代码也不一定写的好。有些几行的小函数都要我纠正多次,它才能改对。然后说不定将来什么时候它又把它们改错了,所以你得盯着它,你得懂什么代码看起来是对的。

但知道什么样的代码是好的对的,这就是最难的事情。没有深入的研究和很多的经验,是无法知道的。是的 AI 现在成了码农,我成了 VP。但一个不懂计算机科学的 VP 领导着一群写面条代码的码农,能做出什么好东西?呵呵,我看着一个个的公司里存在的类似现象,就明白了。不知道手下的人在做什么,不知道谁说的是对的,不知道下一步该做什么。有多少 VP 是在瞎蒙乱撞,坑蒙拐骗,我都是清楚的。

所以有了 AI 还是没用,因为你没有能力驾驭它。你没有资格做 VP。

因为世界上绝大部分的代码都是平庸的面条代码程序员写的,训练数据都是那样,所以 AI 几乎没法写出“王垠级别”代码,也是意料之中的。我发现把我写好的代码给 AI,它确实能进行一些有用的分析和改进,但完全从头开始写的话,AI 真是寸步难行。几乎每一个小的函数都需要我反反复复多次的纠正,才能达到我期望的简单和可理解程度。

我的计算机科学班里的代码,全都是极其精辟的代码,跟普通公司的代码有着天壤之别。所以上我的课的同学,是没什么希望使用 AI 来完成练习的。因为数据量太少,没有训练数据啊,所以 AI 恐怕永远也无法达到这种精辟程度。当然毕业之后,同学们的水平都远超 AI,也远超作为 AI 训练数据来源的那些平庸程序员。

这就是为什么我的课程叫做“计算机科学”,而不是“编程”。计算机科学家和程序员/软件工程师是有巨大差别的。AI 也许能取代普通程序员,却永远无法取代计算机科学家。它只能被计算机科学家利用,作为他的工具。

别误会了,我其实觉得 AI 是很好的东西。使用它们的时候,显然我解决问题的速度加快了很多,很多烦人的事情不用我亲自去管了。这就是为什么经历了这么多次失败我仍然继续使用它们。但你必须明白,AI 只是把人的能力翻倍了而已,如果你的能力是 0,无论乘以多少都仍然等于 0。

本来我不想掺和的,但是王垠描述的这个现象违背了我这里的编程信道论:

现代编程框架是否让人离计算机原理越来越远?

简单快速介绍下,我提出的编程熵论认为,从汇编到高级语言,再到现代框架,整个软件工程的演进方向时完全正确的。

语言、库、框架系统性地消除了实现细节的噪声,从而让程序员更专注于业务逻辑这一核心信号。

但是矛盾之处在于 AI 编程似乎是这条路线的终极形态,那为何反倒需要懂计算机???


简单的解释就是传统编程只有一个信源,那就是程序员自己。

而 AI 编程里有两个信源,LLM 其实也是一个信源,这个额外的信源其实是个干扰源。


传统编程

软件工程的百年历史,本质上是一部与熵作斗争的历史,根本目的很明确:

将人类模糊高熵的意图转化为机器可执行的零熵指令。

为此,不断发明新的语言、库、框架、乃至方法论,其核心目标也很清晰:

在转化过程中,尽可能地降低由人类程序员承担的熵减负荷。

经典编程范式通过引入确定性信道来达成此目标,语言、库、框架的价值在于压缩了编码实现熵所需的码长。

编程语言的语法、编译器的行为、框架的API,都是高度确定性的。

任何输入代码其输出的行为必定是可预测、可复现的。

每一步操作,每一个API调用,都要有一个固定且可预测的结果。

系统的总熵由程序员全权负责,并可以通过编写越来越详尽的代码来逐步消除。

总而言之,传统程序员的核心任务就是进行信源编码,将业务逻辑和实现细节编码为信道能够无损传输的符号序列,也就是代码。


LLM 编程

然而,以 LLM 为基础的AI编程工具是一个概率性的生成式信源,它自身就是一个熵源。

虽然我们获得了一个前所未有的强大智能编码器,但驾驭这个工具所需的认知负荷,反而可能更高。

假如将AI编程工具视为为一个概率性信道:

与确定性信道不同,这个信道的输出不是唯一的。

给定同一个输入 X,每次生成的代码 C_{\text{AI}} 都可能不同,其行为可以由一个条件概率分布 P(C | X) 描述。

数学上来讲,AI工具实际上是从这个分布中进行采样,得到一个具体的输出:

\begin{aligned} C_{\text{AI}} \sim P(C|X) \end{aligned}

这个条件概率分布 P(C|X) 据贝叶斯定理,可以将其展开:

\begin{aligned} P(C | X) = \frac{P(X | C) P_{\text{model}}(C)}{P(X)} \propto P(X | C) P_{\text{model}}(C) \end{aligned}

这里的似然项 P(X | C) 代表了『代码 C 能否很好地实现提示 X』。

如果代码 C 的功能与提示 X 的描述高度一致,那么这个似然概率就高。

而先验项 P_{\text{model}}(C) 代表了『代码 C 本身在模型看来有多常见』。

这个先验概率完全由AI的训练数据决定,几乎是根生蒂固的。

AI的最终输出,是这两个概率乘积的权衡结果。

王垠编程

王垠的脑中有一个目标,他想要一段高度抽象的专家级代码 C_{\text{expert}}

他通过 Prompt X 试图引导AI生成这段代码。

与此同时,世界上存在着大量冗余的、复制粘贴乱改的垃圾代码 C_{\text{mediocre}}

不管怎么说它们也能在功能上满足特性的需求 X

王垠的困境在于世上绝大多数代码都是垃圾,而专家级的精炼代码极少:

\begin{aligned} P_{\text{model}}(C_{\text{expert}}) \lll P_{\text{model}}(C_{\text{mediocre}}) \end{aligned}

带入贝叶斯公式,可以得到最终的后验概率:

\begin{aligned} \underbrace{P(X | C_{\text{expert}})}_{\text{可能较高}} \cdot \underbrace{P_{\text{model}}(C_{\text{expert}})}_{\text{极低}} \ll \underbrace{P(X | C_{\text{mediocre}})}_{\text{可能较高}} \cdot \underbrace{P_{\text{model}}(C_{\text{mediocre}})}_{\text{极高}} \end{aligned}

所以 AI 不是在偷懒,也不是不懂编程,只是统计规律锁死了 AI 的思维模式。

王垠 20 多个小时白费口舌,本质上是在与这个顽固的先验概率 P_{\text{model}}(C_{\text{mediocre}}) 作斗争。


王垠和很多程序员都试图通过一系列交互来驯化一个顽固的概率模型。

设程序员的真实意图为 \mathcal{I},这对应一个理想程序 \mathcal{C}

迭代 t=0

程序员将意图 \mathcal{I} 编码为初始提示 \begin{aligned} X_0 = \text{Encode}_p(\mathcal{I}) \end{aligned}

这个过程本身就有信息损失,引入了编码熵 H(\mathcal{I} | X_0)

对于一个完全不懂计算机科学的人,其 X_0 往往是不完备的,导致这个熵非常高。

然后AI根据 X_0 从其条件概率分布中采样,生成初始代码 C_0

同时,由于 LLM 这一信道的不确定性,这里又引入了生成熵 H(C | X_0)

迭代 t \to t+1

接着程序员会观察 C_t,并将其与内心真正的意图 \mathcal{I} 进行比较。

他需要估算一个语义距离或误差 D_s(\mathcal{I}, C_t),这个距离是多维度极端抽象的,包括但不限于逻辑正确性、性能、可维护性、抽象程度等。

王垠这样的专家能够精确地计算 D_s(\mathcal{I}, C_t),并定位误差的来源。

他看到2万行代码,立刻意识到 D_s 巨大,系统已经发散,没有修改的必要。

但是外行无法估算 D_s,他的评估函数非常的单一,就是程序能否运行。

这个度量非常粗糙且具有误导性,他看到程序跑起来了就误以为 D_s \approx 0


接着,基于评估出的误差 D_s,需要给出一段反馈信息 F_t,这个反馈本质上来说其实是用来修正AI传输过程的纠错码。

反馈的形式多种多样,懂计算机原理的话,就可以指出:

  1. 『这里漏判断了,在用户输入下会出错。』
  2. 『这些重复代码可以抽象成一个函数。』
  3. 『这里性能会有问题,可以加哈希表打表。』
  4. 『不要这样改!』
  5. 『我说了!不要这样改!!』
  6. 『我说了!不要这样改!!照我说的做!!!』
  7. 『算了,这里我自己修好了,你修下一个吧!』
  8. 『我说了!不要这样改!不要这样改!不要这样改!』
  9. 『git reset --hard,退钱!!!!!!!!!!!』

但是外行就是无效沟通,他只能说:

  1. 《太棒了!再给我加个新功能吧!》
  2. 《你写的代码有问题,跑不了!!》
  3. 《我让你做的功能哪去了???》
  4. 《哎,上一版还有的功能,怎么现在没有了?》
  5. 《不是?刚刚还能跑!现在怎么跑都跑不了了??》
  6. 《你没懂我的意思!!!》
  7. 《我不是这个意思!!!!》
  8. 《超!超!超!超尼玛你个飞舞!!!!!》
  9. 《右键删除,退钱!!!!!!!!!!!》

然后 AI 根据人类给出的纠错码,构建新一轮的上下文。

新的提示 X_{t+1} 将包含历史信息:

\begin{aligned} \text{Context}_{t+1} = (\text{Context}_t, X_t, C_t, F_t) \\ X_{t+1} = \text{UpdatePrompt}(\text{Context}_{t+1}) \end{aligned}

接着,AI 再次采样,在新的更丰富的上下文 \text{Context}_{t+1} 上生成新的代码:

\begin{aligned} C_{t+1} \sim P(C | \text{Context}_{t+1}) \end{aligned}


整个过程的目标其实就是寻找到一个反馈序列 \{F_0, F_1, ..., F_N\},使得最终生成的代码 C_N 与真实意图 \mathcal{I} 之间的语义距离足够小:

\begin{aligned} \min_{\{F_t\}} E[D_s(\mathcal{I}, C_N)] < \epsilon \end{aligned}

AI 程序员

所以说,在 AI 编程中,程序员的价值可以用互信息 I(X;C) 来衡量。

互信息表示知道一个变量后,另一个变量不确定性减少的程度:

\begin{aligned} I(\mathcal{I}; C) = H(C) - H(C|\mathcal{I}) \end{aligned}

外行或者新手程序员提供的提示词 X_{\text{novice}} 与真实意图 \mathcal{I} 的关联很弱,提供的信息量少。

此时 AI生成的代码 C 的熵很高,且关于意图 \mathcal{I} 的条件熵 H(C|\mathcal{I}) 也很高。

最终的互信息 I(\mathcal{I}; C) 很低。

那么,代码虽然生成了,但和真实意图关系不大。


但是王垠这样的专家就不一样了,他们可以构造高信息量的 Prompt。

他的初始提示 X_{\text{expert}} 本身就蕴含了大量关于架构、约束和目标的精确信息,极大地降低了初始的语义熵。

随后他还可以提供高信息量的反馈,他的每一轮反馈 F_t 都最大化了对AI后续行为的引导,最大化了互信息 I(C_{t+1}; F_t)

他知道说什么话能最有效地修正AI的概率分布,使其向 C_{\text{expert}} 的方向移动。

整个AI编程过程,对于王垠来说不过是一个通过交互式的信息注入,将一个高熵有偏的概率分布 P(C|X) ,收敛到一个熵极低的以 C_{\text{expert}} 为中心的狄拉克 δ 分布的过程。

而外行缺乏提供有效信息和反馈的能力,整个过程只是在AI巨大的先验概率空间中进行随机游走,最终被巨大的 P_{\text{model}}(C_{\text{mediocre}}) 吸引子捕获,得到一个看似能跑但内部一团糟的熵增产物。


所以 AI 程序员要有什么能力呢?

他需要将模糊的业务意图 \mathcal{I} 转化为一个低熵的、机器可理解的、无歧义的形式化描述 X

接着面对AI生成的大量代码,需要快速估算其与真实意图 \mathcal{I} 的语义距离 D_s

最后设计一个最优的反馈序列 \{F_t\},以最高效的方式引导 AI 收敛到目标。

发散的时候快速回退、删除、重随,不要在错误的路线浪费过多的精力、金钱、以及最宝贵的时间。


天之杯

LLM 见证了无数的垃圾代码,蕴含了此世一切之恶,成了扭曲愿望的黑圣杯。

一个不懂计算机科学的麻瓜,就如同一个没有魔术回路的凡人,妄图触碰根源,许下自己的妄想。

圣杯给出的回应只会是蕴含无穷的信息熵的精神污染,把混乱的愿望放大千百万倍,最终得到一团蠕动的肉块,看似能运行,实则毫无意义。


而掌握了计算机科学的魔法使给出的 Prompt 并不是祈愿,而是咏唱。

以自身对『理』的理解『调律』,不断对根源流出的代码进行观测与修正。

最终,将灵魂中的意志的完美地物质化,此即『第三法·天之杯』!