4 月 23 日,AI Engineer Europe 大会上,Matt Pocock 上台先做了个调查:听说过 specs-to-code 的举手——写一份规格说明,用 AI 把它“编译”成代码,出了问题不看代码,改规格,再编译一遍。举手的人不少;他让举着的别放下,真试过的继续举着,手还举着的人也不少。
他自己也真试过:第一版代码出来,还行;再编译一次,更差;再编译,更差;一直编译一直编译,最后手里是一堆垃圾。
为什么会越编译越烂?他翻了两本老书找答案。
第一本是 John Ousterhout 的《软件设计的哲学》(A Philosophy of Software Design)。Ousterhout 给坏代码下了个定义:复杂性,就是软件系统里一切让系统难以理解和修改的东西。改不动的代码库就是坏代码库——改一处就冒出 bug,那就是坏代码。好代码库的标准只有一个:好改。
第二本是《程序员修炼之道》,里面有一整章讲软件熵:每次改动代码时,如果只想这个改动、不想整个系统的设计,代码库就会一点一点烂下去。specs-to-code 的“再编译一遍”,干的就是这件事:每转一圈,都只看局部、不看设计。
这个做法背后有个更流行的说法在撑腰:代码变便宜了。他直接顶了回去:代码不便宜,坏代码的代价到了史上最高——代码库越难改,AI 能给的好处你就越拿不到,而 AI 在好代码库里是真的好用。所以这场演讲的标题叫《It Ain’t Broke: Why Software Fundamentals Matter More Than Ever》:软件基本功没有过时,反而比任何时候都更要紧。
顺带介绍一下讲的人:Matt Pocock 是 Total TypeScript 的作者,这两年转做 AI 编程教育,正在教一门名字就很挑衅的课:Claude Code for Real Engineers。备课逼他整理出一套 AI 编码的完整方法论,这场演讲就是压缩版。
那基本功具体是什么?他列了一串失效模式,每个配一味药。顺着写代码的顺序捋下来,这些模式不是并列的坑,是四层:想清楚、说同一种话、跑起来、脑子受得了。

第一层:你以为说清楚了,其实没有
“我以为我脑子里想得挺清楚,结果 AI 做出来一个完全不一样的东西。中过招的举手。”
《程序员修炼之道》早写了:没人确切知道自己要什么。你和 AI 之间隔着一层沟通壁垒,你跟它聊需求的过程,其实就是它在向你做需求调研。
Matt 从 Frederick Brooks 的《The Design of Design》里借来一个概念:设计概念(design concept)。几个人一起设计东西时,那个“我们要做的东西”的共识飘在几个人之间,是看不见的。它不是资产,存不进任何 markdown 文件,它是关于你正在做的东西的一套活的理论。人和 AI 之间缺的正是这个。
他的对策是一个只有两句话的 skill,叫 Grill Me,全文照引:
Interview me relentlessly about every aspect of this plan until we reach a shared understanding. Walk down each branch of the design tree, resolving dependencies between decisions one by one.
(不停地盘问我这个计划的每个方面,直到我们达成共识。沿着设计树的每个分支走下去,逐个解开决策之间的依赖。)

就这两句话,AI 会反过来问你 40 个、60 个问题——他见过有人被问了 100 个,AI 才满意地认为共识达成。这个过程里,AI 从一个急吼吼的执行者变成了对手,不断拿问题戳你。聊完的那大段对话也不是废话,可以直接整理成 PRD;改动小的话,直接转成 issue——用他自己的话说,“然后你的 AFK agent 会接手”。AFK 是他演讲里的原词,指的是你离开键盘、agent 自己把活干完。
这个 skill 火到什么程度?他的原话是,放这个 skill 的仓库“大概有 13,000 个 star 之类的吧,反正疯了”。
他还顺带吐槽了一句:他觉得这比 Claude Code 自带的 plan mode 好用——plan mode 太急着产出一份计划然后开工,而先达成共享的设计概念再动手,感觉好得多。说这句时他自己补了句“别来喷我”。
第二层:词对不上
想清楚了,还得说得通——“感觉 AI 在用特别多的词跟你说话,但你们说的不是同一种语言。有这感觉的举手。”
做过多年开发的人对这个场景熟:跟领域专家合作,比如给造芯片的人写软件,你不懂芯片,他不懂代码,中间隔着一条语言的沟。Matt 回到了领域驱动设计(DDD)。他说自己对 DDD 还在探索期,但读到的一切都“悦耳得像音乐”。
DDD 里有个概念叫统一语言(ubiquitous language):开发者之间的对话、代码里的表达、跟领域专家的沟通,全部从同一个领域模型派生出来。到他手里,就是一个 markdown 文件,里面全是术语表,把你和 AI 共用的词一个一个对齐。
他做了个 skill 来自动生成它:扫一遍代码库,找出术语,生成一堆 markdown 表格。他自己用的时候,这张词表全程开着,盘问 AI 和做计划时都摊在手边。后来他读 AI 的思考过程(thinking traces),发现变化不只是计划变准了——AI 连思考都变得更简洁,实现出来的东西跟计划的偏差也更小。
第三层:跑不起来
说通了,做出来,还得跑——第三个失效模式:AI 做出来了,但跑不起来。
最显然的解法是反馈回路:静态类型(他原话:不用 TypeScript 是疯了)、写前端就给 LLM 开浏览器权限让它自己能看页面、自动化测试。
但他观察到的问题是:就算回路都配好了,LLM 也不会像老手那样用它们。它的惯性是一口气写一大堆,然后才想起来“哦,我可能该跑一下类型检查”,或者“也许该跑个测试”。《程序员修炼之道》管这个叫“开出了车灯照亮的范围”,开得太快。他把那句话重复了两遍:反馈的速率就是你的限速。
所以第三个 skill 是 TDD:先写测试,让测试通过,再重构,逼着 LLM 一次只走一小步。
TDD 说起来容易,Matt 自己也认:测试一直就很难。写一个测试要做一堆决策——测多大的单元?mock 掉什么?到底要验证哪些行为?这些决策还互相牵制:单元选大了容易脆,选小了 mock 就变多。他说这件事他想了一整个职业生涯。
他的答案是:好测试的代码库,首先是好代码库——于是又绕回 Ousterhout。Ousterhout 主张深模块:数量相对少的大模块,简单的接口,把复杂实现藏在后面。反面是浅模块:功能没多少,接口倒挺复杂。Matt 在这里放了两页幻灯片,特意停下来“等你们拍完照”。
浅模块的代码库长这样:一大堆小碎块,AI 要一块一块走过去才能搞清楚结构。他补了一句:这种代码库正是 AI 最擅长生成的那种。所以在这种代码库里经常会看到:AI 试图探索代码,但布局太碎,要么没及时找到对的模块,要么没搞懂依赖关系——它不理解你的代码。
深模块的代码库是同样的代码,收进一个个边界里,接口露在上面。这些接口你要自己握紧、认真设计,不然 AI 会把设计搞砸;但边界内部的实现,大体可以交给 AI。
怎么把左边变成右边?又一个 skill:improve-codebase-architecture。他说这事不简单,但有一套可以反复用的步骤:探索代码库,找出互相关联的代码区域,包进一个深模块。这样的代码库天然奖励 TDD——边界简单,测试打在接口上,验证也在接口上。

第四层:脑子跟不上
回路全通了,出码量前所未有,下一个轮到人吃不消。“觉得开发生涯从没这么累过的举手。“他先举了自己的:我也是,累惨了。
这条在他幻灯片上的编号是失效模式六——对,他自己跳号了,前面几个模式大概占满了序号。救法还是深模块,当灰盒用:接口你设计、你审,边界里面的实现不用每行都读。当然有限定条件——金融这类高风险模块别这么干——但应用里大量模块,只要外面有一圈可测试的边界,你懂它的用途、能从外面设计它,里面就不必太操心。他的原话是,这法子“救了我的脑子”:里面那一大坨交给 AI,我只从外面测它、验它。
四层药,是同一种药
四层捋完,回看每一味药:把想法聊成共享的设计概念,把词对齐成统一语言,用 TDD 把步子切小,用深模块守住边界。没有一味是新技术,全是设计工作。
演讲最后他引了 Kent Beck:每天对系统的设计做投资。specs-to-code 的问题正在于它是对设计撤资。他自己的做法是把模块意识带进日常文书:写 PRD 时写清动哪些模块、模块里哪些接口怎么改。
他把 AI 比作一个很强的地面程序员,一个战术型选手,趴在地上改代码的中士。总得有人站在它上面想战略层的事。那个人是你。
我们装上之后,看见他没说的一层
演讲配套的仓库在 github.com/mattpocock/skills,MIT 协议,光工程组就有 18 个 skill。这个仓库自己也按自己的规矩活:根目录放着一份它要求所有项目都该有的 CONTEXT.md 术语表。
我们今天把它装进了自己的仓库,顺带配了一个叫 beads 的任务库。装的过程让我们看见一层演讲没明说的东西:这套系统做的事,是把基本功从个人手艺变成流程的强制环节。
几个具体的例子。triage 环节只有五个标签,规格不全的 issue 永远走不到 ready-for-agent,需求澄清不是美德,是关卡。issue 进入“可交给 agent”状态时,流程要求发一条结构化的 agent brief,仓库文档写得很直白:原始讨论是背景,brief 才是合同。每张任务票开工前必须声明是 HITL 还是 AFK——这件事需不需要人在场,成了动工之前必须回答的问题。beads 把任务之间的依赖关系变成机器可查的,agent 开工前自己跑一句 bd ready,此刻没有阻塞、没人认领的活就列出来了,不需要人分派。

这些环节的共同点:不靠工程师自觉。基本功没有消失,它们从“好工程师记得要做的事”变成了“流程不让你跳过的事”。演讲说“站在战略层的人是你”,装上之后才知道这句话的实操版:战略层不是靠自觉站上去的,是流程把你架在那的。
刚装上一天,效果我们不吹牛,用一阵子再汇报。
想听原演讲的,B 站有中英字幕版(BV1pq8B64EFH),原视频在 YouTube 的 AI Engineer 频道。上一篇《古法程序员何去何从》聊的是同一个判断落在人身上的那一半:AI 越会写代码,看得懂代码的人越贵。


