OpenSpec与Superpowers结合:实现SDD规范驱动开发的AI编码工作流
1. 项目概述:当OpenSpec遇上Superpowers,AI编码的“最后一公里”终于打通
如果你和我一样,在过去一两年里深度折腾过各种AI编码助手,从早期的GitHub Copilot到后来的Cursor、Claude,再到各种本地部署的大模型,那你一定经历过一个典型的“分裂”状态:一边是AI生成的代码片段像雪花一样飞来,速度飞快;另一边是你自己得手动把这些片段拼凑起来,理解上下文,调试边界条件,最后还得写测试和文档。整个过程就像是一个蹩脚的接力赛,AI跑完第一棒,把接力棒(也就是生成的代码)往地上一扔,剩下的九棒还得你自己气喘吁吁地捡起来跑完。效率提升了吗?确实有,但远没有达到“工作流自洽”的质变。
直到我最近把OpenSpec和Superpowers这两个工具“焊死”在一起,整个局面才豁然开朗。这感觉,就像是给AI编码这辆跑车,终于装上了自动导航和底盘稳定系统,让它不仅能跑直线,还能自己过弯、超车,甚至处理突发路况。简单来说,OpenSpec负责定义“做什么”和“做成什么样”(即规范与契约),而Superpowers则赋予AI“如何做”的上下文与执行能力。当它们紧密结合,就形成了一套从意图到可交付代码的完整、闭环的AI驱动开发工作流,也就是最近在开发者圈子里热议的SDD(Specification-Driven Development,规范驱动开发)。
这套组合拳最适合谁?我认为是三类人:一是中小型团队的Tech Lead或架构师,你们需要快速将设计落地,并保证代码质量的一致性;二是独立开发者或小型工作室,资源有限,必须最大化AI的杠杆效应;三是任何对“如何让AI真正理解业务并生成可靠代码”这个命题感到好奇的实践者。接下来,我就把自己踩坑、调试、最终跑通这套工作流的全过程拆解给你看,这不仅仅是一篇教程,更是一次关于未来开发模式的实地勘探。
2. 核心理念拆解:为什么是SDD,而不仅仅是TDD或DDD?
在深入工具之前,我们必须先统一思想:SDD究竟是什么,以及它为何能成为AI编码时代的“杀手级”方法论?
我们都很熟悉TDD(测试驱动开发)和DDD(领域驱动设计)。TDD的核心是“红-绿-重构”,用测试用例来驱动功能实现,确保代码正确性。DDD则关注通过统一的语言和模型来应对复杂业务逻辑。它们都很优秀,但在AI辅助编码的语境下,都面临一些挑战:
- TDD的挑战:让AI直接根据一个失败的测试用例(红)来生成代码(绿),效果往往不佳。因为AI缺乏对“为什么这个测试会失败”以及“这个功能在整个系统中的角色”的宏观理解。它生成的代码可能仅仅是通过了当前测试,却破坏了其他隐式契约。
- DDD的挑战:DDD的概念(聚合根、值对象、领域服务等)对于AI来说过于抽象和依赖上下文。如果没有极其精确的限定和示例,AI很容易生成结构混乱、不符合领域模型的代码。
SDD(规范驱动开发)正是在此背景下被提出的一个演进思路。它的核心主张是:将人类最高级、最明确的意图——即“规范”(Specification)——作为开发流程的唯一源头和真理。这个“规范”不是一份冗长的Word文档,而是一份结构化、机器可读、无歧义的描述文件。它明确规定了:
- 接口契约:API的端点、方法、输入输出数据的精确结构(JSON Schema)、错误码。
- 业务规则:数据验证逻辑、状态转换条件、权限规则。
- 非功能性需求:性能指标、安全要求、兼容性说明。
SDD的工作流可以概括为:编写规范 -> AI基于规范生成代码 -> 验证代码符合规范 -> 迭代。这里的“验证”不仅包括传统的单元测试,更重要的是通过规范本身对生成的代码进行静态校验和契约测试。
OpenSpec和Superpowers的组合,恰好完美地支撑了SDD。OpenSpec是规范的“书写语言”和“校验器”,而Superpowers则为AI提供了理解这份规范并据此行动的“超级上下文”。两者结合,确保了从“人类意图”到“机器代码”的转换路径是直接、可控且高保真的。
3. 工具深度解析:OpenSpec与Superpowers如何各司其职
3.1 OpenSpec:你的机器可读“产品需求说明书”
OpenSpec不是一个具体的软件,而是一种规范格式和一套工具链。你可以把它想象成针对API和组件的“TypeScript类型定义”,但功能强大得多。它的核心是一个YAML或JSON格式的文件(通常命名为openapi.yaml或spec.yaml),但这个文件遵循了OpenAPI Specification标准的一个超集或特定扩展。
它的核心价值在于:
- 单一事实来源:前端、后端、测试、文档都基于同一份OpenSpec文件,彻底消除沟通歧义。
- 机器可读与可执行:工具可以读取它来生成代码、模拟服务器、验证请求、创建测试用例。
- 面向AI优化:结构化的数据比自然语言描述更能被AI准确理解。一个定义良好的
schema能直接告诉AI:“user对象必须包含id(整数)、name(字符串,必填) 和email(字符串,符合邮箱格式)”。
一个极简的OpenSpec片段示例:
openapi: 3.0.0 info: title: 用户管理系统API version: 1.0.0 paths: /users/{userId}: get: summary: 获取用户详情 parameters: - name: userId in: path required: true schema: type: integer responses: '200': description: 成功 content: application/json: schema: $ref: '#/components/schemas/User' '404': description: 用户不存在 components: schemas: User: type: object required: - id - name properties: id: type: integer format: int64 name: type: string email: type: string format: email这份规范明确无误地定义了一个GET接口。AI拿到它,就能毫无歧义地生成对应的控制器代码、数据库查询逻辑、乃至前端调用的Service函数。
实操心得:不要试图一开始就写一个完整的、庞大的OpenSpec文件。应该采用迭代方式,为当前正在开发的核心功能模块先定义规范。从一个简单的、独立的端点开始,让AI生成代码,验证跑通,再逐步扩展规范。这比先花一周写完所有接口规范再开发要高效、务实得多。
3.2 Superpowers:赋予AI“场景化记忆”的上下文增强器
如果说OpenSpec给了AI“图纸”,那么Superpowers就是给AI配了一个“资深架构师助理”,这个助理记得项目里所有的细节和约定。
Superpowers通常以IDE插件(如VS Code扩展)或CLI工具的形式存在。它的核心功能是项目管理与上下文注入。它不仅仅是一个聊天窗口,而是一个智能的“项目感知”系统。
它主要解决以下痛点:
- 上下文遗忘:普通的AI对话,你每次都要重新解释项目结构、技术栈、编码风格。Superpowers会主动维护一个持久的项目上下文(通过扫描项目文件、读取配置文件如
package.json、.gitignore、README.md等)。 - 指令碎片化:你需要反复说“参考
/utils/helper.js里的格式”、“遵循我们项目的ESLint规则”。Superpowers可以预设这些规则,并在每次交互中自动带入。 - 操作断层:AI生成的代码,你需要手动复制、粘贴、创建文件。Superpowers可以直接在IDE中操作文件系统,根据指令创建、修改、移动文件,甚至执行终端命令。
Superpowers的典型工作流程:
- 你打开项目,Superpowers插件自动加载,分析项目结构。
- 你在聊天框输入:“基于
openapi.yaml里/users的POST规范,在src/routes/下创建对应的Express.js路由处理器,并连接到UserService。” - Superpowers会做以下几件事:
- 读取
openapi.yaml,找到对应的规范。 - 理解你项目的结构(
src/routes/目录存在,使用的是Express.js)。 - 知晓
UserService的位置和接口。 - 生成完全符合上下文的代码。
- 直接在
src/routes/userRoutes.js中创建或插入代码块。
- 读取
- 你审查生成的代码,几乎无需修改,因为它已经遵循了项目的所有约定。
注意事项:Superpowers的强大依赖于你项目本身的“整洁度”。一个结构混乱、没有清晰约定的项目,会让Superpowers也无从下手。在引入Superpowers之前,建议先花点时间规范项目结构、统一编码风格(配置好Prettier、ESLint),这能极大提升后续AI协作的效率。
4. 实战:构建自洽的AI编码工作流
理论说再多,不如亲手搭一遍。下面我以构建一个简单的“待办事项(Todo)API”为例,展示如何将OpenSpec和Superpowers“焊死”,形成一个流畅的工作流。
4.1 环境准备与初始化
首先,确保你的开发环境已经就绪:
- 安装Node.js:这是运行JavaScript工具链的基础。
- 安装VS Code:并安装以下插件:
- Superpowers插件:在VS Code扩展商店搜索“Superpowers”或其具体发行名称(如“Qoder”、“Claude for VS Code”等,具体名称可能因版本而异)并安装。安装后通常需要在插件设置中配置你的AI API密钥(如OpenAI、Anthropic等)。
- OpenAPI (Swagger) Editor:用于高亮和校验OpenSpec文件。
- ESLint和Prettier:用于代码风格统一。
- 创建项目目录:
mkdir ai-todo-api && cd ai-todo-api npm init -y - 安装基础依赖:
npm install express npm install -D nodemon
4.2 第一步:用OpenSpec定义“宪法”
在项目根目录创建openapi.yaml文件。这是我们工作流的起点,也是“宪法”。我们先定义最核心的创建和列取Todo的接口。
openapi: 3.0.0 info: title: AI驱动待办事项API version: 1.0.0 description: 这是一个演示SDD工作流的简单API。 servers: - url: http://localhost:3000/api description: 本地开发服务器 paths: /todos: get: summary: 获取所有待办事项 operationId: getTodos responses: '200': description: 成功 content: application/json: schema: type: array items: $ref: '#/components/schemas/Todo' post: summary: 创建新的待办事项 operationId: createTodo requestBody: required: true content: application/json: schema: $ref: '#/components/schemas/TodoInput' responses: '201': description: 创建成功 content: application/json: schema: $ref: '#/components/schemas/Todo' '400': description: 输入参数无效 components: schemas: Todo: type: object required: - id - title - completed properties: id: type: string format: uuid description: 待办事项的唯一标识符 title: type: string description: 待办事项标题 example: "学习OpenSpec" completed: type: boolean description: 是否已完成 default: false createdAt: type: string format: date-time TodoInput: type: object required: - title properties: title: type: string description: 待办事项标题 example: "学习OpenSpec" completed: type: boolean description: 是否已完成 default: false这份规范清晰地定义了数据模型(Todo,TodoInput)和两个端点(GET/todos, POST/todos)。operationId是关键,它将作为生成代码时函数名的依据。
4.3 第二步:用Superpowers生成骨架代码
现在,打开VS Code,确保Superpowers插件已激活并正确配置了API密钥。在项目根目录打开终端,输入code .在VS Code中打开项目。
操作1:生成Express应用骨架在Superpowers的聊天面板中输入:
基于当前目录的package.json,这是一个Node.js项目。请为我创建一个基本的Express.js服务器文件 `app.js`。要求: 1. 监听3000端口。 2. 添加必要的中间件:解析JSON的body-parser。 3. 为 `/api` 路径添加一个路由器。 4. 导出一个可供测试的app实例。Superpowers会生成类似下面的代码,并可能直接创建app.js文件:
const express = require('express'); const app = express(); // 中间件 app.use(express.json()); // 解析 application/json // 路由 const apiRouter = express.Router(); app.use('/api', apiRouter); // 根路径 app.get('/', (req, res) => { res.json({ message: 'Todo API is running' }); }); const PORT = process.env.PORT || 3000; app.listen(PORT, () => { console.log(`Server is running on port ${PORT}`); }); module.exports = app; // 导出供测试使用操作2:根据OpenSpec生成路由和控制器这是核心步骤。在聊天框输入更具体的指令,将OpenSpec作为上下文:
请阅读项目根目录下的 `openapi.yaml` 文件。根据其中的规范: 1. 在 `src` 目录下创建以下结构:`src/routes/todoRoutes.js` 和 `src/controllers/todoController.js`。 2. 在 `todoRoutes.js` 中,实现 `/todos` 的GET和POST路由,它们应调用 `todoController.js` 中对应的 `getTodos` 和 `createTodo` 函数。 3. 在 `todoController.js` 中,暂时用内存数组模拟数据层,实现这两个函数。请严格遵循 `openapi.yaml` 中定义的请求和响应格式,特别是 `Todo` 和 `TodoInput` 的schema。 4. 最后,修改 `app.js`,将 `apiRouter` 挂载上 `todoRoutes`。Superpowers会执行以下动作:
- 读取并理解
openapi.yaml。 - 创建
src目录及子目录。 - 生成高度符合规范的路由文件。例如,
src/routes/todoRoutes.js:const express = require('express'); const router = express.Router(); const todoController = require('../controllers/todoController'); router.get('/todos', todoController.getTodos); router.post('/todos', todoController.createTodo); module.exports = router; - 生成控制器文件
src/controllers/todoController.js,其中包含模拟数据和严格的输入验证(基于OpenSpec的schema精神):// 模拟数据库 let todos = []; let nextId = 1; const todoController = { getTodos: (req, res) => { // 直接返回模拟数据,格式符合Todo schema res.status(200).json(todos); }, createTodo: (req, res) => { const { title, completed = false } = req.body; // 基础验证 (对应OpenSpec中TodoInput的required: title) if (!title || typeof title !== 'string') { return res.status(400).json({ error: 'Invalid input: title is required and must be a string' }); } // 创建新的Todo对象,格式严格遵循Todo schema const newTodo = { id: `todo-${nextId++}`, // 模拟uuid title, completed: Boolean(completed), createdAt: new Date().toISOString(), }; todos.push(newTodo); res.status(201).json(newTodo); // 返回创建的对象 }, }; module.exports = todoController; - 自动更新
app.js,添加const todoRoutes = require('./src/routes/todoRoutes');和apiRouter.use(todoRoutes);。
整个过程,你几乎没有手动编写业务逻辑代码,只是给出了精确的指令和规范。Superpowers基于OpenSpec这个“宪法”,生成了完全合规的代码骨架。
4.4 第三步:验证与迭代——工作流的闭环
生成代码后,工作流并未结束,验证是确保“自洽”的关键。
运行与测试:
- 修改
package.json的scripts:"dev": "nodemon app.js" - 运行
npm run dev。 - 使用Postman或curl测试
GET http://localhost:3000/api/todos和POST http://localhost:3000/api/todos。 - 观察响应是否符合OpenSpec的定义(状态码、JSON结构)。
- 修改
规范变更驱动代码更新: 这是SDD最强大的地方。假设产品经理要求为Todo增加一个
priority(优先级)字段。- 第一步,更新“宪法”:修改
openapi.yaml,在Todo和TodoInput的schema里添加priority属性(枚举类型:low,medium,high)。 - 第二步,指令AI同步更新:在Superpowers中输入:
我更新了 `openapi.yaml`,为Todo模型添加了 `priority` 字段(枚举值:low, medium, high)。请相应地更新: 1. `src/controllers/todoController.js` 中的 `createTodo` 函数,使其能接收并验证 `priority` 字段,默认值为 'medium'。 2. 同时,更新内存模拟数据中已有的todo对象,为它们添加一个默认的 `priority: 'medium'`。 3. 确保GET请求返回的数据也包含此字段。 - Superpowers会分析
openapi.yaml的变更,并精准地修改控制器代码,更新数据初始化逻辑。你只需要审查变更即可。
- 第一步,更新“宪法”:修改
生成接口文档与客户端SDK: 利用OpenSpec的机器可读性,我们可以轻松生成其他产物,进一步自动化。
- 生成API文档:使用
swagger-ui-express库,可以瞬间将openapi.yaml变成漂亮的交互式API文档页面。 - 生成前端TypeScript类型或API客户端:使用
openapi-generator等工具,可以直接从规范生成前端调用所需的类型定义和请求函数,保证前后端类型安全。
- 生成API文档:使用
至此,一个完整的、基于OpenSpec(规范)和Superpowers(AI执行)的SDD工作流就形成了:修改规范 -> AI同步代码 -> 验证 -> 生成衍生资产。这个循环是高度自洽且高效的。
5. 进阶技巧与避坑指南
将两个工具“焊死”意味着更深度的集成和更高效的操作。以下是一些我实践中总结的进阶技巧和常见问题的解决方案。
5.1 如何设计对AI友好的OpenSpec?
AI不是人,它需要清晰、无歧义的结构化信息。一份对AI友好的OpenSpec应具备:
- 完整的
operationId:为每个路径操作都设置一个唯一的、语义化的operationId(如getUserById,createOrder)。这将是AI生成函数名的最佳依据。 - 详尽的Schema定义:尽量使用
$ref引用可复用的组件,但确保每个schema都定义了type、required、properties以及example。example字段能给AI提供极其重要的上下文范例。 - 清晰的描述(description):在每个路径、操作、参数旁边用简单的英语描述其业务目的。例如,
description: “根据用户ID获取用户详情,仅限管理员或用户本人访问。”这能帮助AI理解业务上下文,生成更合理的代码(比如加入权限校验)。 - 使用枚举(enum)和格式(format):对于有限集合的值(如状态、类型),务必使用
enum。对于邮箱、日期、UUID等,使用标准的format。这能让AI生成更精确的验证逻辑。
5.2 最大化Superpowers效能的配置与提示词工程
Superpowers的能力上限取决于你如何配置和与它对话。
- 项目级配置:在项目根目录创建一个
.superpowers或.cursor/rules文件(取决于具体工具)。在这个文件里,你可以预设:
这相当于给了AI一个项目的“员工手册”。{ "project_context": "这是一个基于Node.js和Express的RESTful API项目,使用ES模块语法。代码风格遵循Airbnb JavaScript规范。", "default_tasks": { "create_route": "请参考 `src/routes/userRoutes.js` 的模式创建新的路由文件。", "create_controller": "控制器函数应放在 `src/controllers/` 目录下,遵循 `todoController.js` 的异常处理模式。" }, "files_to_ignore": ["node_modules", ".git", "*.log"] } - 精准的提示词:避免模糊指令。对比以下两种:
- 差:“做个用户登录。”
- 优:“在
openapi.yaml中POST /auth/login路径下,我已定义了请求体(username, password)和响应体(token, userInfo)。请在src/routes/下创建authRoutes.js,并在src/controllers/下创建authController.js实现登录逻辑。密码验证请使用bcrypt库对比哈希值,成功则使用jsonwebtoken库生成一个24小时过期的JWT token返回。” 后者的指令包含了位置、依据、技术细节和库依赖,AI生成的代码会非常接近生产要求。
- 善用“@”引用文件:大多数Superpowers类工具支持在提示词中用
@引用特定文件。例如:“请参考@src/models/User.js中的字段定义,来生成更新用户信息的API。” 这能确保AI使用的上下文是最新的。
5.3 常见问题与排查实录
问题1:AI生成的代码不符合项目编码风格(如缩进、分号)。
- 原因:Superpowers没有获取到项目的风格配置。
- 解决方案:确保项目根目录存在
.eslintrc.js和.prettierrc配置文件。在第一次与AI进行重大项目交互前,可以在聊天框发送这些配置文件的内容,并说:“这是本项目的代码风格配置,请后续所有代码生成都严格遵守此风格。” 之后AI会记住。
问题2:AI总是忘记之前定义的接口或数据结构。
- 原因:对话上下文长度有限,或AI没有主动去读取最新文件。
- 解决方案:在关键指令中,总是明确指向源文件。例如:“基于当前最新的
openapi.yaml文件,请生成...”。对于复杂项目,可以分模块进行,每次只处理一个紧密相关的功能集,减少上下文负担。
问题3:生成的代码有逻辑错误或安全漏洞。
- 原因:AI毕竟不是人,它可能生成有问题的逻辑(如不充分的输入验证、错误的错误处理)。
- 解决方案:AI生成,人类审查。永远不要盲目信任生成的代码。必须将AI视为一个强大的“初级程序员”,它的产出需要资深开发者(你)进行严格审查,特别是业务逻辑、数据验证和安全性相关的部分。建立代码审查环节,即使是AI生成的代码。
问题4:OpenSpec文件变得庞大,难以维护。
- 原因:所有接口定义挤在一个文件里。
- 解决方案:利用OpenAPI的
$ref语法,将不同的组件拆分到多个文件中。
这样,你可以用Superpowers指令AI:“请更新# openapi.yaml paths: /users: $ref: './paths/users.yaml' components: schemas: User: $ref: './components/schemas/User.yaml'./components/schemas/User.yaml,为其添加phoneNumber字段。” 维护性大大提升。
6. 工作流扩展:连接更多自动化环节
一个真正“焊死”的、自洽的工作流不应止步于代码生成。我们可以利用OpenSpec的机器可读性,将其作为源头,触发更多的自动化任务。
- 自动化测试生成:使用如
swagger-test-templates或openapi-generator的测试模板,可以从OpenSpec自动生成接口集成测试的骨架代码,你只需要填充一些模拟数据即可。 - CI/CD集成:在GitHub Actions或GitLab CI中,可以添加一个步骤:每当
openapi.yaml文件发生变更时,自动运行脚本,重新生成客户端SDK并发布到内部的npm仓库,确保前后端契约同步。 - API监控与告警:可以将OpenSpec导入到API网关或监控工具(如Postman Monitor、Datadog)中,自动配置监控的端点、请求方法和预期的成功响应码,实现监控即代码。
这套以OpenSpec为单一事实来源,以Superpowers(AI)为主要执行者,串联起开发、测试、部署、监控的完整流程,才是“AI编码工作流自洽”的终极形态。它不仅仅提升了写代码的速度,更重要的是,它建立了一种可靠、可重复、高质量的价值交付机制。
