文章目录
- 前言
- [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 的文章把当前实践分为三个层次:
- Spec-first:开发前写规范。
- Spec-anchored:实现后继续维护规范。
- 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 负责快速执行,人负责定义正确的问题、约束和验收标准。