第二部分:为什么采用规范驱动开发
Vibe Coding(氛围编程)在你探索想法、制作一次性原型或想快速看到解决方案雏形时很有用。但它难以支撑项目的长期生命周期。聊天中没有持久的记忆,需求与修复混杂在一起,架构决策往往是随机出现的。
SDD 不是通过魔法来解决这个问题,而是将上下文从短暂的对话转移到可版本控制的文件中。智能体(Agent)得到的不仅是"去做"的指令,还有项目地图:项目为何存在、已做出哪些决策、当前正在构建什么、如何验证完成度。
Vibe Coding 的典型故障
- 意图偏移。你要求"简单的表单",智能体却添加了复杂的状态管理、新库和不同的界面风格。
- 上下文瓦解。经过几次会话后,智能体忘记了为什么项目不使用 ORM,或者为什么 API 必须在服务端渲染 HTML。
- 无法验证的结果。智能体修改了 30 个文件,你不知道按什么标准来验收。
- 隐藏决策。重要决策留在了聊天历史中,没有进入代码仓库。
- 审阅疲劳。智能体写得很快,而人却疲于检查大量的变更。
SDD 不会让智能体变得无懈可击。它让错误出现得更早、更小、更可验证。
使用 Qwen Code 时工作方式的变化
不再是这种漫长的单一会话:
qwen
> 构建整个应用。
> 修复这个。
> 看起来不对。
> 添加测试。
> 还是用 SQLite 吧。
你创建一个稳定的循环:
qwen
> /clear
> 阅读 @specs/mission.md @specs/tech-stack.md @specs/roadmap.md。
> 为路线图下一阶段创建功能规范。先向我提问。
然后在新的会话中:
qwen
> /clear
> 阅读 @specs/mission.md @specs/tech-stack.md 和 @specs/2026-05-08-reviews-display/plan.md。
> 只实现任务组 1 和 2。不要修改无关文件。
验证单独进行:
qwen
> /clear
> 将实现与 @specs/2026-05-08-reviews-display/validation.md 对比。
> 修复前先列出差异。
每个会话只获得其角色所需的精确上下文。
SDD 不等于瀑布模型
经典的瀑布模型试图预先描述整个系统。而在与智能体协作的 SDD 中,规范是小型的、动态的、面向单一功能的。你不需要在启动前写 80 页文档。你只需记录足够的上下文,以支持下一个有意义的步骤。
好的功能规范应该是:
- 小型:一个阶段、一个分支、一次合并;
- 可验证:有验证命令和手动验证场景;
- 与路线图关联;
- 无需先前聊天记录,新智能体也能理解;
- 足够严格,让智能体无需猜测重要决策。
好规范回答的七个问题
为了避免将规范变成标题堆砌,请记住这七个问题。如果有任何一个没有答案,说明规范尚未准备好进入实现阶段。
- 功能背后的业务意图或产品需求是什么? 即我们为什么要做这件事,而非"做什么"和"怎么做"。
- 用户是谁,他的使用场景是什么? 如果只有管理员使用该功能,与访客可见的情况相比,会是一组不同的决策。
- 什么在工作范围内,什么不在? 明确列出的边界和明确的"范围外"可以防止范围蔓延。
- 哪些决策已确定,哪些仍开放? 记录已确定的决策是为了防止智能体重做选择。记录开放的决策是为了让人注意到并在实现前解决。
- 哪些限制不能放宽? 技术栈、不变量、数据模式、API 格式、安全限制。
- 什么不应该被破坏? 功能不应触碰的现有行为(详见第 7 部分关于否定需求的内容)。
- 如何证明结果正确? 命令、手动场景、对照值、偏差迹象。没有这些,规范只是愿望,而非契约。
这七个问题不规定文件结构。结构保持不变:requirements.md、plan.md、validation.md。七个问题是内容检查清单。
何时 SDD 是过度设计
不必为一次性 shell 脚本或小型文本修改撰写完整的规范。轻量请求有时更好。实用原则:
- 如果变更可以在 5 分钟内完全理解和验证,普通请求就足够了;
- 如果变更涉及架构、数据、安全、公共行为或多个文件,请编写规范;
- 如果智能体将自主工作超过几分钟,规范几乎总是值得的。
示例:糟糕的省时方式
你请求:
添加入口。
智能体可能选择 JWT、cookie 会话、OAuth、本地用户、无密码登录链接、PostgreSQL、SQLite、Prisma、Drizzle、密码重置、中间件和界面。如果一半选择是错误的,你会花时间回退。
更好的方式是先描述:
# 需求 — 管理员入口
## 边界
- 仅管理员使用的单一登录页面。
- 通过 cookie 会话认证。
- 无自助注册。
- 本阶段无密码重置。
## 决策
- 在 SQLite 中存储单一管理员。
- 使用 httpOnly cookie。
- 仅保护 `/dashboard`。
## 验证
- 未认证的 GET /dashboard 重定向至 /login。
- 错误密码显示通用错误信息。
- 正确密码设置 cookie 并重定向至 /dashboard。
- `npm test` 和 `npm run typecheck` 通过。
现在智能体无需猜测。
实践
取任何你通常会用一句话要求完成的功能,将其改写为小型规范:
# 需求 — <功能名称>
## 边界
## 范围外
## 决策
## 验证
然后向 Qwen Code 提问:
将 @requirements.md 作为功能规范检查。其中有哪些足够模糊的地方,可能导致实现偏离方向?
在消除模糊性之前,不要要求编写代码。
自检问题
- 功能级别的 SDD 与大型预先设计有何不同?
- 为什么"代码能运行"不足以验收智能体所做的变更?
- 你的项目中哪些决策应在代码生成前记录下来?