来源:市场资讯
(来源:图灵人工智能)
您想知道的人工智能干货,第一时间送达
近期,一篇题为(Against Vibes: When is a Generative Model Useful)的博客,在全球知名创业者、开发者社区 Hacker News 上引发了广泛讨论。
博客链接:
https://www.williamjbowman.com/blog/2026/03/05/against-vibes-when-is-a-generative-model-useful/
作者为英属哥伦比亚大学计算机科学助理教授 William J. Bowman,他一针见血地写道:“令我沮丧的是,当人们声称智能体(agent)非常有用时,却无法说明其何时、为何、如何真正有用。”
Bowman 的研究方向聚焦于让程序员能够更准确地向机器表达意图,并在编译过程中完整保留这种意图,具体研究领域包括安全与验证编译、依赖类型编程、程序验证、元编程和互操作性等。
这一研究背景,让他对当下生成式模型热潮的质疑,显得不那么苍白无力。
在这篇文章中,Bowman 并没有讨论 AI 的伦理或社会问题,而是直指一个更基础的问题:生成式模型,究竟在什么时候才是有用的?“我真正想知道的是,生成式模型在什么时候才是有用的。我不想只是“感觉它们有用”,那只是一种 Vibe。”
核心观点如下:
判断生成式模型是否有用,不是一种 Vibe,而是一个需要科学建模的工程问题。
判断生成模型是否有用,需要同时考量三个维度。相对编码成本、相对验证成本、以及任务是否依赖过程本身而非仅仅依赖产出。
生成式模型的“可信度”恰恰是其最大的风险所在。输出看起来合理并不等于正确,而这种似是而非的输出会大幅提高验证成本,尤其在复杂任务中。
使用生成式模型仍然需要领域专业知识。没有专业知识的用户,根本无法判断输出是否满足要求。
对于过程本身具有价值的任务,生成式模型无法替代。学习、研究、工程设计,这些任务的意义不只在于产出,更在于完成过程中所创造的知识与能力。
学术头条在不改变原文大意的情况下,做了简单的编译。全文如下:
假设我想回答这样一个问题:工具 X 对于任务 Y 是否有用?
如果我用科学方法来回答这个问题,我会分析工具 X 的性质并建立一个模型,同时分析任务 Y 及其需求并建立另一个模型,然后利用这些模型来预测:在任务 Y 的情境下,工具 X 的行为会是什么样。
例如:
“我可以用木材代替不锈钢作为这个结构的支撑梁吗?”
“这种酸能否作为该化学反应的合适溶剂?”
“这种编程语言能否提供所需的实时性能保证?”
然而,围绕生成式模型的讨论却不是这样的。相反,你听到的是诸如“软件工程已死”(software engineering is dead)之类的论断,以及不加思考地把生成式模型塞进一切场景中的尝试。
搜索?生成式模型。
代码补全?生成式模型。
摘要生成?生成式模型。
语音转文本?生成式模型。
库存图片?生成式模型。
任何对此提出批评的尝试,往往都会陷入循环争论,或者变成各说各话。
生成式模型对互联网搜索有用吗?
嗯,它确实能生成一些看起来与输入提示相关的文本。
然后呢?
这并没有回答问题。
人们又会说:最新的模型已经好得多了!
好在什么方面?
当有人称之为“提示工程”(prompt engineering)时,我对此感到很沮丧,因为我没有发现任何工程的迹象,而是一系列关于如何在特定模型的特定版本中措辞提示的 Vibe(氛围),这有时会产生与输入提示看似相关的输出,因此也可能与你的预期接近。
如今更令我沮丧的是,当人们声称智能体(agent)非常有用时,却无法说明其何时、为何、如何真正有用。他们能提供的,通常只是一些感觉自己更高效的 Vibe,而这种 Vibe,其实已经被真实的科学研究所质疑:当把客观生产率指标与主观报告进行对比时,两者往往并不一致。
或者,他们只会举一些例子,说系统生成式了大量看起来合理的输出。
(当然,也确实有一些研究者在做真正的科学研究,并发表论文。我这里谈论的,是当这些技术被迅速引入学校、工作场所等现实环境时,人们所使用的那些论证方式。)
我真正想知道的是,生成式模型在什么时候才是有用的。我不想只是“感觉它们有用”,那只是一种 Vibe。从一开始,我基本上就是一个生成式模型的怀疑者。我一直无法说服自己相信生成式模型是有用的。但同时,我也对自己的主观体验持怀疑态度。
我可以想象:一个能够从自然语言生成代码的模型,在某些我尚未发现的使用场景中,可能确实是有用的。我相信,应该存在某种模型,能够回答这样的问题:在什么条件下,生成式模型 X 对任务 Y 是有用的。
本文不涉及伦理、政治或社会层面的问题,只谈论与技术本身的能力问题。
仅作背景说明:我认为,这项技术如此广泛的部署是极其有问题且不负责任的,在当前规模下继续对其进行投资,几乎是一种接近犯罪级别的受托责任失职,且很可能造成经济损害。我也认为,这一切背后的伦理问题令人深感忧虑。
但就目前而言,我只想弄清楚一件事:从技术上看,它们到底能够做到什么。
将生成式任务编码为提示词与直接产出 artifact(成果)相比,其成本如何?这是一个涉及任务、模型和用户三者的函数。
验证生成 artifact 是否满足要求与直接产出 artifact 相比,其成本如何?这主要是任务和用户的函数,但也涉及生成式模型本身。
任务在多大程度上依赖于产出物本身,而非依赖于产出过程?这是任务本身的函数。
这三个因素分别触及了许多人曾经讨论过的问题。但我认为,只有把这三点同时考虑,才是关键。这样一来,我们才能以一种更科学的方式来讨论生成式模型的使用问题。
如果你想要宣称某个新模型“更有用”,必须明确所有这些变量:需界定任务类别,并证明对特定用户群而言,编码成本低于直接产出 artifact;或即使编码成本更高,但验证设计要求的成本更低。
更重要的是,如果我想预测一个生成式模型是否会有用,我现在有了一个可供使用的模型框架。
我的模型预测:随着任务复杂度的增加,生成式模型的有用程度可能会下降。原因在于,生成式模型本质上是概率性的。因此,当任务的要求变得更加复杂时,其输出满足要求的概率会降低,尤其当要求偏离训练数据的常见模式时。更糟的是,当要求与常见模式存在细微差异时。验证复杂要求同样困难,其难度远高于让人类遵循良好工程流程产出易于验证的输出。
另一方面,当出现以下情况时,生成式模型应该是非常有用的:直接创建 artifact 对用户来说很困难,但验证 artifact 却非常容易。这种情况可能出现在需要交叉引用极其具体信息的 artifact 上,这对用户来说耗时费力,但一旦完成,验证起来却很容易。
还有一种情况是:生成式模型被集成到形式化验证系统中,验证过程高度自动化且非常可靠。在这种情况下,用户甚至不需要理解生成的 artifact,系统就能自动验证其正确性。
但总体来说,如果是一个领域新手试图生成复杂的 artifact,这种模式通常不会成立。因为用户缺乏足够的专业知识,无法判断生成结果是否真的符合要求。
这预示着:使用生成式模型的人仍然需要具备领域专业知识。
该模型还预测:对于高度依赖过程的任务,生成式模型基本上是没有用的。原因是,生成式模型所能做的,只是通过一个黑箱过程生成 artifact。
相对编码成本
许多支持生成式模型有用性的论点,本质上都是在谈相对编码成本。要让生成式模型真正有用,将任务编码为提示词的总成本,必须低于直接生成 artifact 的总成本。
总编码成本包括两部分:编写提示词所投入的全部精力,以及运行提示词所消耗的全部算力。如果一项任务很容易用提示词表达,总编码成本就低。如果一项任务不仅容易写成提示词,直接完成又繁琐或困难,那么相对编码成本就更低了。
随着模型能力的提升,更复杂的提示词也能被轻松表达:可以使用语义密度更高的提示词,参考训练数据中更多的信息。一个能够在初始提示后自动优化或重试任务的 Agent,也许只需一条简单的提示,就能完成一项复杂任务。
然而,上述两种情况都会增加提示词的算力成本,有时甚至大幅增加,从而推高总编码成本。更“强大”的模型或许能以更高的概率生成正确输出,从而减少因补充信息而反复调整提示词的成本(即“提示词工程”),并可能降低验证成本。
此外,随着用户能力提升,其直接完成任务的速度可能远超引导模型完成的速度,从而推高相对编码成本。
有人或许会说,最新的模型“更强大”了,或者“真的智能”了,诸如此类。但这些说法,本质上都是不科学的论断。
这些说法的科学表述应该是:“对于某一类任务,新模型的总编码成本低于旧模型。”如此表述之后,很明显这仍然不意味着新模型是有用的。
就我自己的大多数任务而言,相对编码成本一直都很高。我的许多软件工程任务是构建小型、语义密度高的程序,具有非常具体的设计需求,使用的语言比英语更简洁,而我能够流畅地书写这种语言。系统地设计并实现这样的软件,比把需求规格编码成一条生成式模型的提示词,要快得多。
举个例子,我曾尝试用 Claude Opus 4.6 生成一个程序,用于解析我自己为排版语法所设计的一套自定义 DSL,并生成对应的 Haskell 类型定义。经过 8 小时的提示词交互、消耗了数百万个 token 之后,它生成的代码仍然完全没有用。代码通过了我在提示词中给出的测试,但只要看一眼代码本身,就能轻易发现类型错误,以及专门针对测试中特定标识符做特殊处理的逻辑。标识符清理部分的逻辑一团糟,还会偶尔生成空字符串。而一个正确的实现,我自己写也不过三四百行代码,肯定用不了 8 小时。
当然,并非所有任务都是语义密集、设计要求严苛的代码编写。再举个例子,我最近想安装一个软件包,但忘了它的名字。我给模型写了一条极其简单的提示词:“安装那个 x11 的假 GUI 工具。”如果我自己来完成这项任务,需要做大量繁琐的工作,还会遇到许多偶然复杂性。我得先上网搜索这款软件的名称,再对照我所运行的操作系统发行版及其包管理器的命名规范进行交叉查询,还可能需要查一下这个包管理器的具体安装命令,最后再编写并执行一段 shell 脚本来完成安装。而借助 Agent,我用一条极易写出的提示词就完成了所有这些步骤。这项任务的相对编码成本极低。
相对验证成本
一些关于生成式模型的论点聚焦于验证问题:“随着越来越多的代码被生成,形式化验证将变得更加重要。”我认为这类论点同样缺乏科学性。验证本身并非魔法。以某种方式设计的软件可能比以另一种方式设计的软件更易于验证。一个亲自精心设计并实现了软件的用户,往往比一个被直接丢进一个完全由生成代码构成的代码库里的用户,更容易完成验证工作。
这一切都取决于任务、用户,以及模型的生成能力。就我那条“安装某个包”的提示词而言,验证几乎不费任何力气。正确的命令一眼就能认出来,而且就一行。
相对验证成本也会随任务规模的增大而上升。如果你生成的是一行脚本,没什么问题。但如果你试图生成一个体量庞大的成果,你很快就会对逐条核查每一个命令、每一处改动感到厌倦。你根本不可能检查每一行生成的代码。你将不得不寻找其他方式来验证输出。而这,又是一笔额外的成本。
相对验证成本同样取决于用户本身。如果我让模型生成 Racket 代码,一门我非常熟悉的语言,我可以很快判断生成代码的设计与实现是否合理。但如果我试图让模型生成 C 代码,我还不如直接自己写,按照系统化的方法写出安全的 C 代码,然后在沙箱里运行,再跑几个内存检查工具。
相对验证成本在一定程度上也取决于模型的能力。我早期实验过的一些模型会生成垃圾代码,不只是设计糟糕的烂代码,而是犯下一些基础到我根本不会想到去检查的错误:生成括号不匹配的 Racket 代码,引用根本不存在的函数,诸如此类。这类错误跑一下编译器就能发现,倒还好说,但那些没那么容易发现的错误呢?
相对验证成本的一个关键所在,是生成式模型输出的是“看似合理”的内容。说模型生成了“正确”或“错误”的输出,或者说它“犯了错误”,这些表述其实都不准确。它做的,恰恰就是它被设计来做的事:以某种方式,生成在统计上与输入提示词相关的输出。注意,这不是“统计上正确”,只是“统计上相关”。从某种意义上说,所有输出都是“正确”的。因为它本来就只需要是“与提示词相关的分布中的一个点”而已。也许你生成的 C 代码大多数时候都有内存错误。但现实中大多数 C 代码本来就有内存错误。也许你生成的用于安装软件包的 bash 脚本大多数时候都是对的,因为网络上大多数用于安装软件包的 bash 脚本,本来就是对的。
生成式模型输出的“看似合理性”,会大幅提高相对验证成本。因为这些输出本质上是被优化成“接近正确”的样子的。我预测,随着模型变得越来越复杂,相对验证成本可能会上升。我们在生成代码中可能遇到的错误类型,将与我们在人工编写的代码中习惯查找的错误类型截然不同:生成代码中的错误往往是隐蔽的。随着模型能力的提升,你可能越来越倾向于信任它的输出,也因此越来越难以察觉这些隐蔽的错误。形式化方法或许能降低这部分成本,但形式化方法本身并不廉价。没准让一个工程师老老实实跟着设计流程走,反而是更划算的选择。
对于某些任务,验证输出结果可能根本无从实现,或者至少,不重新做一遍你原本想用生成式模型来替代的工作,就无从验证。我认为互联网搜索就是一个很好的例子。你向生成式模型提出一个你自己不知道答案的搜索问题,它给出的回答本质上是无法验证的。除非你亲自去查找可信的信息来源,核实它的摘要是否准确。而一旦你这样做了,生成式模型所做的那些工作,就完全白费了。
Artifact 与过程
有些任务,重点根本不在于产出。或者说,不只在于产出,它们还要求产出必须经由特定的过程来完成。
教育领域有一些显而易见的例子。我不需要学生们把阶乘运算重复计算上亿次,因为我需要的是一个阶乘运算的实现方法。他们实现阶乘,是因为经历这个过程本身,会在他们脑子里创造出知识。编写代码和阅读代码,是两种本质上截然不同的过程,正如撰写这篇博文和阅读这篇博文,是两种本质上截然不同的过程。
这篇博文本身,就是一个过程驱动型任务的例证。我在写这篇文章。我的双手正在敲出出现在这篇文章里的每一个字。它们不是在输入提示词、驱动某个生成式模型吐出一堆看似相关的文字。原因很简单:我的目标不是创造一篇博文。我的目标是创造知识,先在我自己内部,然后在读者内部。写这篇文章的过程,就是我把所有细节想透的过程。
过程驱动型任务在工程领域同样普遍存在。某些工程工作要求必须遵循特定的流程,因为只要流程得到遵守,最终结果就能满足某些特定的性质,而这些性质仅凭观察 artifact,往往难以验证,甚至根本无法验证。举个例子:某家大型公司,也许会禁止工程师向开源项目贡献代码,将其作为软件工程流程的一部分,以规避知识产权风险。而仅凭审查工程师写出的代码本身,你根本无法保证这些风险已被彻底排除。
反对生成式模型的“过程论”论点很常见,大致是这样的:“X 涉及人类沟通或创造力,因此生成式模型不能用来创造 Y。”我对这个论点深有同感,因为我认为,太多东西正是在漠视过程的情况下被生产出来的。
但确实存在一些任务,我真正在乎的只是输出结果。我之前那个 shell 脚本的例子就是如此:我不在乎软件包是怎么被安装上的,我只在乎它装好了没有。(*当然,前提是这个输出不是通过某种真正有问题的过程生成的,好吧……但那是另一篇文章的话题了。)
写作也是如此。我在手动写这篇文章,是因为过程本身很重要。但有些写作是纯功能性的。举个例子:我曾用生成式模型起草一份政策文件。政策文件没有什么需要创意的结构,它的作用就是表达一套规则。我仍然在阅读和修改这份文件,因为我需要把具体内容调整得更符合我的实际情况,但从一份生成的草稿出发,确实是有用的,就像我可能会从一个现成的模板开始写起一样。
但即便产出枯燥乏味、易于验证,过程本身仍可能至关重要。初级工程师或许会写大量平淡无奇、一眼就能核查的代码。用 Agent 来替代他们,成本也许很低。但初级工程师在写那些代码的过程中,正在经历一个积累经验、建构知识、磨练技能的过程。生成式模型可以替代他们的产出,但没有任何东西能替代那个过程。
对我而言,我所写的几乎所有软件,过程都至关重要。我通常是在研究工作的框架下进行软件设计,而我亲自完成设计与实现的过程,本身就在创造知识。这些知识,我随后会与他人分享。软件不是最重要的产出,或者说,不是唯一重要的产出。我想,这也是我一直没有发现这些工具有用的另一个重要原因,也是为什么我始终难以想清楚它们究竟在哪些情况下可能有用。
我们只需要能让计算机产出有用成果的人
那么,生成式模型在什么时候是有用的?当且仅当同时满足以下条件:
将任务编码为提示词的相对成本较低(相较于以其他方式完成该任务);
(或者)验证输出是否满足需求的相对成本较低;
完成任务所采用的具体过程无关紧要。
而要准确判断这一切,模型的使用者需要对所做的工作本身、对该领域中设计需求的验证方式、以及对生成式模型和/或所用的具体模型,都有相当深入的了解。
权衡这些取舍,本身就是工程。如果你在权衡这些取舍的过程中产出软件,你做的就是软件工程。如果你根本没有考虑这些取舍,你不过是在凭 vibe 行事,而你所产出的东西,将落在“碰巧有用”与“危害极大”之间的某个位置。
这些取舍并非生成式模型所独有,但有一点是独有的是,它们使得以极低的成本生产出海量输出成为了可能。这些输出,用自然语言描述起来都显得“言之成理”。但看似合理,不等于有用。生成式模型本身,没有任何机制能够保证输出是有用的。随着模型变得越来越复杂,输出的复杂度和提示词的复杂度也在不断提高。但复杂,不等于更有用。复杂度上升的同时,成本也在上升:算力的成本、验证的成本,以及以产出替代过程所付出的代价。
我理解这些工具的诱惑。有时候,真正有价值的工作极其复杂,令人沮丧。编写软件、运行脚本、整理笔记,这些事情都可以非常繁琐。有时候这种繁琐是偶然复杂性,但更多时候,它偶然产生的复杂性。用生成式模型产出内容,很容易。但我不认为,用它们产出有用的内容,也同样容易。
整理:王江珏
热门跟贴