
OpenSpec Superpowers 搭建 SDDTDD 工作流教学文档先说个直觉现在的 AI 编程工具写代码确实快但写出来的东西经常跑偏——你说要做个导出功能它顺手给你改了配置文件你说要加个缓存它把整个查询逻辑重写了。问题不出在 AI 本身出在我们没有给它一个可执行的流程约束。OpenSpec 和 Superpowers 这套组合就是冲着这个痛点去的OpenSpec 负责把需求写成机器可读的规格文档Superpowers 负责在 Codex CLI 里注入一套能照着规格干活的技能SDD规格驱动开发管设计TDD测试驱动开发管验证两条线拧成一条流水线。这篇文章我会从环境准备、流程设计、实际踩坑三个层面完整介绍这套工作流的搭建方法适合已经在用 AI 辅助编程、但对代码质量有要求的开发者和技术团队参考。1. 从混乱到有序这套工作流到底解决了什么问题1.1 AI 编程的失控点不在代码在上下文我踩过最典型的坑是这样的让 AI 帮我实现一个通过搜索关键词筛选文件列表的功能它确实把搜索逻辑写对了但顺手把结果排序从按修改时间改成了按文件名。单看代码没问题单测也能过但产品经理看一眼就炸了。这种问题反复出现的根源在于传统对话式编程把需求藏在聊天记录里AI 只能靠上下文猜测什么该做、什么不该做一旦上下文窗口滚上去前面的约束就变成了模糊记忆。OpenSpec 的思路是把需求从对话里拿出来变成仓库里的 Markdown 文件。每个功能需求、每条验收标准、每个边界条件都被写成明确条目AI 在动手前会先读这些文件所有决策都基于规格文档而不是对话记忆。规格即契约代码和测试都围绕这份契约展开AI 的自由发挥空间被压缩到可控范围。1.2 SDD 管做什么TDD 管对不对SDD 和 TDD 并不是二选一的关系而是上下游关系。SDDSpecification-Driven Development关注的是需求定义这个功能要解决什么问题、有哪些输入输出、边界条件是什么、怎么验收。TDDTest-Driven Development关注的是代码验证先写一个肯定会失败的测试再写最小代码让测试通过最后重构。前者回答做什么后者回答有没有做对。把两者组合起来以后整个流程变成了这样规格文档定义需求和验收标准 → AI 根据规格拆解任务并生成失败测试 → AI 写最小代码让测试通过 → 重构消除重复代码。每一步都有明确输出物每一步都有验证手段。这跟我们以前手动写需求文档、写测试用例、写实现代码的顺序完全一样但全部交给 AI 按流程执行人只负责审查关键节点。这套流程适合谁适合所有用 AI 写代码、但不想被 AI 的过度自信坑到的人。不管你是独立开发者还是团队协作只要代码要上线、要维护规格先行就值得做。它不能替代你的判断力但它能逼你在让 AI 动手之前先把需求想清楚。2. 环境准备OpenSpec 和 Superpowers 的安装与初始化2.1 安装 Codex CLI 并注入 Superpowers 技能Superpowers 是 Davin Reed 发布的一套 Codex CLI skills 集合本质上是给 AI 预装了一套工作技能包里面包含 TDD workflow、plan writing、debugging 等多个可复用的技能模块。安装方式取决于你用的 CLI 客户端如果你用codex作为交互终端命令是这样的# 1. 确保 Codex CLI 已安装并完成登录 codex --version # 2. 把 Superpowers 技能克隆到 Codex 的 skills 目录 git clone https://github.com/workflow-superpowers/book-codex.git ~/.codex/skills # 3. 用 workbuddy 批量安装 skill 包可选推荐 npx workbuddylatest install skill superpowers用 workbuddy 安装的好处是它会自动处理 skill 之间的依赖关系并且注册到一个统一的技能管理列表里。安装完成后进入 Codex 交互界面输入superpowers关键字如果能看到对应的技能加载信息就说明安装成功。注意Superpowers 本质上是外置技能包不同版本对 Codex CLI 的兼容性略有差异。我用的版本要求 Codex CLI 在 0.42 以上如果你的版本太旧技能包注册后可能不会被读取。遇到这种情况先升级 CLI不用急着排查技能文件本身。2.2 初始化 OpenSpec 规范目录OpenSpec 本身是一个轻量级命令行工具核心是目录即规范。在你的项目根目录下执行# 安装 OpenSpec CLI npm install -g openspec # 在项目根目录初始化规范目录 cd /path/to/your/project openspec init初始化过后项目里会生成一个openspec/目录默认结构如下openspec/ ├── specs/ # 存放当前有效的规格文档 ├── changes/ # 存放工作中的变更提案 └── proposals/ # 存放历史提案归档这个结构跟 Git 的.git目录有点像——它不参与业务代码编译但所有 AI 编程流程都以它为准。每个新功能启动前你需要新建一个change提案提案里写清楚要改什么、为什么改、验收标准是什么AI 会根据这份提案去拆任务、写测试、写实现。规格腐化成摆设本质上是大家嫌写文档麻烦但 OpenSpec 的粒度足够小一个提案一页纸就够成本完全可控。2.3 环境变量的额外配置为了让 Codex CLI 在读取规格后能自动执行先测试后实现的流程我建议在 shell 配置文件里加一个变量让 AI 的高风险操作默认进入审查模式# ~/.zshrc 或 ~/.bashrc export CODEX_HIGH_RISK_OPERATIONSplan这样 AI 在准备执行规格任务时会先生成一份详细计划供你确认而不是直接开始改代码。对团队协作来说这一步能极大减少AI 改了不该改的文件这类事故。3. 核心实操流程从一个真实功能跑通 SDDTDD 闭环3.1 写规格把需求变成可验收的 Markdown理论讲再多不如跑一遍真实流程。我选了一个有代表性的小功能来做演示给一个命令行书签管理工具增加通过关键词搜索书签并按时间排序的能力。需求描述看起来很简单但信息量挺大——有输入、有输出、有排序规则、有时间字段。先创建一个变更提案openspec new add-search-to-bookmark这会生成openspec/changes/add-search-to-bookmark/spec.md我在此基础上填入了完整规格# 变更提案add-search-to-bookmark ## 变更类型 新增功能 ## 原因说明 用户目前无法快速从大量书签中找到目标条目 需要通过关键词过滤并以可预期的方式排序结果。 ## 规格详情 ### 需求描述 新增一个 bookmark search 子命令按关键词过滤现有书签 结果按创建时间倒序排列。 ### 实现要点 - 支持大小写不敏感的关键词匹配匹配范围包括标题和 URL。 - 输出内容包括ID、标题、URL、创建时间。 - 无匹配结果时返回空列表并给出友好提示。 - 排序顺序固定为创建时间倒序即最新创建的排在最前面。 - 不得修改现有书签创建、删除、列表命令的行为。 ### 验收标准 - [ ] bookmark search keyword 返回所有标题或 URL 中包含关键词的书签。 - [ ] 输出内容按创建时间倒序排列。 - [ ] 关键词匹配不区分大小写。 - [ ] 不改变其他子命令的现有行为。 - [ ] 无匹配结果时输出提示信息退出码为 0。规格里那句不得修改现有行为是我特别加的。AI 在改代码时经常顺手优化掉其他逻辑验收标准里明确写出来运行时才有依据去约束它。写完规格后保存这份文档就是后续所有 AI 操作的地图。3.2 让 AI 拆解任务并生成失败测试打开 Codex CLI进入项目目录给 AI 明确指令请阅读 openspec/changes/add-search-to-bookmark/spec.md 按 TDD 方式完成该功能。先拆分任务再对每个任务编写失败测试 不要开始写实现代码。如果 Superpowers 加载正常AI 会调用 TDD 工作流技能输出一份任务清单类似这样创建bookmark search命令入口和参数解析。实现关键词过滤逻辑标题 URL忽略大小写。实现创建时间倒序排序。实现空结果提示。添加或调整测试覆盖上述行为。随后它会为每个任务生成测试文件。以 Node.js 项目为例测试代码会是这个样子import { describe, it, expect } from vitest; import { searchBookmarks } from ../src/search.js; describe(bookmark search, () { const bookmarks [ { id: 1, title: OpenAI Blog, url: https://openai.com/blog, createdAt: 2024-01-10 }, { id: 2, title: Dev.to, url: https://dev.to, createdAt: 2024-02-15 }, { id: 3, title: GitHub Docs, url: https://docs.github.com, createdAt: 2024-03-01 } ]; it(应按关键词过滤标题和 URL且不区分大小写, () { const result searchBookmarks(bookmarks, open); expect(result).toHaveLength(2); }); it(应按创建时间倒序排列, () { const result searchBookmarks(bookmarks, ); expect(result[0].id).toBe(3); expect(result[1].id).toBe(2); }); it(无匹配结果时返回空数组, () { const result searchBookmarks(bookmarks, not-exist); expect(result).toEqual([]); }); });这时候跑测试结果一定是失败的因为实现文件还不存在。这个红灯状态非常重要它是 TDD 的起点证明测试真的在起作用。实操心得让 AI先写测试再写实现这个顺序如果你不明确说明它十有八九会反过来。Superpowers 的 TDD skill 会自动约束这个顺序但如果你没装 Superpowers就必须在提示词里强调不得先写实现代码测试通过前不得编写业务逻辑。3.3 最小化实现与绿灯通行测试写好后给 AI 下第二阶段指令现在实现业务逻辑目标是让现有测试通过。不要添加测试未覆盖的功能。 每通过一个测试就汇报一次进度。AI 会开始逐步实现代码每次实现后运行测试。如果某个测试挂了它会根据失败信息修正实现直到全部变绿。这里有个细节值得注意最小化实现阶段AI 往往会把代码写得很简陋。比如为了满足关键词不区分大小写它可能直接写了toLowerCase()硬比较没考虑 URL 解码之类的边界情况。这其实是 TDD 的正常节奏——先让行为正确再回来优化结构。绿灯之后代码结构问题用重构阶段解决。实测中这一步最耗时的地方往往是AI 写的测试和实现相互印证但都理解偏了需求。比如我们规定匹配范围包括标题和 URL但 AI 写测试时只测了标题实现也只过滤了标题。这时候规格文档就派上用场了我会直接指出规格第 3 条明确写了 URL 也要匹配请补充对应测试用例。如果规格里没写AI 可能永远意识不到自己漏了什么。3.4 重构与回归用规格文档守住边界全部测试通过后进入重构阶段。我给 AI 的指令是测试已全部通过。现在在不改变行为的前提下重构代码 重点是消除重复逻辑、提升可读性同时保持测试全绿。这个阶段 AI 可能做的事情包括把过滤和排序拆成独立函数、提取常量、统一错误提示格式。每次重构后都必须跑一遍完整测试确认没有破坏已有行为。我们的规格里写了不得修改现有书签创建、删除、列表命令的行为所以重构结束后我会手动跑一遍回归测试确保其他命令一切正常。到这里一个功能已经从需求描述变成了有规格、有测试、有实现、有重构的完整闭环。整个过程里我做的最重要的事情不是写代码而是在每个阶段确认 AI 的输出没有偏离规格。规格文档是唯一的事实来源测试是唯一的验收标准剩下的执行交给 AI。4. 常见问题与排查技巧实录4.1 高频问题对照速查表问题现象可能原因解决方式AI 直接写实现代码忽略先写测试指令所用 skill 包未加载或未安装 TDD skill执行npx workbuddylatest install skill superpowers重新安装并在提示词里重复强调 TDD 顺序测试通过了但功能行为明显与需求不符规格文档里的验收标准写得太模糊AI 只按自己理解实现回到spec.md补全边界条件增加具体示例然后让 AI 补充测试用例再重跑AI 改动范围超出本次规格连带修改了别的模块开了过大的文件读取权限或上下文里有其他模块的代码片段用 OpenSpec 的变更边界约束 AI 只能读写当前变更涉及的文件必要时在提示词里声明只允许修改与 add-search-to-bookmark 相关的文件Superpowers 技能未被 Codex 识别Codex CLI 版本过老或 skills 目录路径不对升级 Codex CLI 到最新版本确认 skills 目录为~/.codex/skills重启 CLI 会话测试用例本身写错了实现跟着测试一起错测试是在实现代码之前由 AI 生成的但生成时依赖了实现细节测试应基于规格编写而非基于实现。要求 AI 对照spec.md的验收标准逐条映射测试用例避免测试为了通过而通过想让 AI 终止当前操作但总是继续执行交互模式下的中断信号被忽略按两次 CtrlC 强制中断或在提示词中明确停止当前操作等待我的下一步指令4.2 独家避坑心得这套流程跑了两个月我总结出三个最值得说的经验。第一个经验是规格文档一定要包含不要做什么。人写需求时默认没提到的就是不该做的但 AI 恰恰相反——它倾向于把没提到的都当作可以做。在验收标准里明确写不得修改现有行为不得更换现有的数据结构不得引入额外依赖看起来有些多余却能少踩很多坑。第二个经验是不要让 AI 一次性写太多测试。我试过让它为一个大功能一次生成 20 多个测试用例结果有一半都在测无关紧要的细节另一半因为依赖了未实现的中间状态而反复报错。后来我改成每个任务生成 3 到 5 个针对性测试流程顺畅多了。小型化测试包还有一个好处红灯出现时能更快定位到具体是哪个行为没实现。第三个经验是定期把openspec/changes里已完成的变更归档到openspec/proposals。这个动作很多人嫌麻烦会跳过但归档后的提案沉淀了当初为什么这么设计的决策记录。等三个月后你自己回来看代码或者新同事接手项目这些提案比任何代码注释都更有价值。OpenSpec 的设计初衷就是让规格文档和代码共同演进变更被合并、提案被归档项目历史就变成了一条完整的决策链。4.3 当 AI玩忽职守时手动兜底方案偶尔会遇到 AI 无论如何都无法理解需求的情况。这时候不要在一个会话里反复纠缠我通常的做法是把它看作一个执行器而不是协作者手动把任务拆分得更细比如把实现搜索功能拆成第一步创建命令入口第二步读取书签数据第三步实现过滤逻辑第四步实现排序逻辑然后一条一条发给它。这其实也是 SDD 理念的延伸——规格的粒度越细AI 的自由度越低执行结果就越可控。手动拆分看起来多花了几分钟但省掉了后面调试和返工的时间整体效率反而更高。5. 写在最后的实践经验这套 OpenSpec Superpowers 的 SDDTDD 工作流本质上是在 AI 编程时代重新引入了工程纪律。以前我们靠人脑记忆需求约束靠代码评审兜底现在则可以靠规格文档和测试用例把约束固化在流程里。AI 的能力波动不可控但流程可以做到可控。用这套流程跑了一段时间后我最直观的感受是代码 review 的争议少了很多——大家不再争论这个函数应该叫什么名字这类主观问题而是先对齐规格再讨论实现。最后再分享一个小的操作技巧每次让 AI 开始一个新变更时我都会在项目根目录建一个AGENTS.md文件里面写清楚请先阅读openspec/changes/当前变更名/spec.md所有实现必须满足该文档的验收标准测试通过前不得进入下一步。这个文件会让 Codex 在每次会话开始时就自动加载工作流约束相当于给 AI 装了一个开机自启的流程导航。我实测下来加上这个文件之后AI 跑偏的概率至少下降了一半。如果你也在用 AI 写代码我建议你从一个小功能开始尝试这套工作流。不用一开始就追求完整规范先跑通一遍感受一下规格先行和测试先行带来的变化。等你跑顺了两个变更再回来补齐团队规范也会更容易落地。