告别 Vibe Coding:用 SDD 让 AI 编程提效 50%,三工具实战对比

告别 Vibe Coding:用 SDD 让 AI 编程提效 50%,三工具实战对比

一句话摘要:通过将开发重心前置到"写规范",而非直接让 AI 写代码,我在一个后端项目中把原本需要 5 天的工时压缩到 2.5 天,并系统对比了手搓 SDD、OpenSpec、Superpowers 三种路径。本文是完整的实践复盘。


目录

  • [0. 背景与数据](#0. 背景与数据 "#0-%E8%83%8C%E6%99%AF%E4%B8%8E%E6%95%B0%E6%8D%AE")
  • [1. 为什么需要 SDD](#1. 为什么需要 SDD "#1-%E4%B8%BA%E4%BB%80%E4%B9%88%E9%9C%80%E8%A6%81-sdd")
  • [2. 轻量级实践:手搓 SDD](#2. 轻量级实践:手搓 SDD "#2-%E8%BD%BB%E9%87%8F%E7%BA%A7%E5%AE%9E%E8%B7%B5%E6%89%8B%E6%90%93-sdd")
  • [3. 工程化实践:OpenSpec](#3. 工程化实践:OpenSpec "#3-%E5%B7%A5%E7%A8%8B%E5%8C%96%E5%AE%9E%E8%B7%B5openspec")
  • [4. 高阶实践:Superpowers](#4. 高阶实践:Superpowers "#4-%E9%AB%98%E9%98%B6%E5%AE%9E%E8%B7%B5superpowers")
  • [5. 工作原理深度分析](#5. 工作原理深度分析 "#5-%E5%B7%A5%E4%BD%9C%E5%8E%9F%E7%90%86%E6%B7%B1%E5%BA%A6%E5%88%86%E6%9E%90")
  • [6. 综合总结与选型建议](#6. 综合总结与选型建议 "#6-%E7%BB%BC%E5%90%88%E6%80%BB%E7%BB%93%E4%B8%8E%E9%80%89%E5%9E%8B%E5%BB%BA%E8%AE%AE")

0. 背景与数据

近期在负责一个用户行为分析后台 的开发,覆盖数据大盘、漏斗分析、消息效果、数据质量四个模块,典型的"重 SQL 聚合、重 CRUD、快迭代"场景。借此机会,我系统性地尝试了将 SDD(Spec-Driven Development,规范驱动开发) 引入 AI 辅助编程工作流。

工时数据

阶段 方式 实际工时 对比基准
基准 纯人工开发(不借助 AI) 5 天 ---
第一阶段 手搓 SDDCLAUDE.md + Markdown Spec) 2 天 提效 超60%
第二阶段 OpenSpec 架构重写 1 天(含学习成本) 探索工程化边界
第三阶段 Superpowers 架构重写 1 天(含学习成本) 探索执行效率上限

提效数字只是表象,更重要的发现是:SDD 提升的是代码质量的下限,而不只是速度


1. 为什么需要 SDD

随着大模型代码生成能力的提升,开发者越来越多地依赖 AI。但当项目复杂度超过某个阈值,传统的"凭感觉编程(Vibe Coding)"会暴露出明显的痛点:

sql 复制代码
问题 1:上下文易丢失
面对数十个文件的项目,AI 经常"忘记"前置条件,写着写着就跑偏。

问题 2:架构规范难以约束
AI 容易写出面条代码,忽略团队规约------随意的跨库 JOIN、
未处理全局异常、返回格式不统一......

问题 3:幻觉频发且难排查
通过来回对话让 AI 猜意图,生成代码常带有隐蔽 Bug,
人工排查成本极高。

SDD 是什么

SDD(Spec-Driven Development,规范驱动开发) 的核心哲学:

代码不再是一等公民,规范(Spec)才是------代码只是规范的衍生品。

通过将开发重心前置,用严谨的文档约束 AI 的行为边界,解决上述痛点,让开发者的角色从"代码打字员"向"系统架构设计者"转变。

开发流向从:

复制代码
需求 → 直接撸代码(AI 来写)→ 人工修 Bug

变为:

复制代码
需求 → 写规范(人工主导)→ 让 AI 按规范生成代码 → 人工 Review

主流工具一览

工具 出品方 核心特点
SpecKit GitHub Constitution → Specify → Plan → Tasks 四段式工作流,模板驱动
OpenSpec Fission-AI specs/(当前状态)+ changes/(变更提案)双目录,支持 20+ AI 工具,有 CLI 状态机
Superpowers obra 内置 TDD 质量门控 + subagent 并行执行,流程最严格

三个工具都有一定学习曲线。当时项目工期只有 5 天,在不熟悉SDD框架的前提下,第一阶段优先选择零工具依赖的手搓 SDD,完成交付后再利用额外时间探索 OpenSpec 和 Superpowers。


2. 轻量级实践:手搓 SDD

整体思路

人工把控基建 + Markdown 规范 + Claude Code 生成,分四步走:

css 复制代码
第一步:人工打底  → 搭项目骨架,生成数据层代码
第二步:立规矩   → 写 CLAUDE.md,把架构铁律硬编码为 AI 约束
第三步:写图纸   → 编写 Feature Spec,融合业务规则 + 数据逻辑
第四步:产代码   → Claude Code 读规范生成,人工 Review 验收

第一步:人工打底

AI 不了解公司内部的私有框架、Maven 仓库规范或特定 CI/CD 流程。项目冷启动必须由人工主导:

  1. 应用公司脚手架拉取项目骨架(包含内部封装的 MVC 框架、多数据源、定时任务等依赖)
  2. 人工执行代码生成器(MyBatis-Plus Generator)生成底层 Entity 和 Mapper
bash 复制代码
src/main/java/
└── generate/                ← 全部由代码生成器产出,禁止手动编辑
    ├── entity/
    │   ├── UserEntity.java             # 用户表
    │   ├── ActionEventEntity.java      # 行为事件表
    │   ├── MessageRecordEntity.java    # 消息记录表
    │   └── DailyStatsEntity.java       # 每日统计汇总表
    ├── mapper/
    └── service/

这一步确保底层数据模型与真实 DB 表结构绝对对齐,不给 AI 留底层结构上的自由发挥空间。


第二步:建立全局防腐层(CLAUDE.md

在项目根目录严格维护 CLAUDE.md(Claude Code 的全局上下文规范文件),将所有架构铁律硬编码为项目规则。这是整个方案最关键的一步。

CLAUDE.md 涵盖的核心约束(共 12 节):

约束内容
§0 SDD 开发流程(最高优先级):任何代码修改必须先改 Spec 文档,再改代码
§1 设计哲学:分层隔离、防御性编程、可追溯性、规范先行
§2 API 规范:URL 结构、统一响应格式、分页结构、DTO 命名、Swagger 注解
§3 代码组织:包结构、各层命名与职责、Controller/Service/Mapper 标准写法
§4 多数据源规范:user-dbbiz-db 的路由注解使用,禁止同一事务中混用
§5 异常处理:错误码分段规则、GlobalExceptionHandler 的三类拦截要求
§6 数据模型规范:Entity 标准字段,字段命名一致性约束
§7--12 日志、定时任务、generate 目录使用、多环境配置、技术栈、安全规范

关键约束示例------多数据源规范:

markdown 复制代码
## 四、多数据源规范

| 数据源标识 | 数据库 | 用途 |
|------------|--------|------|
| `user-db`  | MySQL  | 用户认证、账户数据 |
| `biz-db`   | 业务库 | 行为事件、业务数据 |

跨库查询禁止在同一个事务中混用两个数据源。
如果业务需要聚合两个库的数据,在 Service 层分别调用各自数据源的
Service,在内存中合并结果。

Claude Code 读取此文件后,便会在整个会话中自动遵守这些约束。实际验收中,AI 未出现任何跨库 JOIN 或在 Controller 写业务逻辑的情况。


第三步:构建高内聚的 Feature Spec

过去,产品 PRD 和后端 SQL 逻辑是分离的,这会导致 AI 理解割裂。这一步的核心是:将 PRD 的业务展示规则与底层 SQL 计算逻辑融合,转化为高内聚的 Markdown Feature Spec。

.specs/ 目录结构:

csharp 复制代码
.specs/
├── 00-global-constraints.md    # 技术规范(补充 CLAUDE.md)
├── 01-prd.md                   # 产品需求(功能边界、字段规则、筛选条件)
├── 02-data-logic.md            # 全局指标 SQL 定义(唯一真相来源)
├── feature-01-dashboard.md     # 数据大盘
├── feature-02-funnel.md        # 转化漏斗分析
├── feature-03-msg-effect.md    # 消息效果分析
├── feature-04-data-quality.md  # 数据质量页
└── feature-05-etl-job.md       # 每日统计 ETL Job

Feature Spec 的高内聚体现 (以 feature-01-dashboard.md 为例):

markdown 复制代码
# Feature Spec: 数据大盘 (Dashboard)

## 1. Context(背景与目标)
帮助运营团队追踪核心 OKR 的达成情况,并在指标下滑时快速定位根因。

## 2. Requirements(业务规则)
- 主 KPI:期间活跃用户数、期间转化任务数
- 漏斗模块:注册用户数 / 搜索用户数 / 浏览结果用户数 / 发起转化用户数 / 持续跟进用户数

## 3. Data & Logic(数据与核心逻辑)
> API 读取数据源:所有统计类 API 读取预聚合统计表 stats_daily,不直查源表。

-- 主 KPI:时间范围内的汇总值
SELECT
  SUM(active_user_count)      AS active_user_count,
  SUM(conversion_task_count)  AS conversion_task_count
FROM stats_daily
WHERE stat_date >= #{startDate} AND stat_date < #{endDate};

## 4. Constraints(技术约束)
1. API 层所有查询均走 @DS("biz-db") 的统计表,单库读取,无跨库操作
2. 漏斗数据需返回 List,若统计表中某天数据缺失,Service 层补 0 返回

关键设计:Feature Spec 包含了 PRD 描述 + SQL 逻辑 + 技术约束,让 AI 拿到的是一张完整的施工图纸,而非片段信息。


第四步:Agent 生成与人工验收

将 Feature Spec 和 CLAUDE.md 交由 Claude Code 读取,AI 自动生成分层清晰的代码:

java 复制代码
// 生成的 Controller ── 完全符合规范,无任何业务逻辑泄漏
@Api(tags = "数据大盘")
@RestController
@RequestMapping("/api/biz/dashboard")
@RequiredArgsConstructor
@Validated
public class DashboardController {

    private final DashboardService dashboardService;

    @ApiOperation("获取大盘 KPI 汇总数据")
    @GetMapping("/kpi")
    public JsonResult<DashboardKpiResp> getKpi(@Valid DateRangeReq req) {
        return new JsonResult<>(dashboardService.getKpi(req));
    }

    @ApiOperation("获取漏斗按日明细(折线图数据源)")
    @GetMapping("/funnel")
    public JsonResult<List<FunnelDailyResp>> getFunnel(@Valid DateRangeReq req) {
        return new JsonResult<>(dashboardService.getFunnel(req));
    }
}
java 复制代码
// 全局异常处理器 ── AI 一次生成,精确覆盖 CLAUDE.md 中要求的三类拦截
@Slf4j
@RestControllerAdvice
public class GlobalExceptionHandler {

    // 业务异常 → HTTP 200,code=业务错误码
    @ExceptionHandler(BusinessException.class)
    public JsonResult<?> handleBusinessException(BusinessException e) { ... }

    // 参数校验失败 → HTTP 400
    @ResponseStatus(HttpStatus.BAD_REQUEST)
    @ExceptionHandler({MethodArgumentNotValidException.class, BindException.class})
    public JsonResult<?> handleValidationException(BindException e) { ... }

    // 未预期异常 → HTTP 500,不暴露堆栈
    @ResponseStatus(HttpStatus.INTERNAL_SERVER_ERROR)
    @ExceptionHandler(Exception.class)
    public JsonResult<?> handleUnexpectedException(Exception e) { ... }
}

开发者退至"Reviewer"角色,专注进行:

  • Code Review:验证分层是否正确、SQL 是否安全(#{} 不用 ${})、多数据源路由是否准确
  • API 测试:对照 Feature Spec 验收接口行为
  • Bug 修复原则:遇到缺陷不直接改代码,而是先修改 Spec 后让 AI 重新生成,保持文档与代码强同步

小结:轻量级 SDD 的效果

维度 传统 Vibe Coding 轻量级 SDD
AI 输出质量 层次混乱,需大量人工修正 符合规范,直接可用
上下文管理 依赖长对话,易丢失 依赖文件(CLAUDE.md + Spec),随时加载
Bug 修复 直接改代码,文档与代码脱节 改 Spec → 重新生成,文档代码同步
可维护性 后人看不懂 AI 的意图 Spec 即文档,意图清晰
学习曲线 无额外成本 需要学习写 Spec 的方法

工时对比 :纯人工约需 5 天;轻量级 SDD 实际耗时 2.5 天 ,提效约 50%

核心收益不只是速度,而是质量的下限得到了保障。 AI 在 CLAUDE.md + Spec 的约束下,没有写出任何跨库 JOIN,没有在 Controller 里写业务逻辑,全局异常处理器一次生成即符合要求。


3. 工程化实践:OpenSpec

在完成业务交付后,我利用额外时间用 OpenSpec 对同一套需求做了架构重写。相比手搓 SDD,OpenSpec 的核心差异在于:它是一个有工程化约束的工作流框架,而不只是"让你写 Markdown 规范"的方法论。

接入

OpenSpec 的文件接入非常轻量,在项目目录下初始化 openspec/ 并配置极简的 config.yaml

yaml 复制代码
schema: spec-driven

# 可选:注入项目上下文(CLI 会把这段内容透传给每个工件生成指令)
context: |
  Tech stack: Spring Boot 2.x, MyBatis Plus 3.5
  多数据源:user-db (MySQL) / biz-db (业务数据库)
  禁止跨库事务,Service 层内存合并

# 可选:per-artifact 规则
rules:
  tasks:
    - 每个任务不超过 30 分钟工作量

重要提示:OpenSpec 不只是 Markdown 文件 + Skill 提示词,它实际上是一个三层系统(详见第 5 节原理分析),CLI 是驱动整个工作流的状态机。

OpenSpec 约定了两个核心目录,体现了它最核心的设计思想:

bash 复制代码
openspec/
├── config.yaml          # CLI 读取:schema + 项目上下文 + per-artifact 规则
├── specs/               # 系统"现在是什么"------已实现的能力(稳定)
└── changes/             # 系统"正在变成什么"------飞行中的变更
    └── archive/         # 已完成的变更(归档,保留完整决策链路)

specs/ 代表"系统现在是什么",changes/ 代表"系统正在变成什么",两者分离使每个变更都有清晰的生命周期。


四层工件:一次变更的完整生命周期

通过 /opsx:propose 指令,OpenSpec 为每个变更自动生成四层级联工件:

vbnet 复制代码
proposal.md  ──→  Why & What:为什么做这个变更,改了哪些能力
design.md    ──→  How:技术决策、风险取舍、待解问题
specs/*.md   ──→  行为契约:用 WHEN/THEN 格式描述可验收的系统行为
tasks.md     ──→  施工清单:代码级的原子任务,AI 按 task 逐项实现

proposal.md(提案)------回答"为什么做":

markdown 复制代码
## Why
当前后台无法追踪核心 OKR 的达成情况,也无法在未达标时快速定位根因。
需要一套完整的运营数据后台,覆盖数据大盘、转化漏斗、消息效果、数据质量。

## What Changes
- 新增数据大盘 API:支持时间筛选,返回主 KPI 及五步漏斗每日数据
- 新增消息效果 API:周维度比率仪表盘、每日明细、发送漏斗
- 新增数据质量 API:按时间范围统计联系人/公司回复率
- 新增内容列表 API:多条件筛选,分页展示(P1)

## Impact
- 新增 API:约 6 个业务接口
- 数据来源:user-db(用户注册数据)+ biz-db(行为事件),跨库 Service 层内存合并
- 无破坏性变更:全部为新增端点

design.md(技术设计)------回答"怎么做",强制显式化关键决策:

markdown 复制代码
## Decisions

**决策 1:漏斗数据按天返回列表**
返回 List<DailyDataPoint>,前端负责渲染折线图。后端不做图表逻辑。

**决策 2:消息效果过滤在 SQL 层**
按 reply_type 字段分类,WHERE reply_type IN (...),不在内存过滤。

**决策 3:滞后型指标的处理**
邮件/消息送达、打开、回复数据通常在发送后数小时到数天才最终确定。
Job 每天统计"前一天"截至运行时的累计值(非最终值),接受该近似,
通过允许补跑 Job 来更新历史行。

## Risks / Trade-offs
- [风险] 业务数据库按天聚合查询性能 → 确认时间字段索引;必要时加 Redis 缓存
- [取舍] 漏斗"注册用户"不关联搜索行为,统计维度是"当天注册",简化实现

## Open Questions
1. 消息打开率:业务库是否有 open tracking 记录?对应哪张表?
2. "持续跟进用户":判断条件是什么?对应哪张表的哪个字段?

specs/dashboard-overview/spec.md(需求规格)------回答"做到什么程度":

markdown 复制代码
### Requirement: 五步漏斗每日数据查询
系统 SHALL 返回选定时间范围内每日的五步漏斗用户数,用于绘制趋势图。

#### Scenario: 漏斗指标某天无数据
- WHEN 某一天某个漏斗步骤无任何用户
- THEN 该日期该指标返回 0,不跳过该日期记录

#### Scenario: 跨数据源数据合并
- WHEN Service 层需要合并 user-db 的注册数与 biz-db 的其他漏斗指标
- THEN 分别查询两个数据源,以日期为 key 在内存中 merge,禁止跨库事务

这种格式直接逼迫开发者在写代码前想清楚边界场景------"数据缺失时是补 0 还是跳过?"这个问题若不在 Spec 阶段确认,后期 AI 生成的代码行为可能是任意的。

tasks.md(原子任务清单) ------由 /opsx:apply 将 spec 拆解为代码级任务:

markdown 复制代码
## 3. 数据大盘(Dashboard)

- [x] 3.1 创建 DashboardService,实现按时间范围查询主 KPI(biz-db)
- [x] 3.2 实现五步漏斗每日数据查询(注册数来自 user-db,其余来自 biz-db,Service 层按日期 merge)
- [x] 3.3 实现漏斗 metrics 参数过滤逻辑(不传则全返回)
- [x] 3.4 在 DashboardController 中新增 GET /kpi 和 GET /funnel 端点

整个变更完成后,通过 /opsx:archive 归档,Spec 文件同步到顶层 specs/ 目录,代表"系统已实现了这些能力"。


第二个变更:ETL 聚合 Job

实际开发中,第一个变更(API 层)完成后发现一个架构问题:所有统计接口都在实时跨库查询原始表,聚合复杂、性能不可控。因此创建了第二个变更:每日聚合 Job,通过预写入统计表让 API 层退化为简单的单表查询。

这个变更的 proposal.md 精确描述了影响边界:

markdown 复制代码
## Impact
- 新增文件:DailyStatsAggregationJob.java、DailyStatsService.java
- 不修改:现有消息通知 Job(职责独立)
- 间接影响:API 层读数据策略调整(design.md 层面,spec 行为不变)
- 无破坏性变更:现有功能保留不动

关键观察 :这里展示了 OpenSpec 的一个核心优势------"API 实现策略调整"属于 design.md 层面的变化 (How 变了),但 spec 定义的接口行为不变(What 不变)。这种区分在手搓 SDD 中很难做到,往往导致不必要的 spec 改动或者规范与代码的静默漂移。


踩坑:AI 不遵循工作流的问题

OpenSpec 最核心的一个痛点是:Skill 是提示词,不是代码锁,Claude 有时会"绕过"它------没完成 proposal 就直接写 design,或者没跑完 tasks 就跳到归档。

以下几种手段可以加强约束:

CLAUDE.md 硬约束(最有效)

markdown 复制代码
## 工作流约束(最高优先级)
- 禁止在没有对应 tasks.md checkbox 的情况下编写实现代码
- 任何功能实现前,必须确认 openspec/changes/<name>/tasks.md 存在且相关任务为 - [ ]
- 完成任务后必须立即将 tasks.md 中对应项从 - [ ] 改为 - [x]

② tasks 粒度做细

模糊任务("实现 service 层")容易被 Claude 一口气做完;细粒度任务("创建 DailyStatsService.java,只包含方法签名,不实现方法体")会强制分步确认。

③ config.yaml 注入 per-artifact 约束

yaml 复制代码
rules:
  tasks:
    - 每个任务不超过 30 分钟工作量
    - 验证类任务(4.x)必须列明验证标准

这比 CLAUDE.md 里的全局约束更精准,因为它是 per-artifact 的,CLI 在生成每个工件时都会注入。

④ 根本解法:人工把控节奏

在 propose 完成后、apply 开始前,应当明确说"我确认了,开始实现"。把节奏的控制权保留在人手里,而不是说"帮我做完整个流程"------这既是 OpenSpec 的设计意图,也是 SDD 的核心姿态。


OpenSpec vs 手搓 SDD

维度 手搓 SDD OpenSpec
规范入口 一个 CLAUDE.md 承载所有约束 config.yaml + 四层工件分层约束
变更管理 无生命周期,直接改 Spec changes/ → archive/ 流转,完整决策记录
需求与决策分离 混合在同一 Markdown proposal / design / spec / tasks 四层独立
工作流标准化 完全自由,依赖经验 /opsx:propose/opsx:apply/opsx:archive
能力追踪 需人工维护文档与代码同步 specs/ 代表系统当前状态,归档即同步

OpenSpec 最显著的收益是强制显式化决策。手搓 SDD 时,"为什么用内存合并而不是跨库 JOIN"这类决策往往隐性存在,散落在聊天记录里。OpenSpec 的 design.md 将它们变成有迹可查的工程文档。


4. 高阶实践:Superpowers

在 OpenSpec 探索之后,我用 Superpowers (由 obra 开发的 Claude Code 插件)进行了第三次架构实践。相比 OpenSpec 的多工件分布式模型,Superpowers 的核心设计理念更为直接:将完整的技术决策和实现蓝图预先生成,让 AI 在执行阶段最小化决策负担,通过内置的 TDD 循环保证代码质量。

两阶段工作流

Superpowers 的整个工作流分为两个阶段,文件落地在 docs/superpowers/

bash 复制代码
docs/superpowers/
├── specs/                                      ← 阶段一:技术设计文档
│   └── {date}-{feature}-design.md
└── plans/                                      ← 阶段二:实现计划(含完整代码模板)
    └── {date}-{feature}.md

阶段一:生成技术设计文档

Superpowers 第一个产出的 Design Doc 相当于 OpenSpec 中 proposal + design 的融合体,但内容更聚焦于"对实现者有直接指导价值"的信息。

本次设计文档包含三个层次:

架构决策(数据访问分层):

bash 复制代码
ETL 层:DailyStatsJob,每日凌晨 2 点,聚合写入 stats_daily 表
查询层:HTTP /api/biz/**
  └── 大盘/漏斗/消息效果/数据质量 → 读统计表 stats_daily
  └── 内容列表 → 直查原始记录表

数据层定义(含 DDL):

sql 复制代码
CREATE TABLE stats_daily (
  id        BIGINT NOT NULL AUTO_INCREMENT,
  stat_date DATE   NOT NULL,
  -- 即时型指标(当天汇总,Job 写入后即最终值)
  active_user_count        BIGINT NOT NULL DEFAULT 0,
  conversion_task_count    BIGINT NOT NULL DEFAULT 0,
  register_user_count      BIGINT NOT NULL DEFAULT 0,
  ...
  -- 滞后型指标(送达、打开、回复等,每日 Job 回刷近 60 天)
  delivered_count          BIGINT NOT NULL DEFAULT 0,
  reply_count              BIGINT NOT NULL DEFAULT 0,
  ...
  UNIQUE KEY uk_stat_date (stat_date)
) COMMENT = '每日统计汇总表(ETL 预聚合,供 API 层查询)';

Mapper 分工与数据源路由:

Mapper 数据源 职责
EtlBizMapper biz-db ETL 原始聚合 SQL
EtlUserMapper user-db ETL 用户注册数统计
StatsQueryMapper biz-db 读统计表,供 API 层使用
ContentListMapper biz-db 内容列表动态分页查询

完整 API 契约(所有接口的路径、DTO 字段、业务规则、边界处理)。

这份设计文档经人工审核和局部调整后,作为阶段二计划生成的唯一输入


阶段二:生成实现计划(含完整代码模板)

这是 Superpowers 与 OpenSpec 最核心的分叉点:生成的计划文件不只是任务清单,而是包含完整代码模板的施工蓝图。

计划文件头部声明了执行方式:

kotlin 复制代码
> For agentic workers: REQUIRED SUB-SKILL: Use superpowers:subagent-driven-development
> (recommended) or superpowers:executing-plans to implement this plan task-by-task.
> Steps use checkbox (- [ ]) syntax for tracking.

每个 Task 内嵌 TDD 红绿循环

ini 复制代码
- [ ] Step 1:创建 failing test(完整测试代码,此时实现类不存在)
- [ ] Step 2:运行测试 → 确认 RED(mvn test -Dtest=XxxTest)
- [ ] Step 3:创建实现代码(完整 Java 文件,含注解、方法签名、逻辑)
- [ ] Step 4+:创建配套文件(XML Mapper、配置项等)
- [ ] Step N-1:运行测试 → 确认 GREEN
- [ ] Step N:Commit(指定 commit message 格式)

计划文件直接给出完整的测试代码、实现代码和 shell 命令------AI 在执行阶段不需要"想"任何东西,只需按模板施工并验证测试是否通过。


阶段三:Subagent 驱动并行执行

通过 superpowers:subagent-driven-development Skill 触发执行。该 Skill 将计划中相互独立的 Task 分发给并行 subagent,各 subagent 在独立上下文中执行,完成后更新 checkbox。

本次 Task 依赖关系与并行策略:

arduino 复制代码
Task 1(基础设施:拦截器、扫包配置)
    └─→ Task 2(ETL Mapper 层)
            └─→ Task 3(ETL Service)
                    └─→ Task 4(ETL Job)
                            └─→ Task 5(大盘 API)  ┐
                                Task 6(消息效果 API)│ 相互独立,并行执行
                                Task 7(数据质量 API)│
                                Task 8(用户管理 API)│
                                Task 9(内容列表 API)┘

实际产出的 git 提交序列(每个 commit 对应计划中一个 Task):

sql 复制代码
feat: add BizAuthInterceptor and extend MapperScan
feat: add ETL mapper layer (EtlBizMapper, EtlUserMapper)
feat: add DailyStatsService + DailyStatsJob
feat: add StatsQueryMapper with all stats queries
feat: add Dashboard API (GET /api/biz/dashboard/kpi and /funnel)
feat: add Msg Effect API (weekly dashboard + daily list)
feat: add Data Quality API (GET /api/biz/dataQuality/replyRate)
feat: add User Management API (list + mark test user)
feat: add Content List API (paginated list + detail)

每个 commit 均通过了对应的单元测试,全程没有出现"AI 生成代码与规范脱节"的情况。


踩坑:设计文档是执行质量的瓶颈

Superpowers 在执行阶段几乎不需要人工介入,但这以"设计文档足够准确"为前提。本次的主要返工点:

① 字段语义歧义 :设计文档对某个状态字段的描述存在歧义,导致 ETL SQL 生成后需要人工修正。教训:设计文档生成后,逐字段对照真实 DDL 是必要步骤,不能依赖 AI 从字段名推断语义。

② 跨库约束描述不够具体 :设计文档写了"Service 层内存合并",但计划生成时 AI 对路由注解的正确放置位置(Mapper 层 vs Service 层)存在误解。教训:跨库路由规则应在 CLAUDE.md 中以约束形式显式写出,不能只出现在设计文档的架构描述里。

根本原因 :Superpowers 的设计文档没有 OpenSpec design.md 那样强制要求"写出每个决策的 rationale",导致一些隐含假设在转化为计划文件时被错误展开。


5. 工作原理深度分析

OpenSpec 的三层架构

容易产生的误解是"OpenSpec = Markdown 文件 + Skill 提示词"。实际上,它是一个三层系统,CLI 是三层的枢纽,不是可选项

yaml 复制代码
┌─────────────────────────────────────────────────────────┐
│  层 1: Skill / Command(.md 提示词文件)                  │  ← 告诉 Claude 每个阶段该做什么
├─────────────────────────────────────────────────────────┤
│  层 2: openspec CLI(npm 包 @fission-ai/openspec)        │  ← 状态机:依赖关系、进度追踪、模板注入
├─────────────────────────────────────────────────────────┤
│  层 3: 文件系统(openspec/ 目录)                         │  ← 真相来源:工件、任务、规格、归档
└─────────────────────────────────────────────────────────┘

三层之间的数据流:

csharp 复制代码
用户说 /opsx:propose
      │
      ▼
[Skill] 告诉 Claude 调哪些 CLI 命令、以什么顺序执行
      │
      ▼
[CLI] openspec new change    → 写 .openspec.yaml 到文件系统
[CLI] openspec status --json → 读文件系统,返回工件依赖图
[CLI] openspec instructions  → 读 config.yaml,返回工件模板 + 约束
      │
      ▼
[Claude] 按模板写 proposal.md / design.md / tasks.md
      │
      ▼
[文件系统] 工件落地,成为下一次 CLI 查询的依据

如果只有 Markdown 文件,Claude 无法知道"proposal 必须先于 design"这种依赖约束,也无法精确感知哪些任务已完成、哪些还未开始------这正是 CLI 存在的意义。

层 1(Skill):行为规范

各 Skill 各有明确职责:

  • explore:只允许调研,不允许写代码
  • propose:驱动 CLI 生成完整工件集
  • apply:按原子任务逐步实现,每完成一项必须更新 checkbox
  • archive:完整性检查后执行文件系统的 mv 操作
层 2(CLI):状态机

几个关键命令的实际返回:

bash 复制代码
# 返回:工件依赖图 + applyRequires("这些工件都准备好了才能开始实现")
openspec status --change "<name>" --json

# 返回:模板 + 项目上下文(给 Claude 读,不写入文件)
#       + per-artifact 规则 + 解锁条件(写完这个会解锁哪些后续工件)
openspec instructions proposal --json

# 返回:contextFiles + 进度(total/complete/remaining)
#       + 尚未完成的任务列表(通过解析 checkbox 计算)
openspec instructions apply --json

openspec instructions apply 的进度计算是关键:CLI 解析 tasks.md 里的 - [x] / - [ ] 返回精确的"剩余任务列表",Claude 不会重复实现已完成的任务。

层 3(文件系统):真相来源
文件 谁写 谁读 用途
config.yaml 用户手动配置 CLI schema + 项目上下文,per-artifact 约束的来源
.openspec.yaml CLI 自动创建 CLI 变更元数据,CLI 靠它识别"变更"目录
proposal.md Claude Claude + CLI Why & What,后续工件的基础
design.md Claude Claude(apply 时读) How,架构决策
specs/**/*.md Claude Claude(apply 时读) 能力规格,行为边界
tasks.md Claude Claude + CLI checkbox 是进度计数器,CLI 解析计算剩余任务

一句话总结三层分工:文件系统 = 记忆(存什么);CLI = 规则(怎么组织、依赖关系、进度追踪);Skill = 行为(Claude 在每个阶段的姿态和操作序列)。


OpenSpec 的四层工件分工

每层工件防止不同类型的错误:

arduino 复制代码
proposal.md → 防止"做错方向"  ── 先想清楚为什么做
design.md   → 防止"做错架构"  ── 先显式记录关键决策
spec.md     → 防止"做错行为"  ── 先定义边界场景再让 AI 生成
tasks.md    → 防止"AI 发散"   ── 原子任务压缩 AI 自由发挥空间

OpenSpec 与 Superpowers 解决不同层次的问题

OpenSpec 解决的是**"做什么、为什么做"的决策治理问题**:

  • 强制把所有关键决策显式化、可追溯
  • 每个设计选择都有记录在案的 rationale
  • 适合多人协作或需要长期维护的复杂系统

Superpowers 解决的是**"怎么做得又快又对"的执行效率问题**:

  • 把设计文档转化为可执行的施工蓝图
  • 最大化 AI 执行阶段的确定性
  • TDD 保证质量,subagent 并行提升速度
  • 适合需求清晰、需要快速交付的场景

两者并非对立------实践建议见下一节。


TDD 是 Superpowers 的核心质量门控

这是 Superpowers 与手搓 SDD 和 OpenSpec 最本质的差异:质量验证不依赖人工对照规范,而是通过可运行的测试代码来保证。

OpenSpec 的 spec.md 用 WHEN/THEN 格式描述行为边界------这是人工可读的验收标准,需要人来判断实现是否符合:

markdown 复制代码
#### Scenario: 跨数据源查询独立执行
- WHEN Service 采集 user-db 侧的注册数
- THEN 通过 user-db 数据源单独查询,结果以 Java 变量传递,不与 biz-db 查询混用连接

Superpowers 的 plan.md 把同样的要求写成可执行的测试:

java 复制代码
@Test
public void testValidToken_allowsRequest() throws Exception {
    MockHttpServletRequest request = new MockHttpServletRequest();
    request.addHeader("Authorization", "Bearer test-secret");
    boolean result = interceptor.preHandle(request, response, null);
    assertTrue(result);
    assertEquals(200, response.getStatus());
}

验收标准变成了 mvn test 的输出------GREEN = 通过,RED = 未通过,无歧义。

此外,测试先于代码存在,AI 在生成实现代码时已经"知道"期望是什么,而不是生成完之后再对照文档检查,从源头上减少了隐蔽 Bug。


三种执行模型对比

维度 手搓 SDD OpenSpec Superpowers
执行单元 人工逐步交互 人工触发 /opsx:apply superpowers:subagent-driven-development
并行能力 Task 级并行(独立 subagent)
上下文管理 单 session,随时间衰减 CLI 精确注入"剩余任务列表" 多 subagent 各自独立上下文
质量验证 人工 Code Review 人工对照 WHEN/THEN spec 自动化测试(mvn test)
代码模板 完整代码模板内嵌在 plan

6. 综合总结与选型建议

三种方式的全面对比

维度 手搓 SDD OpenSpec Superpowers
上手成本 极低,零工具依赖 中等,需学 CLI + 工件结构 中等,需熟悉 Skill 体系
规范编写投入 低(CLAUDE.md + 若干 Feature Spec) 中(4 层工件 × 变更数) 高(1 精准设计文档 + 1 大型计划文件)
决策可追溯性 差(散落在聊天记录) 优(每变更有独立 design.md + rationale) 中(有架构决策,无显式 rationale)
执行速度 中(人工交互驱动) 中(人工分步确认) 快(subagent 并行 + 完整代码模板)
质量验证 主观 Code Review 对照 WHEN/THEN spec 自动化测试(mvn test)
AI 幻觉风险 中(靠 CLAUDE.md 全局约束) 低(CLI 状态机 + spec 场景双约束) 低(TDD + 完整代码模板双约束)
适用场景 快速验证 / 熟悉域开发 多人协作 / 长期维护系统 需求清晰 / 快速交付

选型建议

objectivec 复制代码
项目/团队情况                          推荐路径
──────────────────────────────────────────────────────
首次尝试 SDD,想快速感受价值            → 手搓 SDD(CLAUDE.md + Feature Spec)
需求不确定,多人协作,重长期维护        → OpenSpec
需求清晰,设计经验丰富,追求执行效率    → Superpowers
希望兼顾决策治理与执行效率              → OpenSpec 梳理设计决策 + Superpowers 执行

四条核心结论

1. 规范文件的本质是降低 AI 决策负担

三种方式的根本区别在于"规范把多少决策权从 AI 手里收回来":

  • 手搓 SDD 把全局约束收回来(分层规范、禁止跨库 JOIN)
  • OpenSpec 把变更决策收回来(每个 design.md 显式记录 How & Why)
  • Superpowers 把实现细节也收回来(计划文件直接给出代码模板)

越往下走,AI 执行阶段的自由度越小、确定性越高,但规范编写阶段需要投入的精力越大。没有"最好的方式",只有与项目复杂度、团队规模、交付压力相匹配的方式。

2. Superpowers 顺畅的代价:设计阶段要求极高的精准性

Superpowers 在执行阶段几乎不需要人工介入,但前提是"设计文档足够准确"。实践中,设计文档里的一个字段语义歧义就导致了 ETL SQL 的返工;一处跨库约束描述不够具体,就导致路由注解被生成到了错误的层。

相比之下,OpenSpec 的 design.md 强制要求写明每个决策的 rationale,对"暴露设计文档中的隐含假设"有显著效果。

实践建议:对于不熟悉的业务域或涉及复杂跨系统交互的场景,建议先用 OpenSpec 完成设计决策梳理,再把 design.md 的内容作为 Superpowers 设计文档的输入------两者结合比单独使用任何一个都更稳健。

3. SDD 的核心价值不只是提速,而是提升代码质量的下限

回顾这三次实践,提效数字是直观的(5 天 → 2.5 天),但更重要的是:AI 在规范约束下没有写出任何违反架构规则的代码

✓ 没有跨库 JOIN ✓ 没有在 Controller 里写业务逻辑 ✓ 没有 SQL 注入漏洞 ✓ 全局异常处理器一次生成即符合要求 ✓ 所有单元测试首次运行均通过

这些问题不是"AI 不会",而是"AI 不会主动想到"------它需要规范来约束,需要测试来验证。这正是 SDD 最值得推广的价值所在。

4. 开发者角色的根本性转变

三次实践的共同点:开发者的核心工作从"写代码"转移到了"定义规范"。无论是手搓 CLAUDE.md、写 OpenSpec 的 design.md,还是确认 Superpowers 的设计文档,最花时间、最需要人工判断的部分都是"把隐性的架构意图显式化"。

这个转变是 SDD 最值得推广的核心价值------不是某个具体工具,而是"规范先行、代码随之"的开发姿态。


以上实践基于 Spring Boot + MyBatis Plus 的 Java 后端项目,工具链为 Claude Code + OpenSpec + Superpowers。核心思路与语言和框架无关,适用于任何需要 AI 辅助编程的中等规模项目。

相关推荐
wggmrlee2 小时前
AI技术架构全局视角
人工智能·架构
树上有只程序猿2 小时前
低代码平台选型指南,10 款热门工具对比
前端·后端
大迪deblog2 小时前
系统架构设计-系统架构评估
架构·系统架构·软件构建
左左右右左右摇晃2 小时前
Java笔记——JMM
java·后端·spring
Java编程爱好者2 小时前
面试官:“你一天烧几十个token也好意思面AI应用开发?”我镇定自若:“我烧的不是token,是我的热情。”面试官:“明天二面。”
后端
Memory_荒年2 小时前
Nacos双面超人:注册中心 + 配置中心,一个都不能少!
java·后端·架构
Memory_荒年2 小时前
Nacos 面试通关宝典:从入门到源码,你值得拥有!
后端
shepherd1112 小时前
别再无脑 cat 了!后端排查 GB 级生产日志的实战命令
linux·后端