最近注意到一个叫 mattpocock/skills 的仓库登上了 GitHub Trending 榜首——一天新增五千多 Star,总数突破三万。作者 Matt Pocock 是个 TypeScript 教育者,过去一年半一直在教人怎么用 AI 智能体做开发。他最近有两场演讲被放出来,讲的是他这一年半观察下来总结出的一套 AI 编程方法论。我看完之后觉得挺有意思,所以写这篇来梳理一下他的思路——不只是仓库里那些 skill 文件本身,而是它们背后的诊断逻辑和设计哲学。
一个不太主流的出发点
现在关于 AI 编程的讨论,基本上分成两个方向。一边说「代码以后不重要了,会提需求就行」;另一边说「程序员要被替代了」。这两种说法听着相反,但仔细想想,它们其实共享一个前提:传统的工程基本功在贬值。
Matt 的立场和这两边都不一样。他说他这一年半观察了很多用 AI 做开发的人,发现了一个规律:那些真正用得好的,既不是把所有事都甩给 AI 的人,也不是什么都不信 AI 非要自己写的人。他们的共同点是——当 AI 搞不定的时候,他们能接得住。
然后他把这个观察往下推了一步:为什么有的人 AI 用得好,有的人越用越乱?他的结论是——问题往往出在代码库本身。好的代码库里,AI 干活又快又准;乱的代码库里,AI 越写越烂。这听起来像是废话,但他接下来的推论有点意思:既然 AI 是个放大器,那好代码的价值就不再只是「好看一点」「好维护一点」这种线性的好处了——它被放大了。反过来也一样,坏代码的代价也被放大了。以前坏代码顶多是让人维护起来头疼,现在坏代码是直接让你没法用 AI,等于你自动放弃了一大块生产力红利。
顺着这个逻辑,Matt 还批评了一种叫「specs to code」的做法——大意是你写好规格文档,让 AI 去生成代码,代码出了问题不去改代码而是改文档,把代码当成编译产物看待。他说他自己试过这个路线,第一次生成的还行,第二次开始劣化,第三次已经没法看了。他觉得这跟所谓的 vibe coding 本质上是一回事——都是在放弃对代码的掌控权。
六种常见的翻车姿势
在这个大前提之下,Matt 把他观察到的 AI 编程翻车场景归纳了六种。他的 skills 仓库里的每个工具大致对应一种。比较有意思的是,他给每种翻车找理论解释的时候,引用的全是 AI 出现之前的经典软件工程著作。
你想要 A,AI 给你做了 B
这大概是最普遍的问题了。你脑子里有个模糊的想法,对着 AI 说了一通,它热火朝天做了一堆,但做出来的不是你要的东西。
Matt 说问题在于你们之间缺少 Brooks 在《设计的设计》里说的那个东西——Design Concept,设计概念。就是说当几个人一起造一个东西的时候,他们脑子里有个共享的画面,知道这东西最终是什么样的。你和 AI 之间往往就没有这个对齐过程。
他的解法是一个叫 grill-me 的 skill。内容很短,大概就是让 AI 扮演一个追问者:每次只问你一个问题,逼你把每个设计决策想清楚说明白,直到双方达成一致为止。实际跑起来会产生四五十轮的问答。听起来烦,但他觉得这比上来就让 AI 出计划要靠谱得多——因为那些计划模式本质上是急着动手,意图还没对齐就开始干了。
AI 说了很多话但不在点子上
另一个常见体验:AI 的回复又长又啰嗦,你说的概念它好像懂了,但写出来的东西用的是另一套术语和抽象。
这个问题 Matt 用领域驱动设计里的 Ubiquitous Language(通用语言)来解释。简单说就是:你的项目里有一套自己的词汇表——你怎么命名 class,怎么叫那些业务概念——但 AI 不知道这些,它用的是自己训练数据里学来的通用说法。
所以他做了个 ubiquitous-language skill:让 AI 扫描你的代码库,把里面的核心术语提取出来整理成表格。之后每次开新对话就把这份表格注入进去。他说他观察 AI 的推理过程后发现,有了这份词汇表之后,AI 不光规划时更靠谱了,连写出来的代码在命名风格上都更贴近现有代码库了。这个副作用倒是挺自然的——你用什么词思考,往往就会用什么词命名。
方向对了但跑不通
假设前面两步都做好了——意图对齐了,术语也一致了——AI 也确实在往对的方向走,但写出来的代码就是跑不通。
Matt 说这是反馈循环的问题。没有类型检查、没有测试、没有 lint,AI 就是闷头写,不知道自己已经偏了。但光是说「那就加测试吧」也不够,因为 AI 有个天然的倾向:它喜欢一口气写很多东西,写完了再说。Hunt 和 Thomas 在《程序员修炼之道》里管这种状态叫「驶出车灯照射范围」——车开得太快,灯照不到那么远,你看不见前面有什么。
他的对策是一个 tdd skill,强制 AI 走测试驱动的红绿循环:先写一个会失败的测试,再写让它通过的最小实现,然后重构。关键在于测试必须在实现之前写好,这就从机制上限制了 AI 每一步的跨度。它没法作弊——你不可能在代码还不存在的时候写一个永远通过的假测试。
代码库本身是个烂摊子
前面三个问题是关于单次交互的质量。但如果代码库的结构本身很碎片化——到处是只有几十行的小文件,互相通过隐式依赖纠缠在一起——那 AI 每次「正确地」完成一个任务,都可能让整体更乱,因为它追踪不了那张复杂的依赖网。
这里 Matt 引用了 Ousterhout 在《软件设计哲学》里的说法:深模块(Deep Module)和浅模块(Shallow Module)的区分。浅模块就是接口复杂、内部功能少的那种——一大堆小零件互相依赖。深模块反过来——接口简洁,内部包了很多逻辑。对 AI 来说,深模块意味着它只需要理解接口约定就能正确地使用这个模块,不需要钻进去看每一行实现。深模块也天然好测试:在接口边界上写测试就行了。
他的 improve-codebase-architecture skill 就是让 AI 去扫描你的代码库,找出那些可以收拢成深模块的碎片化区域,给出重构建议。他举了自己的一个例子:把一个视频编辑器里贯穿前后端的完整流程收拢成一个大模块之后,AI 在那个项目上的表现是「天差地别」。
产出多了但脑子跟不上了
这个问题有点微妙。用了 AI 之后你确实比以前写更多代码了,但同时你觉得自己对代码库的掌控感在下降——你不再清楚每一处细节是怎么回事了。
深模块的思路在这里提供了一种心理上的出路:你把这些模块当成灰箱——接口是你设计的,行为是你验证过的,但内部实现你可以交给 AI,不必逐行审查。Matt 把这个原则总结成一句话:Design the interface, delegate the implementation——设计接口,委托实现。Kent Beck 说过「每天投资于系统的设计」,这就是那句话的具体操作方式。
反过来看那个「specs to code」的做法,问题就很清楚了:它是在从设计中撤资——用一次性的文档替代了持续演进的接口设计。Matt 说你应该做相反的事:加大对设计的投资,因为 AI 让设计的回报率比以前高多了。
任务太大,AI 到后面开始胡说
最后一个问题跟 LLM 本身的物理限制有关。简单说就是:上下文窗口装满之后,模型的注意力质量会下降——Matt 说大约在 100k tokens 这个量级之后,模型就开始从「智慧区」滑入「愚蠢区」。
所以大任务不能硬塞进一个对话里做完。但把大任务切成顺序步骤让一个 AI 一步一步做,又太慢了。他的方案是把任务切成一张 DAG(有向无环图):有些子任务之间有依赖关系必须串行,没有依赖关系的就可以并行分配给多个 AI 智能体。每个智能体都在一个全新的干净上下文里工作,保证它始终待在智慧区。
串起来看:一条完整的流水线
上面六个 skill 不是孤立的工具,它们之间有上下游关系。串起来大概是这样一条线:
先用 grill-me 做需求追问,把模糊的想法变成清晰的共识。然后把共识转化成一份结构化的 PRD 文档。然后把 PRD 拆成一组有依赖关系的 Issue——每个 Issue 是一个垂直切片,从数据层到前端一竿子捅到底。然后 AI 智能体以 TDD 方式逐个实现这些 Issue。完成后人工做 QA 和代码审查,发现的问题变成新 Issue 回到看板。循环往复。
这条流水线有几个设计选择我觉得值得说一下。
第一个是垂直切片。AI 的自然倾向是水平切——先把数据库层全部做完,再做 API 层,再做前端。问题是在第一条完整路径跑通之前你没有任何真实反馈。所以 Matt 要求每个 Issue 都是一个纵向的薄片——它可能很粗糙,但它是一条能跑通的端到端路径。《程序员修炼之道》里管这叫曳光弹——你不需要它精确命中目标,你只需要它发光让你看到弹道。
第二个是上下文管理策略。对话快满的时候,他选择清空重来而不是压缩摘要继续。压缩听起来更省事,但压缩后的摘要会引入漂移和信息损失。从零开始虽然看似浪费,但保证了每一轮 AI 都在一个已知良好的起点上工作。
第三个是人和 AI 的分工。规划环节(追问、写 PRD、切 Issue)必须有人在场。实现环节完全交给 AI,人可以离开。QA 环节又必须有人在场。人的精力集中在决策密度最高的两头,中间那个机械执行的环节交出去。
第四个是并行化。Matt 为此做了一个叫 Sand Castle 的编排库:一个规划智能体看看板上哪些 Issue 没有阻塞关系,把它们分发到独立的 Docker 容器里;多个实现智能体同时干活;干完之后由一个合并智能体处理冲突。审查用高能力模型,实现用高性价比模型,各司其职。
旧书为什么突然变得重要了
Matt 演讲里引用的那些书——Ousterhout 的《软件设计哲学》、Hunt 与 Thomas 的《程序员修炼之道》、Brooks 的《设计的设计》、Evans 的《领域驱动设计》——有的写于二十多年前,全部写在大语言模型出现之前。
为什么这些旧书突然又重要了?我觉得 Matt 给出了一个挺好的解释框架:这些书讲的东西——怎么设计接口、怎么管理复杂度、怎么在协作中对齐意图——本质上都是在讨论「输入信号的质量」问题。以前这个质量差一点,后果就是维护成本高一点、开发速度慢一点,但基本是线性的代价。现在有了 AI 这个放大器,好的输入信号能被放大成惊人的产出,坏的输入信号也会被放大成惊人的混乱。增益系数高了,输入端的差异就变得比以前重要得多。
skills 仓库做的事情,说白了就是把这些书里的原则翻译成了 AI 能执行的格式——几十行的提示词文件。它不是框架,不是 SDK,就是一组行为约束,让 AI 在干活时自动遵循这些被验证过的工程原则。
小结
所以回到标题。把 AI 当许愿池用——丢一个模糊的想法进去,期望捞出一个成品——这条路 Matt 试过,结论是越迭代越烂。把 AI 当放大器用——在输入端下功夫,把设计做清楚、把测试写到位、把模块边界画好、把术语对齐——然后让 AI 放大你的投入,这条路虽然前期看起来慢一些,但产出质量随迭代上升而不是下降。
两条路的岔口其实就一个判断:你信不信基本功在 AI 时代还有用。skills 仓库的三万颗 Star 大概可以算一个投票结果吧。