Spec-Driven Development(规范驱动开发)

文章目录

  • 前言
  • [SDD 和普通 AI 编程有什么区别?](#SDD 和普通 AI 编程有什么区别?)
  • [你的项目非常适合实践 SDD](#你的项目非常适合实践 SDD)
  • 推荐的项目目录
  • [第一步:建立项目 Constitution](#第一步:建立项目 Constitution)
  • [第二步:每个功能写 spec.md](#第二步:每个功能写 spec.md)
  • [第三步:让 AI 生成 plan.md](#第三步:让 AI 生成 plan.md)
  • [第四步:拆成 tasks.md](#第四步:拆成 tasks.md)
  • [第五步:采用 Spec → Test → Code](#第五步:采用 Spec → Test → Code)
  • [适合使用 SDD 的场景](#适合使用 SDD 的场景)
  • [SDD 最容易踩的坑](#SDD 最容易踩的坑)
    • [1. Spec 写得很多,但无法验证](#1. Spec 写得很多,但无法验证)
    • [2. 把实现细节当需求](#2. 把实现细节当需求)
    • [3. Spec 完成后不再更新](#3. Spec 完成后不再更新)
    • [4. 一次让 AI 改太多](#4. 一次让 AI 改太多)
    • [5. 把 AI 当最终决策者](#5. 把 AI 当最终决策者)
  • 推荐你现在这样实践
  • 工具选择建议

前言

Spec-Driven Development,规范驱动开发。

它不是传统的 "先写一大堆需求文档",而是:

先把需求、边界、验收标准、技术方案和任务拆解写清楚,再让 Cursor、Claude Code、Codex、GitHub Copilot、Kiro 等 AI Agent 按规范实现。

现在还流行吗?

流行,而且在 2025---2026 年明显升温。

GitHub 已推出开源的 Spec Kit,用于把功能开发拆成 specification、plan、tasks 和 implementation;AWS 的 Kiro 也把 Spec-Driven Development 作为核心工作流。微软在 2026 年进一步把 SDD 描述为 AI-native engineering 中连接需求、设计、实现和验证的共享事实来源。

它流行的根本原因是:AI 写代码越来越快,但模糊提示词很容易产生:

  • 功能理解偏差
  • 重复实现
  • 架构失控
  • 前后端接口不一致
  • 安全规则遗漏
  • 修改一个功能破坏其他功能

SDD 的作用,就是给 AI 加上一条"工程轨道"。

不过 SDD 目前还没有唯一的行业标准。Martin Fowler 的文章把当前实践分为三个层次:

  1. Spec-first:开发前写规范。
  2. Spec-anchored:实现后继续维护规范。
  3. Spec-as-source:人主要维护规范,由 AI 持续生成或修改代码。

现在大多数真实项目适合前两种,第三种还比较激进。


SDD 和普通 AI 编程有什么区别?

普通 AI 编程可能是这样:

text 复制代码
帮我实现一个商品秒杀功能。

AI 不知道:

  • 是否允许重复购买
  • 库存扣减顺序
  • Redis 和数据库如何一致
  • 是否需要消息队列
  • 接口幂等规则
  • 超卖如何处理
  • 失败后如何补偿

SDD 会先形成规范:

text 复制代码
功能:秒杀下单

业务规则:
1. 一个用户每场活动只能购买一次。
2. 库存以 Redis 为第一道拦截。
3. Redis Lua 脚本必须原子检查库存和用户资格。
4. 请求成功后写入 Kafka。
5. 消费者异步创建数据库订单。
6. 数据库通过唯一索引防止重复下单。
7. 消息处理必须支持幂等。
8. Redis 成功但 Kafka 发送失败时,需要执行补偿。

验收标准:
- 1000 个并发请求下不能超卖。
- 同一用户重复请求只创建一个订单。
- Kafka 消息重复消费不会产生重复订单。
- Redis 不可用时返回明确错误,不直接打数据库。

这时 AI 才开始设计和写代码。

Prompt 是一次性指令,Spec 是项目资产。


你的项目非常适合实践 SDD

你现在准备做的项目包括:

text 复制代码
apps/
  api             NestJS API
  shop-web        Next.js 商城
  admin-web       Next.js 管理后台

packages/
  ui
  types
  api-client
  eslint-config
  tsconfig

还有:

  • PostgreSQL
  • Prisma
  • Redis
  • Kafka
  • JWT / refresh token
  • 秒杀系统
  • 管理后台
  • 商城前端

这类项目跨前端、后端、数据库、缓存和消息队列,AI 很容易只完成局部功能,却破坏整体一致性。

因此非常适合:

Monorepo + SDD + AI Agent


推荐的项目目录

不需要一开始就引入很重的 SDD 工具。可以先在仓库中建立这些目录:

js 复制代码
repo/
├── apps/
│   ├── api/
│   ├── shop-web/
│   └── admin-web/
│
├── packages/
│   ├── ui/
│   ├── api-client/
│   ├── contracts/
│   └── config/
│
├── specs/
│   ├── constitution.md
│   ├── architecture.md
│   ├── domains/
│   │   ├── auth.md
│   │   ├── product.md
│   │   ├── order.md
│   │   └── seckill.md
│   └── features/
│       ├── 001-user-login/
│       │   ├── spec.md
│       │   ├── plan.md
│       │   ├── tasks.md
│       │   └── acceptance.md
│       └── 002-product-management/
│           ├── spec.md
│           ├── plan.md
│           ├── tasks.md
│           └── acceptance.md
│
├── AGENTS.md
├── package.json
└── turbo.json

第一步:建立项目 Constitution

constitution.md 可以理解为整个项目不可违反的"宪法"。

例如:

json 复制代码
# Project Constitution

## Architecture

- 项目使用 pnpm workspace + Turborepo。
- apps/api 使用 NestJS。
- apps/shop-web 和 apps/admin-web 使用 Next.js。
- apps 之间不得直接引用彼此内部代码。
- 公共代码必须放入 packages。

## API

- API 统一使用 /api/v1 前缀。
- Controller 只负责参数解析和响应。
- 业务逻辑必须放在 Service 或 Domain 层。
- 所有输入必须通过 DTO 校验。
- 对外接口必须生成 OpenAPI 文档。

## Database

- 所有数据库访问必须通过 Prisma。
- 禁止在循环中执行无界数据库查询。
- 涉及金额时禁止使用 JavaScript 浮点数。
- 关键业务规则必须由数据库约束兜底。
- Schema 修改必须包含 migration。

## Authentication

- Access token 有效期较短。
- Refresh token 必须轮换。
- Refresh token 只通过 HttpOnly Cookie 传输。
- Cookie 必须根据环境配置 Secure 与 SameSite。
- 服务端只保存 refresh token 哈希值。

## Testing

- 核心 Service 必须有单元测试。
- 核心 API 必须有集成测试。
- 秒杀、支付、库存和认证必须包含异常路径测试。

## AI Rules

- 实现之前必须阅读对应 feature spec。
- 不允许修改 spec 范围之外的模块。
- 不允许自行增加依赖。
- 不确定时必须记录 assumption,不得暗自猜测。
- 完成后必须运行 lint、typecheck 和 tests。

这样无论用 Cursor、Codex 还是 Claude Code,先让 AI 阅读这个文件。


第二步:每个功能写 spec.md

例如商品管理:

cs 复制代码
# Product Management Specification

## Goal

管理员可以创建、修改、上下架和查询商品。

## Actors

- Admin
- Customer

## Functional Requirements

### FR-001 Create Product

管理员可以创建商品。

必填字段:

- name
- sku
- price
- stock
- categoryId

### FR-002 SKU Uniqueness

SKU 在整个系统中必须唯一。

### FR-003 Product Status

商品状态包括:

- DRAFT
- ACTIVE
- INACTIVE

只有 ACTIVE 商品可以在商城前端显示。

### FR-004 Price

商品价格必须大于或等于 0。

金额在数据库中使用 Decimal,API 中使用字符串返回。

## Non-functional Requirements

- 商品列表支持分页。
- 默认每页 20 条。
- 最大每页 100 条。
- 商品查询 P95 小于 300ms。

## Acceptance Criteria

- 未登录用户不能访问管理接口。
- 普通用户访问管理接口返回 403。
- 重复 SKU 返回 409。
- 非法价格返回 400。
- 下架商品不能出现在商城商品列表。

注意:这里主要描述 做什么,不要过早描述具体代码。


第三步:让 AI 生成 plan.md

在 Spec 确认后,再让 AI 设计技术方案。

cs 复制代码
# Implementation Plan

## Affected Applications

- apps/api
- apps/admin-web
- apps/shop-web
- packages/contracts
- packages/api-client

## Backend Changes

1. 创建 ProductModule。
2. 创建 ProductController。
3. 创建 ProductService。
4. 修改 Prisma schema。
5. 添加 SKU 唯一索引。
6. 添加管理员权限 Guard。
7. 添加商品分页查询。

## Frontend Changes

### Admin

- 商品列表页
- 新建商品表单
- 编辑商品表单
- 上下架操作

### Shop

- 商品列表页只展示 ACTIVE 商品

## API Contracts

- POST /api/v1/admin/products
- PATCH /api/v1/admin/products/:id
- GET /api/v1/admin/products
- GET /api/v1/products

## Risks

- Decimal 在前后端序列化时可能丢失精度。
- 管理接口和商城接口的数据字段不同。
- SKU 并发创建必须依赖数据库唯一索引。

你需要重点审查这一阶段。

因为未来高级工程师最重要的能力,不再只是"亲自把代码全部敲出来",而是:

判断 AI 给出的架构、边界和取舍是否合理。


第四步:拆成 tasks.md

cs 复制代码
# Tasks

## Phase 1: Contracts

- [ ] T001 定义 ProductStatus
- [ ] T002 定义 Product DTO
- [ ] T003 更新 OpenAPI 类型生成流程

## Phase 2: Database

- [ ] T004 添加 Product Prisma Model
- [ ] T005 添加 SKU 唯一索引
- [ ] T006 创建 migration

## Phase 3: Backend

- [ ] T007 创建 ProductModule
- [ ] T008 实现创建商品接口
- [ ] T009 实现商品分页接口
- [ ] T010 添加管理员权限验证
- [ ] T011 添加单元测试
- [ ] T012 添加集成测试

## Phase 4: Admin Web

- [ ] T013 创建商品列表页
- [ ] T014 创建商品表单
- [ ] T015 实现上下架操作

## Phase 5: Shop Web

- [ ] T016 创建商城商品列表
- [ ] T017 处理加载、空数据和错误状态

## Phase 6: Verification

- [ ] T018 运行 lint
- [ ] T019 运行 typecheck
- [ ] T020 运行 tests
- [ ] T021 检查 acceptance criteria

不要让 AI 一次完成全部 21 个任务。

推荐一次做一个小阶段:

cs 复制代码
阅读 constitution.md、spec.md、plan.md 和 tasks.md。

只完成 T004-T006。

不要修改其他模块。
完成后:
1. 解释修改内容;
2. 运行 Prisma validation;
3. 运行相关测试;
4. 更新 tasks.md;
5. 列出尚未解决的问题。

这样比一句"把商品模块全部做完"稳定很多。


第五步:采用 Spec → Test → Code

对核心业务,最好把 SDD 和 TDD 结合:

json 复制代码
Spec
  ↓
Acceptance Criteria
  ↓
Tests
  ↓
Implementation
  ↓
Verification

例如 refresh token 轮换:

md 复制代码
Given 用户持有有效 refresh token
When 用户请求刷新 token
Then 系统签发新的 access token
And 系统签发新的 refresh token
And 旧 refresh token 立即失效

先让 AI 写测试:

ts 复制代码
it('should rotate refresh token and invalidate the old token', async () => {
  // ...
});

测试确认正确后,再让 AI 实现。

这比 AI 先写一大块代码、最后补几个"为了通过而通过"的测试更可靠。


适合使用 SDD 的场景

非常适合:

  • 登录和权限
  • 支付
  • 订单
  • 库存
  • 秒杀
  • 多租户
  • 消息队列
  • 跨前后端功能
  • 大规模重构
  • 数据库迁移
  • 多个 AI Agent 并行开发

不必重度使用:

  • 调整按钮颜色
  • 修改一段文案
  • 简单 CSS
  • 修复明显的小 bug
  • 一次性脚本
  • 探索性原型

可以采用分级策略:

任务 推荐方式
小修改 直接 Prompt
普通功能 简化 Spec
跨模块功能 完整 SDD
支付、权限、库存 SDD + TDD
架构改造 SDD + ADR + 分阶段执行

SDD 最容易踩的坑

1. Spec 写得很多,但无法验证

错误写法:

text 复制代码
系统需要快速、安全、用户体验良好。

AI 不知道什么叫快速、安全、良好。

更好的写法:

text 复制代码
商品列表接口 P95 响应时间小于 300ms。
未授权请求返回 401。
普通用户访问管理员接口返回 403。
每个表单必须包含 loading、error 和 empty 状态。

2. 把实现细节当需求

需求阶段不要一开始就写:

text 复制代码
必须创建 ProductRepositoryImpl,并使用 Redis Hash。

除非这是已经决定的架构约束。

应该先写:

text 复制代码
商品详情允许缓存。
商品更新后,旧缓存必须失效。

具体使用 Redis String、Hash 还是其他结构,放到 plan 中决定。

3. Spec 完成后不再更新

如果代码已经变了,Spec 没变,几个月后 AI 会读到错误上下文。

所以每个 PR 都要检查:

text 复制代码
代码是否修改?
测试是否修改?
Spec 是否需要修改?
API Contract 是否需要修改?

4. 一次让 AI 改太多

即使 Spec 很清楚,也不要让 AI 一次完成整个商城。

合理粒度通常是:

  • 一个明确功能
  • 5---15 个相关文件
  • 一套可以独立运行的测试
  • 一个可以审查的提交

5. 把 AI 当最终决策者

AI 可以生成:

  • 需求草稿
  • 边界条件
  • 技术方案
  • 测试
  • 实现
  • Review 建议

但你必须决定:

  • 业务规则
  • 数据一致性策略
  • 安全边界
  • 架构取舍
  • 是否接受技术债
  • 什么才叫完成

推荐你现在这样实践

不要一上来把整个项目全部 SDD 化。

先选择一个中等复杂度功能:

商品管理模块

执行流程:

text 复制代码
1. 建立 monorepo
2. 编写 constitution.md
3. 编写 product-management/spec.md
4. 让 AI 生成 plan.md
5. 你审查 plan
6. 让 AI 生成 tasks.md
7. 每次实现 2---4 个 task
8. 每阶段运行 lint/typecheck/test
9. 完成功能后回顾并更新 spec

商品模块跑通后,再做:

text 复制代码
用户认证
    ↓
商品管理
    ↓
购物车
    ↓
普通订单
    ↓
库存系统
    ↓
秒杀
    ↓
支付模拟

不要先拿秒杀作为第一个 SDD 实验。 秒杀同时涉及 Redis、Lua、Kafka、数据库一致性和幂等,变量太多。先用商品管理熟悉流程,再把 SDD 应用到秒杀。


工具选择建议

目前可以考虑:

  • GitHub Spec Kit:开源、流程完整,适合理解标准 SDD。
  • Kiro:原生强调 requirements、design、tasks 的 Spec 工作流。
  • Cursor / Claude Code / Codex:不强制绑定某个 SDD 工具,仓库里维护 Markdown Spec 同样可以实践。

GitHub Spec Kit 的核心价值不是某个 CLI 命令,而是把开发稳定地拆成"规范、计划、任务和实现";官方也把它定位为帮助编码 Agent 从意图走向可预测结果的工具。(GitHub Pages)

对你的项目,我更建议先使用:

Markdown Spec + AGENTS.md + Cursor/Codex/Claude Code

先掌握方法,再决定是否引入 Spec Kit。不要为了使用 SDD 工具,反而增加大量流程负担。

最终可以总结成一句:

Vibe Coding 适合探索,SDD 适合交付;AI 负责快速执行,人负责定义正确的问题、约束和验收标准。

相关推荐
云栖梦泽1 天前
Camera驱动开发与应用开发中的零拷贝与DMA
linux·驱动开发·嵌入式硬件
脱胎换骨-军哥1 天前
C++ 嵌入式编程实例:从寄存器操作到底层驱动开发
开发语言·c++·驱动开发
智者知已应修善业1 天前
【使用D触发器74HC175实现0001 0011 0111 1111 1110 1100 1000的循环彩灯电路。】2025-4-28
驱动开发·经验分享·笔记·硬件架构·硬件工程
新元代码2 天前
SDD+TDD 双驱动开发模式实战指南
驱动开发
mk0153 天前
20V输入,12V 3A输出 效率96%DCDC降压芯片
驱动开发·单片机·硬件工程·智能硬件·pcb工艺
mounter6253 天前
跨越鸿沟:从内核驱动开发到超大规模云端生产环境的思考
linux·驱动开发·linux kernel·kernel
Saniffer_SH4 天前
NAND技术(二):从 Channel、Die/LUN、P/E Cycle 到 LDPC,一次讲透 NAND 里那些最容易误解的概念
人工智能·驱动开发·嵌入式硬件·测试工具·fpga开发·计算机外设·压力测试
2401_854151554 天前
嵌入式传感器驱动开发深度解析——从 I2C/SPI 驱动到数据融合算法
驱动开发·算法
Bug退散师4 天前
多路IO复用[select版TCP服务器与poll版TCP服务器]与常用网络编程函数详解
linux·服务器·c语言·网络·驱动开发·tcp/ip