OpenSpec-SDD 规范驱动开发
基于 OpenSpec + 规格驱动开发(SDD) + TDD 三者融合的工作流
核心理念:先对齐规范,再动手写代码;AI 与人类在代码之前达成共识。
触发词
- "SDD"、"规范驱动"、"规格驱动"、"先写规范"
- "OpenSpec"、"openspec"
- "TDD前置"、"规格先行"、"需求评审"
- "帮我起草规范"、"写个spec"、"整理需求规格"
使用场景
当你拿到一个需求(功能/接口/模块)时,按以下流程执行:
需求输入 → 规范评审(proposal+spec) → 技术设计(design)
→ 任务分解(tasks) → 评审确认 → 执行实现 → 归档沉淀
特别适用场景:
- 需求模糊,需要先理清楚
- 多方协作,需要评审对齐
- 怕 AI 理解偏差,需要先约定边界
- 需求变更,需要追踪变更记录
六阶段工作流
第一阶段:提案(Proposal)
目标:明确"做什么"和"为什么做",产出 proposal.md
收到需求后,分析并输出:
# {功能名称} 提案
## 背景
为什么要做这个功能?解决什么问题?
## 目标
- 目标1:...
- 目标2:...
## 范围
### 包含
- ...
### 不包含(边界)
- ...
## 成功标准
- 功能上线后达到什么效果?
- 如何验证成功?
## 风险
- 可能的障碍或依赖?
## 关联规范
- 影响哪些现有模块?
判断规范:如果提案不清晰、不完整,继续追问需求方,不要直接进入设计阶段。
第二阶段:需求规范(Spec)
目标:用 Gherkin 格式写出可验证的验收场景,产出 spec.md
# {功能名称} 规范
## 目的(Purpose)
一句话描述这个功能是做什么的。
## 规则(Rules)
业务规则和约束。
## 验收场景(Gherkin格式)
### 场景1:正常流程
- **功能**:XXX
- **背景**:given
- **操作**:when
- **结果**:then
#### 示例场景
- GIVEN 用户已登录
- WHEN 用户访问 /api/xxx
- THEN 返回200,数据结构为{...}
### 场景2:边界情况
...
### 场景3:异常处理
...
### 场景4:权限控制
...
关键原则:
- 每个场景必须是 可验证 的(能写出测试用例)
- 用 Gherkin 格式(GIVEN/WHEN/THEN)
- 覆盖:正常流程 + 边界条件 + 异常处理 + 权限
第三阶段:技术设计(Design)
目标:明确"怎么做",产出 design.md
# {功能名称} 技术设计
## 架构决策
### 数据模型
- 涉及哪些表/实体?
- 新增字段?修改字段?
- 关联关系?
### 接口设计
| 方法 | 路径 | 说明 | 请求参数 | 返回格式 |
|------|------|------|---------|---------|
| GET | /api/xxx | 查询列表 | page,size | {list:[],total} |
### 核心流程
描述关键代码路径,附上时序图或流程图(Mermaid格式)
### 技术选型
- 用什么框架/中间件/工具?
- 为什么这样选?
## 依赖
### 内部依赖
- 依赖哪些已有模块?
### 外部依赖
- 依赖哪些外部接口/服务?
## 兼容性
- 是否涉及数据库迁移?
- 是否影响已有接口?
- 历史数据如何处理?
## 安全考虑
- 权限校验方式?
- 敏感数据处理?
第四阶段:任务分解(Tasks)
目标:将设计拆解为可执行的最小任务,产出 tasks.md
# {功能名称} 实施任务
## 任务清单(按顺序执行)
### 阶段A:基础设施
- [ ] 任务A1:创建数据库表/修改表结构(如需DDL)
- [ ] 任务A2:配置定时任务(如有)
- [ ] 任务A3:初始化数据(如有枚举/配置)
### 阶段B:后端开发
- [ ] 任务B1:Entity/DTO/VO 类
- [ ] 任务B2:Mapper/DAO 层
- [ ] 任务B3:Service 业务逻辑
- [ ] 任务B4:Controller 接口层
### 阶段C:接口文档
- [ ] 任务C1:Swagger 注解补全
- [ ] 任务C2:接口联调测试
### 阶段D:联调与验证
- [ ] 任务D1:前后端联调
- [ ] 任务D2:Spec 验收场景逐一验证
- [ ] 任务D3:回归测试
### 阶段E:上线
- [ ] 任务E1:代码审查(CR)
- [ ] 任务E2:合并分支
- [ ] 任务E3:发布
关键原则:
- 每个任务 原子化,一个任务产出独立可验证的结果
- 标注 优先级:核心路径先做
- 标注 依赖关系:谁先谁后
第五阶段:评审与确认
目标:在动手之前,人类评审员确认 proposal + spec + design
评审清单:
- proposal.md:范围是否清晰?边界是否明确?
- spec.md:验收场景是否覆盖所有情况?是否可验证?
- design.md:技术方案是否合理?是否有遗漏?
- tasks.md:任务拆分是否完整?顺序是否正确?
- 风险项是否已识别?
评审结论:
- ✅ 通过 → 进入第六阶段
- ❌ 不通过 → 回到第一/二/三阶段修改
第六阶段:执行与归档
执行阶段:
- 严格按
tasks.md顺序执行 - 每完成一个任务打勾 ✅
- 实现过程中如发现 spec/design 有问题 → 回到规范阶段修正
归档阶段(任务完成后):
- 将本次变更的四个文件归档到
openspec/changes/archive/YYYY-MM-DD-{change-id}/ - 更新项目主规范(如果本次变更影响到已有规范)
- 清理活跃变更目录
规范模板库
模板1:Entity 规范
# {Entity名称} 实体规范
## 表结构
| 字段名 | 类型 | 约束 | 说明 |
|--------|------|------|------|
| id | BIGINT | PK AUTO_INCREMENT | 主键 |
| ... | ... | ... | ... |
## 索引
- idx_xxx (field1, field2)
## 约束
- 唯一约束:...
- 外键约束:...
## 生命周期
- 创建:谁调用、默认值
- 更新:哪些字段允许更新
- 删除:物理删除/逻辑删除
模板2:接口规范
# {接口名称} 接口规范
## 基本信息
- 接口路径:GET/POST/PUT/DELETE /api/xxx
- 权限:登录/匿名/管理员
- 频率限制:...
## 请求
| 参数名 | 类型 | 必填 | 说明 |
|--------|------|------|------|
## 响应
```json
{
"code": 0,
"message": "success",
"data": {}
}
错误码
| 错误码 | 含义 | 处理方式 |
|---|---|---|
| 1001 | 参数错误 | 提示具体字段 |
### 模板3:定时任务规范
```markdown
# {任务名称} 定时任务规范
## 基本信息
- 任务名称:
- Cron表达式:
- 执行频率:
## 功能说明
做什么?
## 业务逻辑
1. ...
2. ...
## 边界条件
- 数据量过大如何处理?
- 执行失败如何重试?
- 幂等性保证?
## 监控指标
- 执行时长
- 处理数据量
- 失败次数
OpenSpec vs TDD 对比
| 维度 | OpenSpec-SDD | TDD |
|---|---|---|
| 核心 | 规范先行,人机对齐 | 测试先行,代码驱动 |
| 产出物 | proposal + spec + design + tasks | 单元测试 |
| 关注点 | "做什么"和"为什么做" | "怎么验证" |
| 适用阶段 | 功能启动前/需求评审时 | 代码实现时 |
| 配合关系 | SDD在前,TDD在后 | TDD在SDD之后落地 |
推荐工作流:
需求 → SDD(OpenSpec)规范对齐 → TDD 写测试 → 编码实现
注意事项
- 不要跳过规范直接写代码:规范评审是 SDD 的核心,不要为了快而跳过
- 规范要可验证:每个验收场景都能对应一个测试用例
- 变更要留痕:用 spec delta 记录增量变更,不重写全量规范
- 完成后要归档:保持工作目录整洁,规范沉淀到主库
- 先小后大:新项目从单文件 spec 开始,老项目按模块逐步接入
参考资料
- OpenSpec 官方:https://openspec.dev/
- OpenSpec GitHub:https://github.com/Fission-AI/OpenSpec/
- 中文文档:https://radebit.github.io/OpenSpec-Docs-zh/