规格驱动的工作流

spec-driven-workflow
分类编程
作者Alireza Rezvani
许可MIT
评分4.80/5
使用5.6K

规格驱动工作流 (Spec-Driven Workflow) — 强力版

概述

规格驱动工作流强制执行一条不可协商的铁律:在编写任何代码之前,必须先编写规格说明书。 不是同步编写,也不是事后补齐,而是必须在之前。

这不仅仅是文档,而是一份合约。规格说明书定义了系统必须 (MUST) 做什么、应该 (SHOULD) 做什么,以及明确不会做什么。你编写的每一行代码都必须追溯到规格中的一项需求;每一个测试用例都必须追溯到一项验收标准。如果规格中没有定义,就不要去实现。

为什么“规格先行”至关重要

1. 消除返工。 60-80% 的缺陷源于需求而非实现。在规格阶段发现歧义仅需几分钟,而在生产环境中修复则需数天。
2. 强制清晰化。 如果你无法用简单的语言描述系统应该做什么,说明你对问题的理解还不足以开始写代码。
3. 实现并行开发。 规格一旦通过审核,前端、后端、QA 和文档编写可以同步启动。
4. 建立问责机制。 规格即是“完成”的定义。关于功能是否“完工”不再有争论 —— 要么满足验收标准,要么不满足。
5. 直接驱动 TDD。 采用 Given/When/Then 格式的验收标准可以 1:1 转化为测试用例。规格本身就是测试计划。

铁律

code
没有经过审核通过的规格,就不能写代码。
没有例外。没有所谓的“快速原型”。没有“我以后再补文档”。

如果规格尚未编写、评审并获批,实现阶段不得开始。就这么简单。

---

规格格式

每份规格必须遵循以下结构。所有章节均为必填 —— 如果某章节不适用,请填写 “N/A — [原因]”,以便评审员确认该项是被考虑过而非被遗漏。

强制性章节

| # | 章节 | 核心规则 |
|---|---------|-----------|
| 1 | 标题与元数据 | 作者、日期、状态(草稿/评审中/已批准/已废弃)、评审员 |
| 2 | 上下文 (Context) | 该功能存在的原因。2-4 段文字,并附带证据(指标、工单)。 |
| 3 | 功能需求 (FR) | 使用 RFC 2119 关键词 (MUST/SHOULD/MAY)。编号为 FR-N。每项需求必须是原子的且可测试的。 |
| 4 | 非功能需求 (NFR) | 性能、安全、可访问性、可扩展性、可靠性 —— 且必须有可衡量的阈值。 |
| 5 | 验收标准 (AC) | Given/When/Then 格式。每项 AC 必须至少引用一个 FR-* 或 NFR-*。 |
| 6 | 边界情况 (EC) | 编号为 EC-N。覆盖所有外部依赖的失效模式。 |
| 7 | API 合约 | TypeScript 风格的接口。涵盖成功和错误响应。 |
| 8 | 数据模型 | 表格形式,包含字段、类型、约束。需求中的每个实体必须有对应的模型。 |
| 9 | 超出范围 (Out of Scope) | 明确列出排除项及其原因。防止实现过程中的范围蔓延。 |

RFC 2119 关键词

| 关键词 | 含义 |
|---------|---------|
| MUST | 绝对要求。缺失则视为不合规。 |
| MUST NOT | 绝对禁止。 |
| SHOULD | 推荐。除非有记录在案的理由,否则不应省略。 |
| MAY | 可选。由实现者自行决定。 |

详见 spec_format_guide.md,其中包含带有分章节示例的完整模板、需求编写的正反面案例以及不同功能类型的模板(如 CRUD、集成等)。
(例如:认证、迁移)。

请参阅 acceptance_criteria_patterns.md,获取涵盖认证、CRUD、搜索、文件上传、支付、通知和无障碍场景的 Given/When/Then 验收标准完整模式库。

---

边界自治规则 (Bounded Autonomy Rules)

这些规则定义了代理(人类或 AI)在何时必须停止并寻求指导,以及何时可以独立执行。

必须停止并询问的情况:

1. 检测到范围蔓延 (Scope Creep)。 实现过程中需要规格说明书(Spec)之外的功能。即使该功能看起来显然必要,也请停止。Spec 可能是刻意将其排除在外的。
2. 歧义程度超过 30%。 如果针对某项具体需求,你无法通过 Spec 确定超过 30% 的正确行为,则说明 Spec 不完整。请勿猜测。
3. 需要破坏性变更 (Breaking Changes)。 实现过程将改变现有的 API 契约、数据库模式或公共接口。必须上报。
4. 涉及安全影响。 任何涉及认证、授权、加密或 PII(个人可识别信息)处理的变更都需要明确批准。
5. 性能特性未知。 如果需求规定“必须在 < 500ms 内完成”,但你无法衡量或保证这一点,请在实施猜测方案前上报。
6. 跨团队依赖。 如果 Spec 要求与其他团队或服务协作,请在基于该依赖进行构建前予以确认。

可以自主继续的情况:

1. 当前任务的 Spec 清晰且无歧义
2. 所有验收标准均已通过测试,且你正在进行内部重构。
3. 变更非破坏性 —— 没有公共 API、模式或行为的变更。
4. 实现是定义明确的验收标准的直接转化
5. 错误处理遵循代码库中已记录的既定模式

上报协议 (Escalation Protocol)

当你必须停止时,请提供:

markdown
## 上报:[简短标题]

阻塞点: [需求 ID,例如 FR-3]
问题: [具体且可回答的问题 —— 不要问“我该怎么做?”]
考虑的方案:
A. [方案] — 优点:[...] 缺点:[...]
B. [方案] — 优点:[...] 缺点:[...]
我的建议: [A 或 B,并附带理由]
等待的影响: [在问题解决前,哪些工作被阻塞?]

严禁在没有建议的情况下上报。严禁提出开放式问题。务必提供选项。

详见 references/bounded_autonomy_rules.md 获取完整的决策矩阵。

---

工作流 — 6 个阶段

阶段 1:需求收集

目标: 理解需要构建什么以及为什么构建。

1. 访谈用户。 询问:
- 这解决了什么问题?
- 用户是谁?
- 成功的定义是什么?
- 明确不应该构建什么?
2. 阅读现有代码。 在提出变更建议前,先理解当前系统。
3. 识别约束条件。 性能预算、安全要求、向后兼容性。
4. 列出未知项。 每个未知项都是一个风险。现在就将其暴露出来,而不是在实现过程中。

退出标准: 你能在 2 分钟内向不熟悉该项目的人解释清楚该功能。

阶段 2:编写 Spec

目标: 按照上述 Spec 格式生成一份完整的规格说明文档。

1. 填写模板的每个部分,不得留空。
2. 为所有需求编号 (FR-*, NFR-*, AC-*, EC-*, OS-*)。
3. 精确使用 RFC 2119 关键词。
4. 使用 Given/When/Then 格式编写验收标准。
5. 使用 TypeScript 风格的类型定义 API 契约。
6. 在 O(排除项)中列出明确的排除内容。
超出范围。

退出标准: 规格说明书可直接交给未参加需求会议的开发人员,且其能够在无需询问澄清问题的情况下实现该功能。

第三阶段:验证规格说明书

目标: 验证规格说明书的完整性、一致性和可实现性。

对规格说明书文件运行 spec_validator.py

bash
python spec_validator.py --file spec.md --strict

手动验证清单:

  • [ ] 每个功能需求至少对应一个验收标准

  • [ ] 每个验收标准均可测试(无主观描述)

  • [ ] API 契约涵盖了需求中提到的所有端点

  • [ ] 数据模型涵盖了需求中提到的所有实体

  • [ ] 边界情况涵盖了每个外部依赖的失效模式

  • [ ] “超出范围”部分明确列出了经过考虑但被否决的内容

  • [ ] 非功能性需求具有可衡量的阈值

退出标准: 验证器评分 80+,且所有手动清单项均通过。

第四阶段:生成测试

目标: 在编写实现代码之前,从验收标准中提取测试用例。

对已批准的规格说明书运行 test_extractor.py

bash
python test_extractor.py --file spec.md --framework pytest --output tests/

1. 每个验收标准转化为一个或多个测试用例。
2. 每个边界情况转化为一个测试用例。
3. 测试为存根(Stubs)——仅定义断言,不包含具体实现。
4. 所有测试在初始状态下必须失败(TDD 的红灯阶段)。

退出标准: 拥有一个测试文件,其中每个测试均以“未实现”或同等错误失败。

第五阶段:实现

目标: 逐个完成验收标准,编写代码使失败的测试通过。

1. 选择一个验收标准(从最简单的开始)。
2. 用最少的代码使相关测试通过。
3. 运行全量测试套件 —— 确保无回归。
4. 提交代码。
5. 选择下一个验收标准,重复上述步骤。

规则:

  • 不要实现规格说明书之外的任何内容。

  • 在所有验收标准通过之前,不要进行优化。

  • 在所有验收标准通过之前,不要进行重构。

  • 如果发现缺失的需求,请立即停止并先更新规格说明书。

退出标准: 所有测试通过。所有验收标准均已满足。

第六阶段:自审

目标: 在标记为完成前,验证实现与规格说明书一致。

执行下方的自审清单。如果任何一项未通过,请在宣布任务完成前予以修复。

---

自审清单

在将任何实现标记为完成之前,请验证以下所有项:

  • [ ] 每个验收标准都有通过的测试。 无一例外。如果存在 AC-3,则必须存在对应的 AC-3 测试且通过。
  • [ ] 每个边界情况都有测试。 EC-1 至 EC-N 均有对应的测试用例。
  • [ ] 无范围蔓延。 实现中不包含规格说明书之外的功能。如果添加了内容,请更新规格说明书或将其删除。
  • [ ] API 契约与实现一致。 代码中的请求/响应结构与规格说明书完全一致。包括字段名、类型、状态码等。
  • [ ] 错误场景已测试。 规格说明书中定义的每个错误响应都有触发该响应的测试。
  • [ ] 非功能性需求已验证。 如果规格说明书要求 < 500ms,你必须拥有证明其达到该阈值的证据(基准测试、压力测试或性能分析)。
  • [ ] 数据模型一致。 数据库模式与规格说明书匹配。无冗余列,无缺失约束。
  • [ ] 未构建超出范围的项目。 再次确认“超出范围”部分的内容没有渗入到实现中。

与 TDD 指南的集成

规格驱动工作流(Spec-driven workflow)与 TDD 是互补而非竞争关系:

code
规格驱动工作流                      TDD (红-绿-重构)
─────────────────────         ──────────────────────────
阶段 1:收集需求
阶段 2:编写规格
阶段 3:验证规格
阶段 4:生成测试  ──→  RED:测试已存在且失败
阶段 5:实现      ──→  GREEN:编写最少代码以通过测试
阶段 6:自我审查  ──→  REFACTOR:清理内部实现

衔接点: 规格驱动工作流产生测试存根(阶段 4),随后由 TDD 接管。规格定义了“测试什么”,而 TDD 定义了“如何实现”。

在以下场景使用 engineering-team/tdd-guide

  • 红-绿-重构循环的纪律执行

  • 覆盖率分析与缺口检测

  • 特定框架的测试模式(Jest, Pytest, JUnit)

在以下场景使用 engineering/spec-driven-workflow

  • 在构建之前定义构建目标

  • 编写验收标准(Acceptance Criteria)

  • 完整性验证

  • 范围控制

---

示例

完整的实操示例(包含提取测试用例的密码重置规格)请参阅 spec_format_guide.md。该示例演示了全部 9 个章节、需求编号、验收标准、边缘情况,以及由 test_extractor.py 生成的相应 pytest 存根。

---

反模式

1. 规格批准前就开始编码

症状: “在规格评审期间,我先开始写代码。”
问题: 评审会产生变更。此时你编写的代码实现的是一个被否决的设计。
原则: 在规格状态变为“已批准(Approved)”之前,不得开始实现。

2. 验收标准模糊

症状: “系统应运行良好”或“UI 应有响应感”。
问题: 不可测试。“良好”和“响应感”的具体定义是什么?
原则: 每项验收标准必须是机器可验证的。如果无法为其编写测试,请重写该标准。

3. 缺失边缘情况

症状: 仅定义了正向路径(Happy path),未定义错误路径。
问题: 开发人员在实现时临时决定错误处理方式,导致行为不一致。
原则: 对于每个外部依赖(API、数据库、文件系统、用户输入),必须至少指定一种失败场景。

4. 将规格作为事后文档

症状: “功能开发完了,我现在来补写规格。”
问题: 这是文档而非规格。它描述的是“构建了什么”,而非“应该构建什么”。由于设计已定型,它无法捕捉设计缺陷。
原则: 如果规格是在代码之后编写的,它就不是规格。请将其重新标记为文档。

5. 超出规格的“过度设计”(Gold-Plating)

症状: “既然在写这段代码,我顺便把……也加上了。”
问题: 代码未经过测试,设计未经过评审。这些“额外功能”可能引入隐蔽的 Bug。
原则: 不在规格中的功能不予构建。如需增加功能,请提交新的规格。

6. 验收标准缺乏需求追溯

症状: 存在 AC-7,但未引用任何 FR-* 或 NFR-*。
问题: 孤立的标准意味着要么缺失了需求,要么该标准是不必要的。
原则: 每个 AC-* 必须引用至少一个 FR-* 或 NFR-*。

7. 跳过验证步骤

症状: “规格看起来没问题,直接开始吧。”
问题: 在实现过程中发现缺失章节,导致开发阻塞。
原则: 在开始实现前,务必运行 spec_validator.py --strict 并修复所有警告。

---

交叉引用

参考资料
  • engineering-team/tdd-guide — 红-绿-重构循环、测试生成、覆盖率分析。在本工作流的第 4 阶段后使用。
  • engineering/focused-fix — 深度功能修复。当基于规范的实现出现系统性问题时,使用 focused-fix 进行诊断。
  • engineering/rag-architect — 如果功能涉及检索或知识系统,请使用 rag-architect 进行规范内的技术设计。
  • references/spec_format_guide.md — 包含各章节详细说明的完整模板。
  • references/bounded_autonomy_rules.md — 关于停止与继续执行的完整决策矩阵。
  • references/acceptance_criteria_patterns.md — 编写 Given/When/Then 验收标准的模式库。

---

工具

| 脚本 | 用途 | 关键参数 |
|--------|---------|-----------|
| spec_generator.py | 根据功能名称/描述生成规范模板 | --name, --description, --format, --json |
| spec_validator.py | 验证规范完整性(评分 0-100) | --file, --strict, --json |
| test_extractor.py | 从验收标准中提取测试存根 | --file, --framework, --output, --json |

bash
# 生成规范模板
python spec_generator.py --name "User Authentication" --description "OAuth 2.0 login flow"

验证规范

python spec_validator.py --file specs/auth.md --strict

提取测试用例

python test_extractor.py --file specs/auth.md --framework pytest --output tests/test_auth.py