SDD
Spec-Driven Development, 规范驱动开发, 现在在 Vibe Coding 的使用中经常提及的一个开发模式
导入
好,现在我们开始许愿 —— “请给 player 添加血量的实现”, 然后 Coding Agent 给出洋洋洒洒千行代码实现了这个功能,使用了一个全局变量存储 player 的血量( 不行不行? 似乎好像也行
此时我们可以发现一件事情 —— 我们提出了需求, AI 似乎也实现了我们的需求,但是其实对于整个架构的设计,其实我们的参与度比较低,所以实际上的链路大抵是 —— 我们提出需求 -> AI 设计 -> AI 顺带实现
那么此时代码的不可控程度会大幅增加,不仅增加了审核代码的心智负担,也会降低我们对于代码的“掌握度”
所以 SDD 试图解决的核心问题之一就是这个
主要思想
也就是我们不希望跳过“设计”这个步骤直接许愿 —— 即在开始实现之前,先明确系统应该满足什么行为,再根据这些行为设计实现方案、拆分任务、编写代码并验证最终实现是否符合最初的想法
简单例子
还是以给 player 添加血量的这个功能实现作为例子,然后速通 vibe 出来的代码假设是 ——
class Player {
public:
int health = 100;
void take_damage(int damage) { health -= damage; }
};看上去没什么问题,一个非常简单的实现,但是对于血量的约束?最大血量?能否为负?血量为负之后有什么行为?初始化一定是100吗?……
这一切都是隐藏在我们的prompt之外的信息,但是我们不说,没人知道 (
于是就需要写清楚 spec 这块
Specification
继续上文,先不考虑具体实现,而是先说明清楚心中血量功能的具体表现行为 ——
- Player 拥有当前血量
- Player 拥有最大血量
- 初始化时当前血量等于最大血量
- 受到伤害时当前血量减少
- 当前血量不能小于 0
- 当前血量不能大于最大血量
- 当前血量到达 0 时 Player 死亡
而具体是通过成员变量,全局单例,或是组件来具体实现,则不是此处需要定义的部分
综上所属,此阶段需要我们描述清楚系统/功能所需要满足的内容
Plan 和 Task
当系统应该满足什么行为基本确定之后,现在开始说明技术细节(Plan)和实现步骤(Task) —— 可以理解为上一个步骤是 What, 而现在是 How
在 Plan 中,可以说明清楚我们是通过什么方式实现,各个模块之间如何依赖等,比如简单的 ——
HealthComponent
Responsibilities:
- own current/max health
- maintain health invariant
- process damage
- expose current/max health
- provide dead-state information值得注意的是,此处不是把代码实现出来,只是说明清楚技术细节,或许可以理解成把上一步的系统行为规范从自然语言说明转化成更技术上的说明和解决方案
然后通过 task 把 plan 中的各个说明给拆解以方便之后实现
因为 plan 相当于一个总的技术蓝图,比较肥硕,,所以借助 task 拆解成每一个比较简单且好交付的步骤来让 Agent 去实现
其他流程
上述是比较大的步骤,接下来基本上就是交付给AI实现(Implement),然后进行审核和测试等(是否符合spec的定义?是否可以正常work等)