规范驱动开发 (SDD)
原文:https://github.com/github/spec-kit/blob/main/spec-driven.md
权力倒置
几十年来,代码一直是王者。规范服务于代码——它们是我们在"真正的"编码工作开始后建造然后丢弃的脚手架。我们编写PRD来指导开发,创建设计文档来告知实现,绘制图表来可视化架构。但这些总是从属于代码本身。代码就是真理。其他一切最多只是良好的意图。代码是真理的源泉,随着它的前进,规范很少能跟上步伐。由于资产(代码)和实现是一体的,很难在不试图从代码构建的情况下拥有并行实现。
规范驱动开发(SDD)颠覆了这种权力结构。规范不再服务于代码——代码服务于规范。产品需求文档(PRD)不是实现的指南;它是生成实现的源泉。技术计划不是告知编码的文档;它们是产生代码的精确定义。这不是对我们构建软件方式的渐进式改进。这是对驱动开发的根本重新思考。
规范与实现之间的差距自软件开发诞生以来就一直困扰着它。我们试图通过更好的文档、更详细的需求、更严格的流程来弥合它。这些方法失败了,因为它们接受差距是不可避免的。它们试图缩小差距但从未消除它。SDD通过使规范及其从规范中产生的具体实现计划可执行来消除差距。当规范和实现计划生成代码时,就没有差距——只有转换。
这种转换现在成为可能,因为AI能够理解和实现复杂的规范,并创建详细的实现计划。但没有结构的原始AI生成会产生混乱。SDD通过足够精确、完整和明确的规范和后续实现计划来提供这种结构,以生成工作系统。规范成为主要产物。代码成为它在特定语言和框架中的表达(作为实现计划的实现)。
在这个新世界中,维护软件意味着发展规范。开发团队的意图用自然语言表达("意图驱动开发")、设计资产、核心原则和其他指导方针。开发的通用语言提升到更高层次,代码是最后一英里的方法。
调试意味着修复生成错误代码的规范及其实现计划。重构意味着为清晰度而重新构建。整个开发工作流程围绕规范作为中央真理源泉重新组织,实现计划和代码作为持续再生的输出。用新功能更新应用程序或创建新的并行实现,因为我们是创造性的存在,意味着重新审视规范并创建新的实现计划。因此,这个过程是0 -> 1, (1', ..), 2, 3, N。
开发团队专注于他们的创造力、实验和批判性思维。
SDD工作流程实践
工作流程从一个想法开始——通常是模糊和不完整的。通过与AI的迭代对话,这个想法成为一个全面的PRD。AI提出澄清问题,识别边缘情况,并帮助定义精确的验收标准。在传统开发中可能需要数天会议和文档的工作,在数小时的专注规范工作中就完成了。这改变了传统的SDLC——需求和设计成为持续活动而不是离散阶段。这支持团队流程,其中团队审查的规范被表达和版本化,在分支中创建并合并。
当产品经理更新验收标准时,实现计划自动标记受影响的技术决策。当架构师发现更好的模式时,PRD更新以反映新的可能性。
在整个规范过程中,研究代理收集关键上下文。他们调查库兼容性、性能基准和安全影响。组织约束被自动发现和应用——您公司的数据库标准、认证要求和部署策略无缝集成到每个规范中。
从PRD中,AI生成将需求映射到技术决策的实现计划。每个技术选择都有文档化的理由。每个架构决策都追溯到特定需求。在整个过程中,一致性验证持续提高质量。AI分析规范的模糊性、矛盾性和差距——不是作为一次性门控,而是作为持续的改进。
一旦规范及其实现计划足够稳定,代码生成就开始了,但它们不必是"完整的"。早期生成可能是探索性的——测试规范在实践中是否有意义。领域概念成为数据模型。用户故事成为API端点。验收场景成为测试。这通过规范合并了开发和测试——测试场景不是在代码之后编写的,它们是生成实现和测试的规范的一部分。
反馈循环延伸到初始开发之外。生产指标和事件不仅触发热修复——它们为下一次再生更新规范。性能瓶颈成为新的非功能性需求。安全漏洞成为影响所有未来生成的约束。规范、实现和运营现实之间的这种迭代舞蹈是真正理解出现的地方,也是传统SDLC转变为持续演进的地方。
为什么SDD现在很重要
三个趋势使SDD不仅可能而且必要:
首先,AI能力已经达到一个阈值,自然语言规范可以可靠地生成工作代码。这不是关于替换开发者——而是通过自动化从规范到实现的机械转换来放大他们的有效性。它可以放大探索和创造力,轻松支持"重新开始",并支持加法、减法和批判性思维。
其次,软件复杂性继续呈指数级增长。现代系统集成了数十个服务、框架和依赖项。通过手动流程保持所有这些部分与原始意图一致变得越来越困难。SDD通过规范驱动的生成提供系统化的一致性。框架可能演变为提供AI优先支持,而不是人类优先支持,或围绕可重用组件进行架构。
第三,变化的速度在加速。需求变化比以往任何时候都更加迅速。转向不再是例外——它是预期的。现代产品开发要求基于用户反馈、市场条件和竞争压力的快速迭代。传统开发将这些变化视为干扰。每次转向都需要手动将变化传播到文档、设计和代码中。结果要么是限制速度的缓慢、仔细的更新,要么是积累技术债务的快速、鲁莽的变化。
SDD可以支持假设/模拟实验:"如果我们需要重新实现或更改应用程序以促进销售更多T恤的商业需求,我们将如何为此实现和实验?"
SDD将需求变化从障碍转变为正常工作流程。当规范驱动实现时,转向成为系统化再生而不是手动重写。在PRD中更改核心需求,受影响的实现计划自动更新。修改用户故事,相应的API端点重新生成。这不仅仅是关于初始开发——它是关于通过不可避免的变化保持工程速度。
核心原则
规范作为通用语言:规范成为主要产物。代码成为它在特定语言和框架中的表达。维护软件意味着发展规范。
可执行规范:规范必须足够精确、完整和明确,以生成工作系统。这消除了意图和实现之间的差距。
持续改进:一致性验证持续进行,而不是作为一次性门控。AI将规范分析模糊性、矛盾性和差距作为持续过程。
研究驱动上下文:研究代理在整个规范过程中收集关键上下文,调查技术选项、性能影响和组织约束。
双向反馈:生产现实告知规范演进。指标、事件和运营学习成为规范改进的输入。
探索分支:从同一规范生成多种实现方法,以探索不同的优化目标——性能、可维护性、用户体验、成本。
实现方法
今天,实践SDD需要组装现有工具并在整个过程中保持纪律。该方法可以通过以下方式实践:
- 用于迭代规范开发的AI助手
- 用于收集技术上下文的研究代理
- 用于将规范转换为实现的代码生成工具
- 适应规范优先工作流程的版本控制系统
- 通过AI分析规范文档进行一致性检查
关键是将规范视为真理的源泉,代码作为服务于规范而不是相反方向的生成输出。
通过命令简化SDD
SDD方法通过三个强大的命令得到显著增强,这些命令自动化了规范→规划→任务工作流程:
/speckit.specify 命令
此命令将简单的功能描述(用户提示)转换为完整的结构化规范,并自动进行仓库管理:
- 自动功能编号:扫描现有规范以确定下一个功能编号(例如,001、002、003)
- 分支创建:从您的描述生成语义分支名称并自动创建
- 基于模板的生成:复制并自定义功能规范模板与您的需求
- 目录结构:为所有相关文档创建适当的
specs/[branch-name]/结构
/speckit.plan 命令
一旦功能规范存在,此命令创建全面的实现计划:
- 规范分析:读取并理解功能需求、用户故事和验收标准
- 宪法合规:确保与项目宪法和架构原则的一致性
- 技术转换:将业务需求转换为技术架构和实现细节
- 详细文档:为数据模型、API合同和测试场景生成支持文档
- 快速启动验证:生成捕获关键验证场景的快速启动指南
/speckit.tasks 命令
创建计划后,此命令分析计划和相关设计文档以生成可执行任务列表:
- 输入:读取
plan.md(必需)以及如果存在的话,data-model.md、contracts/和research.md - 任务派生:将合同、实体和场景转换为特定任务
- 并行化:标记独立任务
[P]并概述安全的并行组 - 输出:在功能目录中写入
tasks.md,准备由任务代理执行
示例:构建聊天功能
以下是这些命令如何改变传统开发工作流程:
传统方法:
1. 在文档中编写PRD(2-3小时)
2. 创建设计文档(2-3小时)
3. 手动设置项目结构(30分钟)
4. 编写技术规范(3-4小时)
5. 创建测试计划(2小时)
总计:约12小时的文档工作
使用命令的SDD方法:
# 步骤1:创建功能规范(5分钟)
/speckit.specify 具有消息历史和用户状态的实时聊天系统
# 这自动:
# - 创建分支"003-chat-system"
# - 生成specs/003-chat-system/spec.md
# - 用结构化需求填充它
# 步骤2:生成实现计划(5分钟)
/speckit.plan 用于实时消息的WebSocket,用于历史的PostgreSQL,用于状态的Redis
# 步骤3:生成可执行任务(5分钟)
/speckit.tasks
# 这自动创建:
# - specs/003-chat-system/plan.md
# - specs/003-chat-system/research.md(WebSocket库比较)
# - specs/003-chat-system/data-model.md(消息和用户模式)
# - specs/003-chat-system/contracts/(WebSocket事件,REST端点)
# - specs/003-chat-system/quickstart.md(关键验证场景)
# - specs/003-chat-system/tasks.md(从计划派生的任务列表)
在15分钟内,您拥有:
- 具有用户故事和验收标准的完整功能规范
- 具有技术选择和理由的详细实现计划
- 准备代码生成的API合同和数据模型
- 用于自动和手动测试的综合测试场景
- 在功能分支中正确版本化的所有文档
结构化自动化的力量
这些命令不仅节省时间——它们强制执行一致性和完整性:
- 没有遗忘的细节:模板确保考虑每个方面,从非功能性需求到错误处理
- 可追溯的决策:每个技术选择都链接回特定需求
- 活文档:规范与代码保持同步,因为它们生成它
- 快速迭代:更改需求并在几分钟内重新生成计划,而不是几天
这些命令通过将规范视为可执行产物而不是静态文档来体现SDD原则。它们将规范过程从必要的邪恶转变为开发的驱动力。
模板驱动质量:结构如何约束LLM以获得更好的结果
这些命令的真正力量不仅在于自动化,还在于模板如何引导LLM行为朝向更高质量的规范。模板充当复杂的提示,以生产性方式约束LLM的输出:
1. 防止过早的实现细节
功能规范模板明确指示:
- ✅ 专注于用户需要什么以及为什么
- ❌ 避免如何实现(无技术栈、API、代码结构)
这种约束迫使LLM保持适当的抽象级别。当LLM可能自然地跳到"使用React和Redux实现"时,模板保持它专注于"用户需要数据的实时更新"。这种分离确保规范即使在实现技术变化时也保持稳定。
2. 强制明确的 uncertainty 标记
两个模板都强制使用[NEEDS CLARIFICATION]标记:
从用户提示创建此规范时:
1. **标记所有模糊性**:使用[NEEDS CLARIFICATION: 具体问题]
2. **不要猜测**:如果提示没有指定某些内容,标记它
这防止了LLM做出合理但可能不正确假设的常见行为。而不是猜测"登录系统"使用电子邮件/密码认证,LLM必须将其标记为[NEEDS CLARIFICATION: 未指定认证方法 - 电子邮件/密码、SSO、OAuth?]。
3. 通过检查清单进行结构化思考
模板包括充当规范"单元测试"的综合检查清单:
### 需求完整性
- [ ] 没有[NEEDS CLARIFICATION]标记
- [ ] 需求是可测试和明确的
- [ ] 成功标准是可测量的
这些检查清单迫使LLM系统地自我审查其输出,捕获可能遗漏的差距。这就像给LLM一个质量保证框架。
4. 通过门控进行宪法合规
实现计划模板通过阶段门控强制执行架构原则:
### 阶段-1:预实现门控
#### 简单性门控(第七条)
- [ ] 使用≤3个项目?
- [ ] 没有未来验证?
#### 反抽象门控(第八条)
- [ ] 直接使用框架?
- [ ] 单一模型表示?
这些门控通过使LLM明确证明任何复杂性来防止过度工程。如果门控失败,LLM必须在"复杂性跟踪"部分记录原因,为架构决策创建问责制。
5. 分层细节管理
模板强制执行适当的信息架构:
**重要**:此实现计划应保持高级和可读。
任何代码示例、详细算法或广泛的技术规范
必须放在适当的`implementation-details/`文件中
这防止了规范成为不可读代码转储的常见问题。LLM学会保持适当的细节级别,将复杂性提取到单独的文件中,同时保持主文档可导航。
6. 测试优先思考
实现模板强制执行测试优先开发:
### 文件创建顺序
1. 创建带有API规范的`contracts/`
2. 按顺序创建测试文件:合同→集成→e2e→单元
3. 创建源文件以使测试通过
这种排序约束确保LLM在实现之前考虑可测试性和合同,导致更强大和可验证的规范。
7. 防止推测性功能
模板明确劝阻推测:
- [ ] 没有推测性或"可能需要"的功能
- [ ] 所有阶段都有明确的先决条件和可交付成果
这阻止LLM添加使实现复杂化的"有则更好"功能。每个功能都必须追溯到具有明确验收标准的具体用户故事。
复合效应
这些约束共同产生以下规范:
- 完整:检查清单确保没有遗漏
- 明确:强制的澄清标记突出不确定性
- 可测试:测试优先思考融入过程
- 可维护:适当的抽象级别和信息层次结构
- 可实现:具有具体可交付成果的明确阶段
模板将LLM从创意作家转变为纪律严明的规范工程师,引导其能力产生持续高质量、可执行的规范,真正驱动开发。
宪法基础:执行架构纪律
SDD的核心是宪法——一套管理规范如何成为代码的不变原则。宪法(memory/constitution.md)充当系统的架构DNA,确保每个生成的实现保持一致性、简单性和质量。
开发的九条条款
宪法定义了塑造开发过程每个方面的九条条款:
第一条:库优先原则
每个功能必须作为独立库开始——没有例外。这从一开始就强制模块化设计:
Specify中的每个功能必须作为独立库开始其存在。
任何功能都不得在首先抽象为可重用库组件的情况下
直接在应用程序代码中实现。
这一原则确保规范生成模块化、可重用的代码而不是单体应用程序。当LLM生成实现计划时,它必须将功能结构化为具有清晰边界和最小依赖的库。
第二条:CLI接口授权
每个库必须通过命令行接口暴露其功能:
所有CLI接口必须:
- 接受文本作为输入(通过stdin、参数或文件)
- 产生文本作为输出(通过stdout)
- 支持JSON格式进行结构化数据交换
这强制执行可观察性和可测试性。LLM不能将功能隐藏在opaque类中——一切都必须通过基于文本的接口访问和验证。
第三条:测试优先命令
最具变革性的条款——测试之前无代码:
这是不可协商的:所有实现必须遵循严格的测试驱动开发。
在以下情况之前不得编写实现代码:
1. 编写单元测试
2. 测试由用户验证和批准
3. 确认测试失败(红色阶段)
这完全颠覆了传统的AI代码生成。而不是生成代码并希望它工作,LLM必须首先生成定义行为的综合测试,获得批准,然后才生成实现。
第七条和第八条:简单性和反抽象
这些配对条款对抗过度工程:
第7.3节:最小项目结构
- 初始实现最多3个项目
- 额外项目需要文档化理由
第8.1节:框架信任
- 直接使用框架功能而不是包装它们
当LLM可能自然地创建精心设计的抽象时,这些条款迫使它证明每一层复杂性。实现计划模板的"阶段-1门控"直接执行这些原则。
第九条:集成优先测试
优先考虑真实世界测试而不是隔离的单元测试:
测试必须使用真实环境:
- 优先使用真实数据库而不是模拟
- 使用实际服务实例而不是存根
- 实现前必须进行合同测试
这确保生成的代码在实践中工作,而不仅仅是在理论上。
通过模板进行宪法执行
实现计划模板通过具体检查点操作化这些条款:
### 阶段-1:预实现门控
#### 简单性门控(第七条)
- [ ] 使用≤3个项目?
- [ ] 没有未来验证?
#### 反抽象门控(第八条)
- [ ] 直接使用框架?
- [ ] 单一模型表示?
#### 集成优先门控(第九条)
- [ ] 定义了合同?
- [ ] 编写了合同测试?
这些门控充当架构原则的编译时检查。LLM不能在不通过门控或在"复杂性跟踪"部分记录合理例外的情况下继续。
不变原则的力量
宪法的力量在于其不变性。虽然实现细节可以演进,但核心原则保持不变。这提供:
- 跨时间一致性:今天生成的代码遵循与明年生成的代码相同的原则
- 跨LLM一致性:不同的AI模型产生架构兼容的代码
- 架构完整性:每个功能都加强而不是破坏系统设计
- 质量保证:测试优先、库优先和简单性原则确保可维护的代码
宪法演进
虽然原则是不变的,但它们的应用可以演进:
第4.2节:修正过程
对此宪法的修改需要:
- 明确记录变更理由
- 项目维护者审查和批准
- 向后兼容性评估
这允许方法在保持稳定性的同时学习和改进。宪法显示其自身的演进,带有日期修正,展示原则如何基于真实世界经验进行改进。
超越规则:开发哲学
宪法不仅仅是规则书——它是塑造LLM如何思考代码生成的哲学:
- 可观察性优于不透明性:一切都必须通过CLI接口可检查
- 简单性优于聪明性:从简单开始,只有在证明必要时才添加复杂性
- 集成优于隔离:在真实环境中测试,而不是人工环境
- 模块化优于单体:每个功能都是具有清晰边界的库
通过将这些原则嵌入到规范和规划过程中,SDD确保生成的代码不仅仅是功能性的——它是可维护的、可测试的和架构健全的。宪法将AI从代码生成器转变为尊重和加强系统设计原则的架构伙伴。
转变
这不是关于替换开发者或自动化创造力。这是关于通过自动化机械转换来放大人类能力。这是关于创建一个紧密的反馈循环,其中规范、研究和代码共同演进,每次迭代都带来更深的理解和意图与实现之间更好的对齐。
软件开发需要更好的工具来维护意图和实现之间的一致性。SDD通过生成代码而不是仅仅指导代码的可执行规范,提供了实现这种一致性的方法。