# Spec Driven Development

> 在编码之前生成结构化的规格文档。当用户要求写 spec、设计功能、规划新项目，或需求模糊时使用（如"我想做一个X"、"帮我设计Y"）。触发词：写spec、写规格、需求不清晰、新功能设计、帮我设计、技术方案、spec。

- Skill: `xiaoweidotnet/spec-driven-development` (Agent Skill, multi-file: 2 files)
- Install (CLI): `npx skillmds@latest add xiaoweidotnet/spec-driven-development`
- Raw SKILL.md: https://api.skillmd.com/api/skills/xiaoweidotnet/spec-driven-development/raw
- Safety review: pending
- Works with: Claude Code, Claude.ai, OpenAI Codex
- Category: Coding & Dev Tools
- Author: xiaoweidotnet (https://skillmd.com/u/xiaoweidotnet)
- Updated: 2026-09-17
- Page: https://skillmd.com/skills/xiaoweidotnet/spec-driven-development

---


# Spec-Driven Development

## 概述

生成结构化规格文档（spec）——定义构建什么、为什么、怎样算完成。**不负责**规划任务或写代码。spec 确认后交给 `planning-and-task-breakdown`。

## 核心原则

**spec 结束时不应留下未决问题。** 每一个模糊点要么从代码库找到答案，要么逐个向用户推荐默认方案并当场决策。

## 适用场景

- 启动新项目或新功能，尚未有书面 spec
- 需求模糊、不完整，或只是大概想法
- 即将做出重要的架构决策
- 多个协作者需要对齐"完成"的定义

**不适用：** 单行修复、需求已明确的改动。已有 spec 只需拆解任务——直接用 `planning-and-task-breakdown`。

## Spec 生成流程

```
探索代码库 ──→ 逐个澄清 ──→ 撰写 ──→ 确认 & 保存
     │              │            │            │
     ▼              ▼            ▼            ▼
 能自己找到      每次只问     填充模板    人类审阅通过
 的答案不问      一个问题                 后保存到仓库
```

### 步骤 0：探索代码库（先于任何问题）



**能从代码库推断的答案，绝不要问用户。** 只在以下情况才提问：代码库没有答案、存在多种合理选择、或者选择不可逆且后果重大。

### 步骤 1：逐个澄清（一次只一个）

列出你认为确定的事实（从代码库推断出的结论），然后**一次只问一个问题**。
使用 ‘AskQuestion’ 工具进行提问
每个问题必须附带一个**推荐方案**——告诉用户你建议怎么做、为什么，让用户只需说是或否。

```
从代码库确认的事实：
- 技术栈：Spring Boot 2.x + MyBatis-Plus + MySQL（来自 pom.xml）
- 认证方案：Spring Security + JWT，session 无状态（来自 SecurityConfig.java）
- 前端：Vue 3 + Element Plus + TypeScript（来自 package.json）

需要确认的第 1 个问题：
推荐方案——数据模型用两张表：dict_type（类型）和 dict_item（字典项），
类型含 name/code/sort，项含 label/value/type_id/sort。
理由：与项目现有 Complaint 模块的两级结构一致，且支持按编码获取字典的公开 API。
→ 这样可以吗？
```

**逐个推进。** 等用户回答前一个问题，再问下一个。不要批量抛出。

当用户给出了你的推荐方案之外的回答，**接受它**——用户是领域专家。但当用户的回答与你从代码库观察到的事实矛盾时，指出来："但代码中 User 表已有 phone 字段，不需要新增——用现有字段就行，对吗？"

### 步骤 2：撰写

每解决一个问题，就立即填入 spec 对应位置。不要等所有问题问完才动笔——**边问边写**。

Spec 覆盖六个核心领域：

1. **目标** —— 构建什么、为什么、用户是谁、成功标准
2. **命令** —— 完整可执行命令（`npm run build`、`npm test -- --coverage`）
3. **项目结构** —— 源码、测试、文档的目录布局
4. **代码风格** —— 一个真实代码片段胜过三段文字。含命名规范和格式化规则，但要尽量简洁
5. **测试策略** —— 框架、测试位置、覆盖率要求、各测试级别职责
6. **边界** —— 三级约束：必须做 / 先问再做 / 绝不

**Spec 模板：**

```markdown
# Spec: [项目/功能名称]

## 目标
[构建什么、为什么。用户故事或验收标准。]

## 技术栈
[框架、语言、关键依赖及版本]

## 命令
[构建、测试、lint、开发——完整命令]

## 项目结构
[目录布局及说明]

## 代码风格
[示例代码 + 关键约定]

## 测试策略
[框架、测试位置、覆盖率要求、测试级别]

## 边界
- 必须做: [...]
- 先问再做: [...]
- 绝不: [...]

## 成功标准
[如何判断完成——具体的、可测试的条件]

## 决策记录
[在澄清过程中做出的关键决策及理由。每条一句话。]
- 决策: 用两张表（dict_type + dict_item）而非单表——理由：支持按编码获取、避免 category 字段冗余
- 决策: 删除类型级联软删除其下字典项——理由：与项目 Complaint 模块的 complaint→complaint_reply 处理一致
```

> 注意：模板中没有"待澄清问题"章节。所有问题应在步骤 1 中逐个解决并记录到决策记录中。

**将模糊描述转化为可测试的标准：**

```
需求："让仪表盘更快"

转化：
- 仪表盘 LCP < 2.5s（4G 网络）
- 初始数据加载 < 500ms
- 加载中无布局偏移（CLS < 0.1）
→ 这些目标是否正确？
```

### 步骤 3：确认 & 保存

将 spec 提交给人类审阅。确认：

- [ ] 六个核心领域全部覆盖
- [ ] 成功标准具体且可测试
- [ ] 所有模糊点已转化为决策记录
- [ ] 人类已审阅并批准

保存到 `docs/features/[功能名称]/spec.md`。根据目标推导功能名称（如 "用户认证"、"支付集成"）。保存前与用户确认路径。

**保存后，明确告知用户：** spec 已完成，下一步用 `planning-and-task-breakdown` 将 spec 拆解为可执行任务。

## 轻量级 Spec

对于小改动，写最小 spec：

```markdown
# Spec: [功能名称]
## 目标
[一行——做什么、为什么]
## 成功标准
- [2-3 条可测试的条件]
## 边界
- [实施的约束条件]
```

6 行 spec 远胜于没有 spec。

## 后续步骤

| 技能 | 做什么 |
|------|--------|
| `planning-and-task-breakdown` | 将 spec 拆解为有依赖关系的可执行任务 |
| `incremental-implementation` | 逐任务实现 |
| `test-driven-development` | 用红-绿-重构验证每个任务 |

## 保持 Spec 存活

- **决策变更时更新** —— 数据模型要改？先更新 spec，再实施
- **范围变更时更新** —— 新增或砍掉的功能应反映在 spec 中
- **将 spec 纳入版本控制** —— spec 和代码一样属于仓库
- **在 PR 中引用 spec** —— 关联每次 PR 对应的 spec 章节

## 常见借口

| 借口 | 真相 |
|------|------|
| "这个很简单，不需要 spec" | 简单任务仍需验收标准。两行 spec 就可以。 |
| "我先写代码，写完再补 spec" | 那是文档不是规格。spec 的价值在编码*之前*迫使你想清楚。 |
| "写 spec 太慢了" | 15 分钟写 spec 避免 15 小时返工。 |
| "需求反正会变" | 过时的 spec 仍比没有 spec 强。需求变了就更新它。 |
| "用户很清楚自己要什么" | 再清晰的需求也有隐含假设。spec 暴露这些假设。 |

## 红旗信号

| 症状 | 应对 |
|------|------|
| 没有书面需求就开始写代码 | 停。问："什么叫'做完'？怎么验证？" |
| "直接开始做吧"而不先澄清 | 引导："先花 5 分钟定一下成功标准。" |
| 做出架构决策却不记录 | 暂停，两句话写下决策和理由。 |
| 因为"很明显"而跳过 spec | 每个"明显"的任务至少藏着一个未说出口的假设。 |
| spec 结尾出现了"待澄清问题"列表 | 违反了核心原则——回到步骤 1，逐个解决。 |

### 应对抗拒

**"这点改动写 spec 太麻烦了。"**
→ 用轻量级 spec：目标（1 行）+ 成功标准（2-3 条）+ 边界。

**"我知道要什么，直接做就行。"**
→ "好的，我复述一下理解——30 秒。"写出 2-3 条成功标准。有不对的恰好证明 spec 的价值。

**"我们边走边看吧。"**
→ 只为第一个切片写 spec，做完再为下一个切片写。保持节奏，避免跑偏。

