从第一次接触到“Spec 驱动开发”这个概念到现在,我前后折腾了好几版工作流。早期直接人肉写测试,写着写着就发现需求变了,连测试也跟着推倒重来;后来尝试先写设计文档,但文档和代码距离太远,维护着维护着就没人看了。直到把 OpenSpec 和 Superpowers 组合起来搭了一套 SDD+TDD 的闭环,我才真正体会到“先定行为、再写测试、最后落实现”这条路是能走通的。这篇文档我把整个搭建过程、每一步的取舍、实际跑通的案例以及踩过的坑都记录下来,适合想把手头开发流程往规范化和自动化方向推进一步的团队或个人,也适合刚接触 SDD、TDD 概念但不知道怎么落地的新手参考。
1. 整体设计与核心思路:为什么把 Spec 放在测试前面
1.1 SDD 是什么,它解决了什么问题
SDD(Spec-Driven Development)按照字面理解就是“由规格说明书驱动的开发”。它不是让开发变成写文档,而是把需求行为用结构化的 spec 文件固定下来,让 spec 成为开发、测试、评审的共同参照物。
我个人的理解是,传统开发的痛点在于需求存在人的脑子里。产品说“用户要能改头像”,开发脑子里想的是“上传文件、裁剪、保存 URL”,测试心里想的是“图片太大要报错,格式不对要提示”。三方默认一致,但一旦某个环节理解偏差,返工成本就来了。SDD 做的事情,就是把“用户能改头像”拆解成一组可验证的行为描述,例如:
- 用户上传合法图片后,系统中保存新的头像地址;
- 用户上传超过 5MB 的图片,系统返回错误提示;
- 用户上传非图片格式的文件,系统拒绝保存。
这些描述一旦放进 spec 文件,它就变成了开发的输入和测试的基准。OpenSpec 正是围绕这个需求设计的一套规格文件管理工具,它定义了 spec 的目录结构、格式约定和变更流程,让团队不再靠口头对齐。
1.2 TDD 的循环是什么,为什么单独做容易卡住
TDD 的经典循环是红-绿-重构:先写一个会失败的测试,再写最小实现让测试通过,最后优化代码结构。这个循环理论上非常清晰,但实际落地时经常卡在第一步——测试到底该测什么。
我刚学 TDD 的时候,遇到复杂业务就懵。比如“积分规则按会员等级打折”,这句话本身不精确,测试没法写。是打折后向下取整还是四舍五入?会员等级变化后历史订单算不算?这些不定义清楚,让测试先行的开发者硬写测试,最后只会写出一个“测了但没意义”的测试。
SDD 其实是在给 TDD 补充前置条件:先通过 spec 把行为边界逼出来,再动手写测试。所以 SDD 和 TDD 不是二选一,而是上下游关系。spec 回答“要做什么”,测试回答“怎么证明做对了”,最后由实现代码回答“怎么做到的”。
1.3 OpenSpec 与 Superpowers 在流程中的分工
把两个工具放在一起之后,它们的角色非常清晰:
| 工具 | 角色 | 核心价值 |
|---|---|---|
| OpenSpec | 规格管理 | 把需求变成结构化的 spec 文件,提供变更、审阅、版本管理机制 |
| Superpowers | 开发辅助技能集 | 在 Codex 等 AI 编程助手中注入可执行的开发流程,读取 spec、生成测试、生成实现 |
我习惯把 OpenSpec 理解为“需求与代码之间的契约层”,而 Superpowers 是“执行层”。OpenSpec 告诉你应该做什么,Superpowers 则具体指导 AI 助手按照流程一步步实现。两者一起用,效果是:你的 AI 编码工具不再是一次性聊天框,而是变成一个知道流程、知道规范、知道怎么自己验活的工程助手。
提示:如果你只用 OpenSpec 不用 Superpowers,你得到的是一个规格管理工具;如果你只用 Superpowers 不用 OpenSpec,你得到的是一个能力很强但方向感不足的编码助手。两者的组合才是完整闭环。
2. 环境准备:把工具装进日常工作流
2.1 OpenSpec 的安装与项目初始化
OpenSpec 的实际安装方式在不同版本里会有些差异,但大体路径是一致的:把它作为命令行工具安装到项目或全局环境中。以常见的 npm 生态为例,一条命令就能完成:
npm install -g openspec安装完成后,在项目根目录执行初始化命令:
openspec init这个命令会生成一个规则约定目录,通常包括 specs 目录、变更记录文件以及配置文件。初始化之后,项目里会多出一个 specs 文件夹,专门用来存放按模块拆分的规格说明。
如果你是团队协作,可以把 specs 目录一起提交到 git 仓库。这样每次需求变更都能走代码评审流程,而不是依赖某个人脑子里的记忆。
2.2 通过 Codex CLI 安装 Superpowers
Superpowers 是按技能包(skill)方式运行的,最常见的载体是 Codex CLI。安装思路非常简单:从技能仓库将 Superpowers 克隆或下载到本地技能目录,然后让 Codex 在运行时能识别到它。
以我实测过的方式为例,假设你的 Codex 配置中已经指定了项目级目录~/.codex/skills,那么安装步骤就是:
git clone https://github.com/your-superpowers-repo/superpowers ~/.codex/skills/superpowers克隆完成后,建议做一次目录检查,确认技能包内包含 skills 子目录和对应的说明文件。如果目录结构不对,Codex 是识别不到的,这是新手最容易踩的坑。
2.3 验证工具是否协同工作
装完之后不要急着写业务代码,先验证两个工具是否真的协同。我的验证办法有两个:
第一个,在项目里跑一次 OpenSpec 的变更创建命令,生成一个最小 spec,确认目录结构正常。
openspec change new 2025-01-test-change第二个,在 Codex 里直接向 Superpowers 提问,例如“请基于当前项目的 spec 工作流,指导我完成第一个变更”。如果 Superpowers 生效,AI 会按照 skill 文件里定义的流程逐步响应,而不是给一段通用回答。
注意:打开 Codex 时,可以通过命令行直接指定说明文件来激活 Superpowers。如果发现 AI 回答完全忽略 spec 目录的存在,多半是技能包没有加载成功,优先检查路径、文件名和权限。
3. 核心实操:从空 spec 到测试通过的完整闭环
3.1 一个规范化的 spec 文件长什么样
OpenSpec 的 spec 文件不是自由散文,而是有结构约定的。以我之前做过的“用户头像上传”功能为例,新建的 change 目录下会包含一个 proposal.md 文件,核心段落一般是:
## 变更原因 用户目前无法更换个人头像,影响社区互动体验。 ## 行为变化 - 用户在个人信息页可点击上传头像图片; - 系统对图片大小、格式进行校验; - 校验通过后保存头像 URL 并展示。 ## 影响范围 - 用户模块 / profile 服务 - 个人信息前端页面这段内容看起来像需求文档,但它的价值在于为后续测试提供输入。每一条行为变化,都应该能映射到一个或多个测试用例。写 spec 时不要用“优化”“增强”这类模糊词,而是写“当 A 场景发生时,系统会 B”,这样测试才写得出来。
3.2 从 spec 到测试:先让测试失败
按 SDD+TDD 的顺序,spec 定稿之后立刻进入测试编写阶段。还是头像上传的场景,对应的测试可以拆成三条:
test('用户上传小于5MB的合法图片,返回头像URL'); test('用户上传大于5MB的图片,返回大小超限错误'); test('用户上传非图片文件,返回格式错误');在实现还没有写的时候,这些测试会全部失败,或者因为依赖的接口根本不存在而报编译错误。这个阶段失败是对的,它能证明测试真的在验证行为。很多团队忽略这一步,直接用 AI 生成代码,结果出现“测试全部通过但功能根本不完整”的情况,就是缺少了红-绿-重构里的红。
3.3 用 Superpowers 引导生成实现代码
测试写好之后,让 Superpowers 参与进来。Superpowers 的能力不是帮你写一大段代码,而是按 skill 中所定义的流程,指导 AI 助手读懂 spec、运行测试、修改实现、再次运行测试,循环往复直到目标行为全部可验证。
用 Codex CLI 时,我会先输出一条指令,例如:
codex "请加载 superpowers 技能,依据 specs/2025-01-test-change/proposal.md 中描述的行为变化,在 tests 目录中补齐失败测试的对应实现,并运行测试直到通过"这时候 Superpowers 会引导 Codex 进入“先看测试失败再改代码”的循环,而不是直接甩出一整段实现。它能减少一种很常见的失控现象:AI 一次性生成大段代码,结果把不相关的模块也改了。
从实操效果来说,网络上的相关热词里有很多人搜“superpowers 如何使用”,说明很多人卡在这一步。我的建议是不要指望 Superpowers 替你做设计决策,它的价值在于让 AI 帮手的行为更规范、更有章法。
3.4 把 SDD+TDD 跑成一个固定循环
当单个变更跑通之后,要把它固化成团队日常流程。运行循环的节奏我在团队里落地成了四步:
- 产品需求产生后,先写 change 的 spec 文件并提交评审;
- spec 评审通过,根据行为变化编写测试用例,跑红;
- 使用 Superpowers 在 Codex 中实现代码,直到测试全绿并完成 code review;
- 测试全绿后,回到 OpenSpec 执行变更完成指令,让这次 spec 变更归档。
这四步跑顺之后,开发节奏从“需求会议-开发-吵架”变成了“写规格-写测试-补实现-归档”,每次需求变更都有据可查。
4. 完整案例:为用户配置模块落地 SDD+TDD 工作流
4.1 需求拆解与 spec 编写
下面用一个更完整的例子过一遍全流程。假设我们有一个 Web 应用,需要增加一个用户配置模块,核心功能是允许用户修改自己的昵称,并校验昵称是否合法。
我先用 OpenSpec 创建变更:
openspec change new user-profile-nickname然后编写 proposal.md,把行为写细:
## 变更原因 用户希望修改个人昵称,目前系统不支持。 ## 行为变化 - 用户可在设置页输入新昵称并提交; - 昵称长度为 2 到 20 个字符,超过或不足时提交失败; - 昵称不可包含特殊符号,仅允许中英文、数字、下划线; - 修改成功后,页面展示新昵称并同步到用户信息接口。 ## 影响范围 - user profile 领域模型 - 用户设置接口 - 前端设置页不要小看这种逐条列举,它直接决定后面的测试数量。如果这一阶段不写清楚“长度 2 到 20”,后面的测试就是拍脑袋。
4.2 测试先行与实现生成
根据上面的行为变化,我设计了四组测试用例:
| 测试场景 | 输入 | 预期结果 |
|---|---|---|
| 合法昵称 | “新的昵称” | 修改成功,返回 true |
| 昵称过短 | “a” | 返回长度错误 |
| 昵称过长 | 长度为 21 的字符串 | 返回长度错误 |
| 非法字符 | “你好!” | 返回格式错误 |
测试写好之后,第一次运行全部失败。原因很简单,接口还不存在。此时请 Superpowers 介入,我在 Codex 里会让 AI 实现updateNickname函数,并且明确要求它“在实现过程中运行测试,直到所有测试通过”。
Superpowers 的 skill 在这中间起到的作用是节点控制。没有它,Codex 可能把校验逻辑写在接口层之外的另一处,或者尝试重构整个项目;有了它,AI 会按 skill 描述的步骤一步步走,先读 spec,再读测试,再定位实现位置。
4.3 回归验证与变更归档
所有测试通过之后,不要急着开始下一个需求,回到 OpenSpec 完成变更:
openspec change complete user-profile-nickname这一步会把当前变更合并进项目的规格基线。以后如果有人问“昵称长度到底是多少”,直接查 specs 基线文件就行,不用翻聊天记录。
实测下来,一次干净的变更大概在 20 分钟到 1 小时之间,具体取决于复杂程度。和之前没有规范时相比,最大的差别是任何时候中断都能恢复:打开 specs 目录就知道做到哪一步了。
5. 常见问题与排查技巧实录
5.1 Superpowers 技能包没有被加载怎么办
这是出现频率最高的问题,症状是你在 Codex 里怎么喊 Superpowers 都没反应,AI 的回复和平时完全一样。
排查顺序按下面三条来:
- 检查技能包目录是否在 Codex 配置的加载路径下;
- 检查 skill 描述文件是否存在且格式正确;
- 尝试在 Codex 中直接询问“可用的技能列表”,看它是否列出 Superpowers。
有几次我以为是技能没装好,结果只是目录层级套深了一层。技能仓库解压出来通常会有一层 GitHub 风格的文件夹,用户要找到superpowers根目录,把它整个放到 skill 目录里,而不是再包一层。
5.2 spec 写得太粗导致生成代码跑偏
AI 生成代码跑偏,几乎都是 spec 没有约束到位。举一个实际例子:我让 AI 实现一个“搜索”按钮,但 spec 里没写清搜索是前端过滤还是后端查询,结果 AI 在两个方案之间来回摇摆,最后生成了一版刷新页面的伪实现。
解决的办法只有一条:把粒度细化到“行为可观察”。你写“当用户点击搜索按钮后,列表区域展示与关键词匹配的结果”,比写“支持搜索功能”要可靠得多。这条技巧同样适用于人有团队协作——spec 越细,评审越容易发现问题。
5.3 测试全绿但对需求理解错了怎么办
这是一个隐蔽问题。测试全绿,不代表需求做对了。比如需求是“用户上传头像后裁剪为正方形”,你写成“保存原图并压缩比例”,测试当然能动,但结果和产品预期完全不同。
我的做法是在 spec 评审时加上验收场景的复核:对每一条行为变化,问一句“用户能从界面上观察到什么变化”。如果这句话说不出来,说明 spec 本身有问题。有几次我宁可推迟编码时间,也要先把这条拧清楚,否则后续返工成本更高。
5.4 团队协作时 spec 与代码的同步节奏
多人协作时容易出现的乱象是 spec 已经更新到第三版,代码还在按第一版实现。如果项目使用 git,我建议把 spec 目录纳入 code review 范围,不允许绕过 code review 直接改规格。规格变更相当于需求变更,线上偷偷改版本一定会出事故。
另外可以借助 Codex 和 Superpowers 的能力,在实现代码时让它输出一份与原始 spec 的映射说明。哪个测试对应哪个行为变化,实现改动了哪些文件,都可以作为 review 时的对照材料。我们团队这么跑了几周之后,评审效率明显提升,因为不用每个人从头读一次代码了。
6. 把工作流扩展到自己项目里的几个建议
如果你之前完全没有接触过 SDD,不要一上来就把所有模块都要求写 spec,那样团队会直接反抗。我建议先选一个边界清晰、改动频繁的小模块做试点,比如用户配置、偏好设置或导出功能,跑通一轮完整闭环,让大家看到收益后再逐步铺开。
Superpowers 不是银弹,它是一个流程增强工具。关键是背后的流程本身要合理。我在实际使用中最大的体会是:这一套工作流最大的价值不是自动化,而是它逼着你在写代码之前先想清楚行为边界。很多代码写不下去,根本原因是需求没有描述到行为粒度,和工具没关系。
最后分享一个小技巧。在 OpenSpec 的 change 目录里,保存一些成功的 spec 作为模板。下次写新 spec 时,直接参考已经通过评审的写法,比从空白文档开始要快得多,也能保持团队风格一致。我在连续写了十几个 change 之后,已经能在一杯咖啡的时间内完成一个中大型功能的规格初稿。这种手感,光看工具文档是练不出来的。