Talk is cheap. Show me the code.
Linus Torvalds, 2000
一个正在流行的错误命题
2000 年,Linus Torvalds 在 Linux 内核邮件列表上留下了一句日后被印在无数开发者 T 恤上的话:”Talk is cheap. Show me the code.” 在他那个时代,这句话的意思很清楚:代码是唯一的证据,空谈一文不值。
二十多年过去了,到了 AI 编程的时代,这句话在很多人心里被悄然改写成了另一个版本,”Code is cheap. Show me the spec.”。代码反而廉价了,真正稀缺的是规范、是 提示词、是计划。其中最激进的版本叫 “specs to code”,意思是只要把规范写好,不必审阅代码,让 AI 像编译器一样反复跑上一遍即可。
Matt Pocock 是 TypeScript 社区的知名教育者,Total TypeScript 课程作者,近期把重心转向 AI 编程,在 aihero.dev 上开设了一门 “Claude Code for Real Engineers” 课程。
他在一场演讲里分享过自己实践 specs to code 的经历:跑一遍,产出一版代码;再跑一遍,代码质量下降;再跑一遍,进一步劣化。台下举手表示同感的人很多。
这可不是工具的问题,而是命题问题。Linus 那句话在 AI 时代无需被反转,只需要追加上一行注脚。talk 和 code 的生产成本确实更低了,但维护坏代码的代价变得前所未有地昂贵。
为什么 specs to code 会塌方
《程序员修炼之道》(The Pragmatic Programmer)中有一个常被低估的概念,叫软件熵(software entropy)。每一次改动若只着眼于局部,不顾整体设计,代码库就会持续退化。AI 并不能让这一规律失效,反而会加速它。
原因并不复杂。AI 是一名不知疲倦的战术级程序员,产能远超人类。在一个架构清晰、模块足够深、测试完整的代码库中,这份产能是乘数;在一个边界模糊、职责错乱、缺乏反馈回路的代码库中,它便是除数。每一轮 compile-and-run 循环,都会将熵增向前推进一格。
“specs to code” 默认了一个前提,开发者可以不看代码。但代码本身就是最精确的规范。凡是不在实现层面审查的项目,不过是把”看代码”的时间推迟到了故障发生的那一刻。所谓”不看代码”,本质上仍是在编写代码,只是换了一个名字。
三条没被 AI 淘汰的旧原则
如果 specs to code 并非解决问题的答案,那什么才是?我的回答是回到二十多年前的那几本软件的经典。
一、先对齐设计意图,再动手
Frederick Brooks 在《设计的设计:计算机科学家的论文》(The Design of Design)中提出过一个概念,称为 design concept。当两个人合作设计一个系统时,他们脑中会浮现出一个共同的、不可见的”这件事物应是什么样”的概念。它不是文档,也不是示意图,而是意图本身。
人与人协作时容易忽略这一点,人与 AI 协作时则会直接导致崩盘。AI 默认的 plan mode 有一个致命偏好,急于产出资产,急于先写出一份 spec,随即开始动工。但资产化得越早,分歧就暴露得越晚。
Jesse Vincent 的开源项目 Superpowers 直接把这条纪律内置成了 skill。它是一套面向 AI coding agent 的方法论,brainstorming 是其中最核心的一条,要求 agent 在动手之前反过来盘问使用者,直至双方对需求的理解彻底对齐。看似低效,实际上是把项目后期才会暴露的返工,前置到提示词阶段加以解决。
这种对抗式追问迟早会取代”先写一份 PRD”的默认工作流。原因很简单,PRD 本身就是 design concept 被固化为资产后的副产物,AI 无需再走这道弯路。
二、给 AI 一本词典
AI 表述冗长、行话过剩,这并非模型本身的缺陷,而是因为你没有给它一本领域词典。
Eric Evans 在《领域驱动设计》(Domain-Driven Design)中提出过一个概念,叫统一语言(ubiquitous language):开发者之间、开发者与领域专家之间、以及代码本身,都应使用同一套术语。这套术语并非风格偏好,它决定了系统内部的概念如何切分。
这一古老的概念在 AI 时代具有新的实用价值。面对同一个任务,配备一份术语表与否,AI 的产出质量差异显著。原因在于术语表压缩了 AI 的搜索空间。它无须再为”订单”一词臆测十种可能的抽象,而是直接沿着给定的抽象继续推进。
做法并不复杂。让 AI 扫描一遍代码库,抽取核心名词、动词、状态,整理为一份 Markdown 表格,开发者自行审校一轮,此后每次 planning 都将其挂载在上下文中。我的观察是,AI 的思考链会明显变短,实现也更贴合既定计划。
三、把 AI 关进深模块里
John Ousterhout 在《软件设计的哲学》(A Philosophy of Software Design)中把模块分成两类:深模块与浅模块。深模块将复杂度隐藏在一个简单接口之后;浅模块恰好相反,接口看似复杂,内部却没有多少实质的工作。
问题在于,AI 的默认产出恰是浅模块,一堆小文件、小函数、错综的依赖。让它实现一个功能,它会在十余处同时散布改动,每一处单看都合理,整体却已无法审查。
深模块之所以在 AI 时代更值得投资,是因为它直接决定了开发者能否把 AI 当作灰盒(gray box)使用。只要模块接口清晰、边界稳定,验证只需在接口层完成,内部实现则可部分授权给 AI。这才是速度的真正来源,而非更长的提示词。
反之,浅模块意味着必须逐行审查 AI 散布在各处的改动。这不是”用 AI 加速开发”,而是给自己增添了一份 PR review 的兼职。
你的新角色:战略级架构师
Kent Beck 有一句被反复引用的话,”每天都要投资于系统设计”。在 AI 出现之前,这句话的意思是不要让技术债压垮长期可演进性;在 AI 出现之后,它的含义变得更为具体。开发者最稀缺的那部分时间,必须投入到接口、边界、领域模型、测试策略这些只有人能做的决策之上。
这几件事做到位,AI 就是一名极富执行力的一线程序员;未能做到,AI 便会以前所未有的速度把代码库推入泥潭。specs to code 的方向正好相反,它是在从系统设计中抽身(divest),而非持续投入(invest)。这正是它注定不收敛的根本原因。
结语
冯骥才的小说《神鞭》里,傻二靠一条祖传的大辫子打天津卫,赢得”神鞭”的名号。直到辫子被洋枪一枪打断,他消沉许久后剪掉辫子,苦练双枪,从”神鞭”蜕变为”神枪手”,继续抗击外敌。故事结尾他道出一句台词:
祖宗的东西再好,该割的时候就得割。我把鞭剪了,神却留着。
这句话放在 AI 编程的当口恰到好处。specs to code 的支持者以为要割的是代码本身,是过去二十年积累下来的那套工程功底;但真正该割的,其实是开发者自己”每一行都要亲手写就”的身份执念。能写好代码,不等于必须亲手输入每一行代码。
代码从未如此昂贵,因为决定它是否昂贵的,不再是工时,而是开发者对系统的判断力。这份判断力 AI 无法替代,只会将它放大,或将它的缺席暴露无遗。