| name | spec-driven-development |
| description | 在编码之前创建规格。当开始一个新项目、功能或重大变更且尚无规格时使用。当需求不清晰、模棱两可,或仅作为模糊想法存在时使用。当需要起草 PRD(产品需求文档)时使用。 |
规范驱动开发
概述
在编写任何代码之前编写结构化规格。规格是你和人类工程师之间的共享真相来源——它定义我们正在构建什么、为什么以及如何知道它完成了。没有规格的代码就是猜测。
何时使用
- 开始一个新项目或功能
- 需求模糊或不完整
- 变更涉及多个文件或模块
- 你即将做出架构决策
- 任务将需要超过 30 分钟来实现
何时不使用: 单行修复、拼写纠正或需求明确且自包含的变更。
门禁工作流
规范驱动开发有四个阶段。在当前阶段被验证之前,不要推进到下一阶段。
规格化 ──→ 规划 ──→ 任务 ──→ 实现
│ │ │ │
▼ ▼ ▼ ▼
人类 人类 人类 人类
审查 审查 审查 审查
阶段 1:规格化
从高层愿景开始。询问人类澄清问题,直到需求具体。
立即提出假设。 在编写任何规格内容之前,列出你正在假设的内容:
我正在做的假设:
1. 这是一个单机存储引擎(非分布式)
2. 节点间通信使用 gRPC(非自研二进制协议)
3. 持久化格式沿用现有 LSM-tree 布局(基于现有 manifest 格式)
4. 我们仅针对 Linux x86_64(无 macOS/ARM 支持)
→ 现在就纠正我,否则我将按这些进行。
不要静默地填补模棱两可的需求。规格的整个目的就是在代码编写之前揭示误解——假设是最危险的误解形式。
编写涵盖这六个核心领域的规格文档:
-
目标——我们正在构建什么以及为什么?用户是谁?成功是什么样子?
-
命令——带有标志的完整可执行命令,而不仅仅是工具名称。
构建:cargo build --release
测试:cargo test --workspace
Lint:cargo clippy -- -D warnings
开发:cargo run --bin server
-
项目结构——源代码的位置、测试的位置、文档的位置。
src/ → 服务源代码
src/storage → 存储引擎
src/rpc → 网络与 RPC 层
tests/ → 单元和集成测试
tests/cluster → 多节点端到端测试
docs/ → 文档
-
代码风格——一个展示你风格的真实代码片段胜过三段描述它的文字。包含命名约定、格式化规则和良好输出的示例。
-
测试策略——什么框架、测试的位置、覆盖率期望、哪些测试级别用于哪些关注点。
-
边界——三层系统:
- 始终做到: 提交前运行测试,遵循命名约定,验证输入
- 先询问: 数据库 Schema 变更,添加依赖项,更改 CI 配置
- 永远不做: 提交机密,编辑 vendor 目录,未经批准移除失败测试
规格模板:
# 规格:[项目/功能名称]
## 目标
[我们正在构建什么以及为什么。用户故事或验收条件。]
## 技术栈
[框架、语言、关键依赖项及版本]
## 命令
[构建、测试、Lint、开发——完整命令]
## 项目结构
[带描述的目录布局]
## 代码风格
[示例片段 + 关键约定]
## 测试策略
[框架、测试位置、覆盖率要求、测试级别]
## 边界
- 始终:[...]
- 先询问:[...]
- 永远不:[...]
## 成功标准
[我们如何知道这完成了——具体的、可测试的条件]
## 待解决问题
[任何未解决的、需要人类输入的问题]
将指令重新框定为成功标准。 当收到模糊需求时,将其转化为具体条件:
需求:"让读取路径更快"
重新框定的成功标准:
- 命中缓存的点查 p99 < 1ms
- 冷读(未命中缓存)p99 < 10ms
- 16 线程下吞吐不低于 200K ops/s
→ 这些是正确的目标吗?
这让你能够循环、重试和解决问题以达成清晰目标,而非猜测"更快"意味着什么。
阶段 2:规划
有了经过验证的规格,生成技术实现计划:
- 识别主要组件及其依赖项
- 确定实现顺序(必须首先构建什么)
- 记录风险和缓解策略
- 识别什么可以并行构建 vs 什么必须顺序构建
- 定义各阶段之间的验证检查点
遵循 planning-and-task-breakdown 了解这些步骤背后的依赖图映射和垂直切片机制;它是规范的来源。上面的要点是轻量摘要;如果它们有分歧,以 planning-and-task-breakdown 为准。
输出约定: 将计划保存到 tasks/plan.md,将任务列表保存到 tasks/todo.md,按照 /plan 命令约定。如果 tasks/ 不存在则创建它。下游命令(/build 等)期望这些路径。
计划应该是可审查的:人类应该能够阅读它然后说"是的,这是正确的方法"或"不,改 X。"
阶段 3:任务
将计划分解为离散的、可实现的 task:
- 每个 task 应该可以在一次专注的会话中完成
- 每个 task 有显式的验收条件
- 每个 task 包含一个验证步骤(测试、构建、手动检查)
- 任务按依赖关系排序,而非按感知的重要性排序
- 没有 task 需要超过约 5 个文件的变更
遵循 planning-and-task-breakdown 了解完整的任务规模化和依赖排序机制;它是规范的来源。下面的模板是轻量内联形式;如果它们有分歧,以 planning-and-task-breakdown 为准。
任务模板:
- [ ] 任务:[描述]
- 验收:[完成后什么必须为真]
- 验证:[如何确认——测试命令、构建、手动检查]
- 文件:[哪些文件将被触碰]
阶段 4:实现
一次执行一个任务,遵循 skills/incremental-implementation/SKILL.md(incremental-implementation)和 skills/test-driven-development/SKILL.md(test-driven-development)。使用 skills/context-engineering/SKILL.md(context-engineering)在每个步骤加载正确的规格部分和源文件,而非用整个规格淹没智能体。
保持规格持续更新
规格是活的文档,而非一次性产物:
- 当决策变化时更新——如果你发现数据模型需要改变,先更新规格,然后实现。
- 当范围变化时更新——添加或取消的功能应反映在规格中。
- 提交规格——规格属于版本控制,与代码一起。
- 在 PR 中引用规格——链接回每个 PR 实现的规格部分。
常见合理化借口
| 合理化借口 | 现实 |
|---|
| "这很简单,我不需要规格" | 简单的任务不需要长规格,但它们仍然需要验收条件。两行的规格也可以。 |
| "我写完代码再写规格" | 那是文档,不是规格。规格的价值在于在代码之前强制清晰性。 |
| "规格会拖慢我们" | 15 分钟的规格可以防止数小时的返工。15 分钟的瀑布式胜过 15 小时的调试。 |
| "需求反正会变" | 这就是为什么规格是活的文档。过时的规格仍然比没有规格好。 |
| "用户知道他们想要什么" | 即使是明确的请求也有隐含的假设。规格揭示那些假设。 |
红旗警告
- 没有任何书面需求就开始编写代码
- 在澄清"完成"意味着什么之前询问"我应该直接开始构建吗?"
- 实现任何规格或任务列表中未提及的功能
- 做出架构决策而不记录它们
- 因为"构建什么很明显"而跳过规格
验证
在继续实现之前,确认: