ARTICLE · 1148521
AI 编程最贵的 bug,是“正确地做错事”
引子
一个功能,上周让 AI 写完了。这周还在修。
修到最后你发现:不是代码写错了。
是需求,从一开始就理解偏了。
这是今天 AI 辅助开发里最常见的浪费。它不是"写错了一个函数",而是"把一个错的东西,非常正确地写了出来"。
后者更贵。因为前者改一行代码,后者要推翻一整周。
问题出在哪?
出在:过去我们给 AI 的需求,载体是聊天记录。
聊天记录有四宗罪。
一,会滚出上下文。你翻到下一个任务,它就没了。
二,没有版本。改了什么、谁改的,说不清。
三,不可审阅。代码可以 review,需求只能靠"凭记忆"。
四,不可并行。两个人同时让 AI 改同一个模块,互相覆盖。

所以行业里冒出了一个词:规格驱动开发(Spec-Driven Development)。
而在这一堆工具里,目前最实用的一组搭配,是两个:
OpenSpec 管"说清楚",Superpowers 管"做对事"。
这篇文章,讲的就是这两个技能配合使用的三条最佳实践,和四个最容易踩的坑。
一、第一个实践:先把需求从聊天记录里"捞"出来
先说 OpenSpec。
它是一个轻量的、开源的规格驱动框架。安装只要一行:
npm install -g @fission-ai/openspec@latestcd your-project && openspec init --tools claude需要 Node 20.19.0 以上。
它做的事,本质上是"把合同写下来"。
每一次变更,不再是聊天记录里的一段话,而是仓库里的一个文件夹:
openspec/changes/add-payment-webhooks/├── proposal.md # 为什么要做这次变更├── specs/ # 增量规范(Delta Specs)├── design.md # 技术方案怎么做└── tasks.md # 实现清单四个文件,回答四个问题:为什么做、要变成什么样、怎么做、分几步做。

而它最关键的设计,是增量规范(Delta Specs)。
它不要求你把整个系统的规格重写一遍,只描述"这次变了什么":
## ADDED Requirements## MODIFIED Requirements## REMOVED Requirements这个设计的价值在哪?
一句话:它让规格,可以像代码一样被增量维护。
传统做法是先写一份完整规格再开工。那适合从零开始的新项目。
但现实中,九成的需求是"给现有系统加个东西"。你不可能每次都重写一遍规格。
增量规范解决了这个问题。两个变更只要动的是不同需求,就不会冲突,可以并行。
做完之后一归档,增量自动合并进主规格树 openspec/specs/。
你的"系统说明书",就这样一次变更、一次变更地长出来。
这一点,连 Thoughtworks 都专门写进了技术雷达。他们给的评价很准:OpenSpec 是增量的、工具无关的,尤其适合存量系统。
这句话很重要。因为绝大多数人的代码库,都不是从零开始的。
核心命令,记住四条就够:
/opsx:new # 创建一个变更/opsx:ff # 一次性生成所有规划文档/opsx:apply # 按任务清单实现/opsx:archive # 归档,增量合并进主规格复杂场景还有 /opsx:explore(先探索再动手)、/opsx:verify(归档前验证)、/opsx:bulk-archive(批量归档)。
注意,OpenSpec 还有一个别的工具少有的东西:openspec validate。
需求写得好不好,它可以做程序化校验。这一点,是"建议"和"闸门"的分界线。
最佳实践 · 第一条
把 /opsx:ff 之后的那次人工审阅,当成整条流水线里最值钱的一步。
因为在这里改一句话,成本是 1。在代码里改,成本是 100。
审的时候盯三件事:
一,proposal 的边界对不对。别多,也别少。
二,规格里的要求,用的是 MUST 还是 SHOULD。这决定了 AI 的用力程度。
三,任务拆得够不够细。
二、第二个实践:给 AI 装上"硬闸门"
再说 Superpowers。
如果 OpenSpec 解决的是"说什么",那 Superpowers 解决的是"怎么做"。
它出自 Jesse Vincent 之手。
这个名字你可能不熟,但他做的东西你大概率用过。他写了 Request Tracker,2005 到 2008 年管理 Perl 6 项目,联合创办了 Keyboardio,还做了 K-9 Mail——后来被 Mozilla 收购,变成了 Android 版 Thunderbird。
一句话概括这个人:他一直在给别人造基础设施,而且极其在意"流程"。
Superpowers 要解决的问题非常具体。
AI 编程助手的默认行为是:收到请求,立刻开始写代码。
没有分支,没有测试,没有 review。
问题不在智能,在纪律。
它的做法很有启发:不靠"讲道理",靠"硬闸门"。

看三个最典型的。
第一个,brainstorming。
它的硬性约束是:在你确认设计方案之前,不允许启动任何实现动作。
不能写代码,不能搭脚手架,不能"先试试看"。
为什么?因为大部分被浪费的工作量,都来自"先干起来再说"。
第二个,TDD。
这条规则是"没有失败的测试,不许写生产代码"。
原文的措辞非常强硬,大意是——先写了实现代码再补测试?删掉,重来。
不是警告。是删除。
为什么必须这么狠?
因为模型的天性是"讨好"。
你让它补个测试,它会写一个"验证这段代码做了什么"的测试。那叫同义反复,不叫测试。
删掉,是唯一能切断这个循环的办法。
第三个,writing-plans。
它要求:计划要细到"每个任务 2 到 5 分钟、精确到文件路径、给全代码上下文、写清验证方式"。
而且写计划时,要假设执行者是一个"对你的代码库零上下文、品味还不怎么样"的人。
听起来苛刻。但它有个非常现实的前提:
下一步的执行者,可能是子 agent。它对你代码库的了解,就是零。
有个真实结果值得看一眼。
一个叫 chardet 的 Python 字符编码检测库,新版本性能提升了 41 倍,准确率到 96.8%,顺手剃掉了一批积压多年的老问题。
作者说,那套覆盖 2161 个文件、99 种编码的测试,正是 TDD 这条硬闸门逼出来的副产品。
最佳实践 · 第二条
不要试图"温和地"使用这些技能。要么全开,要么不用。
闸门的价值,就在于它不让步。
你让它通融一次,它就退化成一个"建议"。而 AI 对"建议"的态度,你懂的。
三、为什么偏偏是这两个
市面上做规格驱动的工具不少。
GitHub 有 Spec Kit,还有更重的 BMAD,以及绑定特定 IDE 的 Kiro。
为什么最后落到 OpenSpec 加 Superpowers 这一组?
因为它们的"性格",是互补的。
Thoughtworks 在技术雷达里点破了一件事:很多规格驱动框架和技能工作流,更适合从零开始的新项目(greenfield)。而 OpenSpec 的特别之处,是它对存量系统(brownfield)更友好。
方法就是前面说的增量规范——不重写全量规格,只描述这次变了什么。
而 Superpowers 补的,恰恰是 OpenSpec 不擅长的那一半。
OpenSpec 的长处是"把要求写清楚",但它管不住 AI 写代码时的具体动作。
tasks.md 只说做什么,不说怎么做。
Superpowers 反过来:它管得住动作,但它不知道"该做什么"——它手里没有需求档案。
一个管 What,一个管 How。
一个偏"文档",一个偏"行为"。
一个靠 CLI 校验强制,一个靠硬闸门强制。
这就是它们能拼在一起的原因:接口干净,没有重叠,也没有空档。
顺便说一句,还有第三层,很多人会忽略。
在需求层(OpenSpec)和流程层(Superpowers)之上,还有一层:工程纪律层——代码规范、测试覆盖率、安全检查。
这一层,光靠 AI 遵从是不够的。必须再配一道 CI 闸门。
因为"模型说它会遵守",和"构建失败了就合不进去",是两回事。
四、真正难的部分:两条流水线怎么接上
到这里,两个技能各自都好用。
但真正的坑,出现在它们交界的地方。
先把分工说清楚:
需求层,OpenSpec 主导。 管说什么(What)。产出 proposal、specs、design。强度靠 CLI 校验,可程序化强制。
流程层,Superpowers 主导。 管怎么做(How)。产出计划、测试报告、审查记录。强度靠模型遵从加硬闸门。
一句话:OpenSpec 管"说清楚",Superpowers 管"做对事"。
它们能接上,是因为有一个天然的接口:
OpenSpec 的 tasks.md,正好是 Superpowers writing-plans 的输入。

完整的双闭环流程,六步。
第一步:输入 PRD,人工审。
把 MVP 的 PRD 切成若干个 markdown 文件,人先过一遍。
这是整条流水线里,唯一一个"人必须完全负责"的环节。别省。
第二步:brainstorming 做设计探索。
在 superpowers/specs/ 下,产出一份带时间戳的设计文档。
这一步是在"想清楚",不是在"写代码"。
第三步:交给 OpenSpec 立契约。
执行 propose 时,明确指定"根据这份设计文档创建提案"。
OpenSpec 会生成一个 change,里面有 proposal、design、按领域划分的 specs,和对应的 tasks。
到此,聊天记录里的模糊想法,正式变成了一份书面契约。
第四步:交叉验证。
这是很多人会跳过、但最该做的一步。
拿 OpenSpec 生成的 spec,回头对一遍 PRD。看有没有漂移。
需求漂移不是一次发生的。是每一环丢一点、加一点,最后累积成的。
这一步,是整条链路上唯一的刹车点。
第五步:交给 Superpowers 执行。
把整个 change 丢过去,让它显式执行 writing-plan,输出到 superpowers/plans/。
然后按 Subagent-Driven 模式,用 TDD 实现每一个任务,原子提交。
提交通常落在框架自动创建的 worktree 里,天然避开了版本冲突。
这里有个关键取舍:跳过 OpenSpec 的 /opsx:apply。
为什么?
因为 OpenSpec 的 apply 是"让 AI 按任务清单写代码"。而 Superpowers 的 TDD 流程做得更好——它有测试纪律、代码审查、验证机制。
用后者替代前者,是这套组合里的核心判断。
第六步:回到 OpenSpec 归档。
执行 /opsx:archive。
这里有一个必须提前知道的"副作用":
因为执行阶段是 Superpowers 操作的,tasks.md 里的勾选框很可能还是空的。
工件状态是 done,但任务没打勾。
这不是 bug。
直接忽略那些没打勾的任务,确认归档。 归档的规格会合并进 openspec/specs/,同时在 changes/archive/ 里留一份历史。
如果你在意这个状态不一致,也有办法:手动把 - [ ] 改成 - [x],或者写一个桥接技能自动同步。
回头看这六步,你会发现:人一共介入了三次。
审 PRD,审 spec,审每个任务的产出。
这三次介入,不是流程的负担。它们是流程的全部价值所在。
AI 能替你写代码,但不能替你决定"什么是对的"。
最佳实践 · 第三条
双闭环的价值,不在于"两个工具都用上了",而在于那个交叉验证点。
工具接不接得上,是效率问题。
规格有没有漂移,是生死问题。
五、四个最常见的坑
坑 01
跳过 OpenSpec,直接让 AI 写代码。
结果:需求漂移。
你会在第三周才发现,做的和当初说的,不是一回事。
坑 02
跳过 Superpowers,自己手动实现。
结果:流程失控。
代码能跑,但没有测试、没有审查。三天后,没人敢改。
坑 03
把技能当"建议"用。
删掉 TDD 的删除逻辑,在 brainstorming 的闸门前放行一次。
闸门一旦松动,它就只是个装饰。
坑 04
在需求每小时变一次的原型项目上,硬上这套流程。
规格驱动是有成本的。
什么时候该用?一句话判断:
当"理解错"的代价,超过"写文档"的成本时,用。反之,别用。
总结
把 AI 从"打字员"变成"工程师",靠的不是更强的模型。
靠的是两样东西:
一份写在仓库里的契约(OpenSpec),和一套不许让步的闸门(Superpowers)。
前者保证你做对的事。
后者保证你把事做对。
行动建议就三条。
一,从下一个"跨多个文件、涉及行为变更"的需求开始。先跑 /opsx:ff,人工审一遍 spec,再动代码。
二,装上 Superpowers,完整地用。不要挑着用。
三,在 OpenSpec 和 Superpowers 之间,保住那个交叉验证点。
它看起来最"不产出代码",但它是唯一能挡住需求漂移的地方。
AI 写代码很快。
但快的另一面,是乱。
先立规矩,再写代码。