4. Imagine if naked people were stupider. It turns out, naked models actually are.
抱歉,不是那种裸体模特。但你现在感受到的失望?那正是 Kyle Kingsbury 对 LLM 的感受。
Kyle Kingsbury 是当今最顶尖的系统工程师之一。他的 Jepsen 项目花了十年时间,系统性地证明了分布式数据库并不像它们宣称的那样可靠。CockroachDB、MongoDB、Redis 以及其他几十个数据库,都做出了它们无法兑现的一致性保证。他把结果公开发表,厂商修复了 bug,整个行业因此变得更加诚实。Jepsen 是应用怀疑主义的杰作。
上周他发表了一篇 32 页的文章,标题是《一切的未来都是谎言,我想:关于扯淡机器的扯淡》。文章写得非常漂亮、研究深入、幽默风趣,但在最重要的问题上错了。
他的观察是正确的,但结论不对。
关于范围的说明:这篇文章只针对 Kingsbury 的技术主张——即 LLM 是不可靠的扯淡机器,无法产生可信的输出。他对劳动力替代、信息生态和文化影响的更广泛担忧是真实且独立的问题,值得单独写文章讨论。我不讨论它们,并不意味着我在回避。这里我只讨论架构问题:模型的不可靠性是否让有用系统变得不可能?还是说它只是一个工程问题?我认为是后者。Kingsbury 的文章假设的是前者。这就是我们的分歧所在。
在工作台上测试引擎
Kingsbury 的文章是一份 LLM 失败案例的目录。他让 Gemini 为 3D 浴室渲染图应用材质,结果它忘了马桶,还改变了房间形状。他让 Claude 做图像到图像的转换,结果它生成了几千行 JavaScript,制造出一堆莫名其妙的乱七八糟多边形。他让 ChatGPT 在蓝色衬衫上加白色补丁,结果它改了颜色、移动了补丁、甚至删掉了它们。他还看到同事的 LLM 声称下载了股票数据,却画出了一张随机数字的图表。
这些失败每一个都是真实的。我见过类似的失败。每一个在用 LLM 构建系统的人都见过。Kingsbury 没有编造任何东西。
但这里发生的情况是:一个人坐在裸露的语言模型面前,用自然语言输入一个请求,然后看着它失败。
- 没有技能文件(skill file)告诉模型如何处理任务。
- 没有确定性工具来处理需要精确性的部分。
- 没有解析器(resolver)把请求路由到正确的能力。
- 没有外壳(harness)来管理上下文、强制安全约束或限制行为。 他是在工作台上测试引擎,却得出“汽车不安全”的结论。
架构问题
给没读过本系列第一篇文章的读者补充几个术语:
- 技能文件 是一个可复用的 Markdown 文档,它教模型如何处理一项任务——它是一套流程,而非提示词。
- 解析器 是一个路由表,告诉模型针对哪类任务该读取哪个文档。
- 确定性代码 是每次输出都完全一致的软件——SQL 查询、API 调用、数学运算——这些模型永远不该碰的部分。
- 外壳 是薄薄的一层导体,它把模型跑在循环里、读取文件、管理上下文。 合在一起就是:薄外壳 + 胖技能。 Kingsbury 的核心主张是 LLM 是“扯淡机器”。它们会编造事实、混乱无序、容易被操纵、不可信任。他是通过孤立测试模型的方式得出这个结论的,就像测试一个函数:输入 → 输出 → 评估输出。
遇到 Kingsbury 这些问题的人,正是那些直接和裸模型聊天、期望可靠输出的人。而没有这些问题的人,都构建了外壳。不是因为外壳让模型变得可信,而是因为外壳让整个系统变得可信,即使里面的模型不可信。
Kingsbury 其实知道外壳的存在。他引用了 Claude Code 的源代码泄露:Anthropic 在自己模型周围构建的 51.2 万行工程代码。即使是世界上最好 LLM 的制造者,也不信任裸模型。他们用实时仓库上下文、提示缓存、专用工具、会话记忆、并行子代理把它层层包裹。这 51.2 万行代码就是证据——模型可靠性是一个工程问题,而非哲学问题。
但我要诚实地说:51.2 万行并不简单。我将要描述的模式(技能、解析器、确定性代码、测试)概念上很干净,但 robust 的实现是真正的工程。外壳会失败,技能可能会编码错误的流程,验证层也只和它检查的不变量一样可靠。我的主张不是“外壳让一切都变简单”,而是“外壳把模型的不可靠性从‘停止的理由’变成了‘要解决的问题’”。这个区别很重要。
股票数据的例子是最清晰的说明。LLM 声称下载了股票价格并画了图,但数据是随机的。Kingsbury 把这当作 LLM “撒谎”的证据。但实际发生了什么?有人让一个语言模型(一个文本预测机器)去互联网获取数据。它根本无法从互联网获取数据。它没有工具,没有 HTTP 客户端,没有 API key。所以它做了语言模型最擅长的事:生成一段看起来像股票数据响应的文本。
解决办法不是更好的模型,而是确定性工具:一个真正调用股票 API、返回真实数字、然后把数据作为上下文交给模型的函数。模型永远不碰数据获取。它只决定要查什么,代码决定怎么查。输入相同,输出永远相同。
这就是我在《薄外壳,胖技能》里描述的架构。把智能推到技能里,把执行推到确定性代码里,让外壳保持轻薄。当你这样做时,Kingsbury 描述的那类失败就会大幅减少。不是因为模型变聪明了,而是因为模型根本没有被要求去做它做不到的事。失败不会全部消失,但失败模式从“模型幻觉了”变成了“技能写错了”或“工具有 bug”。这些是可调试、可测试、可修复的问题。这就是混乱与工程的区别。
浴室问题
再看 Kingsbury 的浴室例子。他让 Gemini(一个语言模型)为一幅 3D 渲染图应用材质。Gemini 根本不是图像编辑器,也不是 3D 建模工具。它只是一个被临时加上图像能力的文本预测系统。当然它会忘掉马桶,当然它会改变房间形状。它只是在用像素即兴表演。
一个被正确外壳包裹的系统会完全不同地处理这个任务。技能文件会说:把任务分解成步骤。
- 识别图像中每一个表面(使用视觉模型)
- 为每个表面选择合适的材质(潜变量——模型决定)
- 使用确定性图像处理工具应用材质(代码——Pillow、OpenCV 或 Blender 脚本)
- 验证输出几何形状与输入一致(确定性对比) 模型做判断,代码做执行,解析器负责路由,外壳负责编排整个序列。
它会永远成功吗?不会。技能可能分解错误,视觉模型可能认错表面,确定性对比可能容差不对。这些都是真实失败模式,我每一个都遇到过。但它们是可调试的失败模式——你能找到哪一步出错,修复它,然后重新运行。而 Kingsbury 的那些失败无法调试,因为根本没有系统可调试,只有模型在即兴表演。
锯齿状不等于损坏
Kingsbury 最精彩的观察之一是“锯齿状技术前沿”——LLM 的能力边界不规则、不可预测。它们能做多变量微积分,却解不了简单的文字题;能写论文,却数不清字母。
这是正确的,也很重要。但 Kingsbury 得出了错误的结论。他说锯齿状前沿让 LLM 不适合需要可靠性的任务。而它真正意味着的是:你需要路由。
解析器就是上下文的路由表。当出现 X 类任务时,就加载 Y 技能。当任务需要数字母时,就路由到代码——三行 Python 函数就够。当任务需要写论文时,就路由到模型。当任务需要编辑图像时,就路由到一个结合两者的流水线。
锯齿状前沿是支持外壳工程的论据,而不是反对 AI。 irregularity 是真实的,解决方案就是绕开它!你必须把确定性代码放在模型弱的地方,把模型判断放在代码无法推理的地方。解析器就是绘制这张地图的工具。
在我自己的系统中,我把 OpenClaw 的“大脑解析器”设计成只有 80 行 Markdown,用编号决策树把每一条知识路由到正确的目录。没有它的时候,技能自己决定归档,13 个里面 10 个都错了。加上它之后,归档错误直接降到零。模型并没有变聪明,是路由变得明确了。
混乱是约束的理由
Kingsbury 认为 LLM 是混沌系统。它们对微小输入扰动敏感,容易被对抗性操纵,行为不可预测。他是对的。改写一个问题就会改变答案,调整句子顺序就会改变输出,看不见的 Unicode 字符就能劫持行为。
他把这当作根本问题。是的!如果你把原始、无结构的输入喂给裸模型,确实如此。
但如果通过技能文件来约束输入,就不必如此。
技能文件是一个结构化的 Markdown 文档,它定义了流程。它告诉模型该读什么、该考虑什么、输出什么格式、遵守什么约束。输入给模型的不再是“修这张图”,而是一份 200 行的文档:这是任务,这是流程,这是好的输出长什么样,这些是你有的工具,这些是你不能用的,如果你不确定该怎么办……
通过技能文件的结构化输入,混乱程度会比自由形式的自然语言大幅降低。技能约束了轨迹。它无法消除混乱(随机系统永远无法完全消除),但它能引导混乱,就像河岸引导河流。Kingsbury 说没有河岸的河流会泛滥,这没错。但这不是反对河流的理由,而是支持修河岸的理由。
推理是转移话题
Kingsbury 对“推理”模型的观点很聪明。他说思维链(chain-of-thought)痕迹本质上是“LLM 在给自己写同人小说”。他引用 Anthropic 的发现:Claude 的思维链并不能可靠反映它真实的推理过程。
这是真的,但无关紧要。思维链只是草稿纸,不是最终产品。人类做长除法时,纸上的中间步骤也不是神经元活动的真实记录,它只是组织计算的工具。没人通过草稿写得漂不漂亮来评价数学家。
重要的是输出。整个系统(模型 + 外壳 + 工具)是否产生了正确、可验证的结果?这才是可测试的问题。Kingsbury 没有测试它,因为他没有构建系统。
他只是在评价草稿纸,而不是答案。
我们也不知道阿司匹林为什么有效
文章快结束时,Kingsbury 指出“我们其实不知道 transformer 模型为什么这么成功,也不知道怎么让它们变得更好”。这是真的。阿司匹林的机制直到 1970 年代才完全搞清楚,全身麻醉至今仍不完全清楚,自行车稳定性(陀螺理论是错的)直到 2011 年才被彻底解释。
实用性并不需要理论上的完备性。工程可以在研究继续的同时推进,这一直是历史常态。
我们没有等到 1971 年的机制论文就停止开阿司匹林。我们没有一边争论机翼为什么产生升力一边把飞机停飞。问题不是“我们是否理解机制”,而是“我们能否用现有能力构建可靠系统、严格测试它们,并在理解加深时持续改进”。Kingsbury 隐含的假设是:不完全理解就无法构建。而整个工程史都在说:可以。
Jepsen 真正该测的是什么
讽刺的是,Kingsbury 的 Jepsen 方法论对 AI 系统完全正确,但他用在了错误的层级上。
Jepsen 测试数据库时,会注入故障并检查不变量。它不测试 CPU,也不测试操作系统,它测试的是完整的数据库系统,在压力下验证它自己的声明。当 CockroachDB 声称线性一致性时,Jepsen 注入网络分区,看声明是否成立。
把同样的方法论用于 AI 系统,目标非常明显。不要测试模型是否幻觉!它当然会。测试的是系统是否幻觉:
-
外壳是否阻止幻觉数据到达用户?
-
技能文件是否把需要精度的任务路由到确定性代码?
-
解析器是否对正确的输入触发?
-
实体传播是否完整? 这些都是可测试的声明。我们正在测试它们:
-
确定性代码的单元测试
-
流水线正确的集成测试
-
解析器触发评估(routing accuracy)
-
LLM-as-judge 的输出质量评估
-
全流水线的端到端测试 Agent 系统的测试金字塔是存在的,只是 Kingsbury 没有测试它。他测试的是裸模型,这就像把 Jepsen 跑在裸文件系统上,而不是数据库上。
真理的美学
我来谈谈 Kingsbury 最深层的论点——大多数读者即使说不清,也会感受到的那一点。LLM 不产生真理,它产生看起来像真理的文本。它有说真话的美学,却没有认识论的基础。用 Harry Frankfurt 定义的哲学意义来说,它们是扯淡机器:对输出真假漠不关心的系统。
这是正确的。这也正是架构为什么重要的原因。
裸模型产生的是似是而非的文本。
被外壳包裹的系统产生的是经过验证的文本。
技能文件说:“对照源数据检查你的工作。”
确定性代码说:“把输出和真实数据对比,不一致就拒绝。”
模型负责生成草稿,系统负责生成验证结果。
似是而非与经过验证之间的差距,正是外壳工程要填补的空白。
但 Kingsbury 完全忽略了一点:验证的质量取决于技能文件的质量。而技能文件是由人类——创始人、开发者或提示词编写者——写的。
这就是为什么开源如此重要。一个闭源 Agent 永远无法让你自己编写验证输出的技能,因为法律主义和安全主义会阻止真正深度定制。你需要能够说:“这是我的 schema,这是我的不变量,这是我领域里正确的结果长什么样,现在去验证它。”你无法通过一个守护系统提示的 API 做到这一点。
认识论问题真实存在,解决方案是开放的外壳,让用户控制验证层。不是信任,是工程。
这正是我的 YC 合伙人兼朋友 Pete Koomen 在《AI 无马马车》里谈到的:用户必须自己写提示,否则我们就会成为看不见的系统提示的奴隶。
汽车
在文章结尾,Kingsbury 把 AI 比作汽车。他让读者不要只看汽车有多快,而是想想它们对城市做了什么。他的答案是:城市蔓延、铅中毒、社区被推平、对汽车的依赖。这是一个好比喻。
但他从中得出了完全错误的教训。我们没有通过怀疑引擎来解决汽车的问题。我们是用工程解决的:安全带、溃缩区、催化转化器、交通灯、高速公路设计、燃油喷射、ABS、气囊、排放标准。每个十年都有新的工程让系统更安全、更高效、更实用——不是让引擎变聪明,而是围绕引擎构建更好的系统。
对引擎的怀疑从未救过一条命。真正救命的是底盘工程。
这就是对 Kingsbury 文章的回答。不是“要小心”。不是“这些机器是骗子”。
答案是:
构建系统。
写技能。
测试代码。
用解析器路由。
让确定性部分保持确定性。
让潜变量(模型)部分受到约束。
测试整个系统,而不是模型。
当系统失败时(它一定会失败)——调试出问题的步骤,修复技能,然后重新运行。
Kingsbury 说裸模型不可靠,这是对的。他说它们会编造、混乱、产生真理的美学而非真理本身,这也是对的。他错的地方在于,把这些特性当作判决,而不是约束。模型不可靠,但系统不必不可靠。
模型是引擎,外壳是汽车。造车吧。
——
我已经把本系列描述的架构开源了。GBrain 是知识层,让你能构建自己的个人 OpenClaw / Hermes Agent 来为你工作。GStack 是技能层,让你能用 Claude Code 快速开发。