先写规格,再写代码:我的 SDD 工作流 v2.0
这是我的 Vibe Coding 实战系列第一篇。打算之后陆续补几篇,把我这半年用 Claude Code 做项目过程中踩过的坑、沉淀下来的规矩,都写一写。
起因是简历更新时给自己挖了个坑——把"Vibe Coding"和"自研工作流"写进去了,回头一想,总不能只在简历里写,博客却两年没更。
一、缘起:Claude Code 爽完了,然后呢?
去年开始用 Claude Code 后,第一感受是爽。一句话生成半天的代码量,重构一个组件十分钟搞定。
但新鲜感过一阵就变成了另一种感受——还债。
具体痛点列几条,我相信只要真用 AI 写代码超过一个月的人都会有共鸣:
- 每次都要重新解释项目背景。开一个新会话,又得把项目结构、技术栈、已有约定讲一遍,讲不全 AI 就自由发挥。
- 改完代码还得大规模 Review。AI 是很快,但它不知道哪些是"能动的"、哪些是"千万别碰的",Review 的时间把节省的时间全赔进去了。
- AI 对业务理解有偏差。需求说 A,它理解成 A',写出来像 A 又不完全是 A,离得远还不如离得远——离得近反而更难发现。
- 旧项目改造最容易翻车。AI 看几个文件就开始动手,结果把原有的命名约定、目录结构、封装模式打破了,整个项目越改越乱。
- 多人协作时每个人用 AI 的思路都不一样。同一个团队,甲用 AI 一套玩法,乙用 AI 另一套玩法,代码风格和约束越来越发散。
核心问题其实就一句:AI 不知道「这里应该是什么样的」,所以它按「常见的应该是什么样的」来写。
二、核心原则:先写规格,再写代码
SDD(Spec-Driven Development)的核心原则只有一句:
先写规格,再写代码。AI 每次动代码之前,必须先知道「这里应该是什么样的」。
换句话说,与其每次让 AI 从零开始"猜"项目和业务,不如把"这里应该是什么样的"提前写下来,让它读,让它按规矩来。
Spec-Driven 这个思路不是我原创,GitHub Spec Kit、Amazon Kiro 的 specs 都是这个方向。但具体落到自己团队和 Claude Code 的协作场景里,还得自己搭一套。这就是 SDD Workflow 的由来。
目前迭代到 v2.0。
三、SDD 长什么样:三图体系
SDD Workflow 是一个分三层的工作流:
| 步骤 | 名称 | 说明 |
|---|---|---|
| 图一 | 项目启动 | 新项目或旧项目接入,完成基础建设后进入开发循环 |
| 图二 | 业务开发循环 | 需求 → 设计 → 原型 → 评审 → 开发 → 测试 → 上线 → 归档 |
| 图三 | 变更通道 | 每次开发任务的执行路径:直通 / 快速 / 标准 |
每一图管一层事,互相咬合。我按顺序说一下。
图一:项目启动
每次开始新对话,AI 先问一句:新项目还是旧项目?
这一步特别关键。两条路的处理方式完全不同:
新项目:
- 用户提供 PRD(放根目录)
- AI 读 PRD,理解业务
- AI 单独询问技术栈(不从 PRD 猜——这是 v2 的重要规则,之前 PRD 里偶尔夹技术描述,AI 会误读成硬约束)
- AI 询问外部依赖
- 学习公司规范文档 → 写入
rules/ - 学习外部依赖文档 → 记录到
api-libs.md - AI 初始化
.project/目录 - 初始化代码结构,确认能跑起来
旧项目:
AI 自动读代码得出的部分(项目结构、命名约定、目录结构、外部依赖、数据库、接口),和必须人工确认的部分(危险区域、分支策略、部署环境、敏感配置、性能约束、团队协作信息、基线状态),严格分开。
旧项目最容易翻车的不是 AI 读不懂代码,而是 AI 读懂了,但不知道"这块代码不能动"。所以这一步的人工确认清单是硬要求。
图二:业务开发循环
这一图其实就是标准的"需求 → 设计 → 原型 → 评审 → 开发 → 测试 → 上线 → 归档",没什么神秘的。重点在于每一步都有对应的 AI 产出物:
- 需求分析:AI 拆解需求、梳理用户故事、写验收标准
- 方案设计:AI 输出
DES-xx.md(技术方案、数据结构、接口) - 原型生成:AI 生成 HTML 线框图 / 交互流程图
- 评审:人工确认(不通过则回到方案设计)
- 开发:走变更通道(见图三)
- 测试:AI 辅助写用例,人工验证
- 上线:人工确认部署
- 归档:AI 自动写入
context.md、生成 Changelog
图三:变更通道——全文最关键的设计
这是 v2 新增的,也是我最想拿出来说的一个设计。
早期版本我犯的错是:所有开发任务走同一个流程。结果就是改一行 CSS 的颜色也要走 Spec、评估影响面、写 Changelog——AI 被折腾到爆炸,开发效率反而下降。
v2 把变更分成三档:
| 通道 | 触发条件 | 执行路径 |
|---|---|---|
| 直通 | 不涉及代码(讨论 / 解释 / 运行命令) | 直接回答 → 更新 context.md |
| 快速 | 仅样式 / 文案,不改变逻辑 | 直接改代码 → 更新 context.md |
| 标准 | 涉及业务逻辑 / 接口 / 数据 / Bug | 执行 Step 1~7 完整流程 |
标准通道的 7 步:
Step 1 加载 Spec 读取 index.md → 路由匹配 → 读 REQ+DES → 检查 sync-status
Step 2 文档学习(按需) 涉及未记录的 API/库时触发,学完反填 project-custom.md
Step 3 评估影响面 判断波及哪些模块、识别潜在风险
Step 4 执行代码变更 符合 specs/ 规范 + rules/ 公用规范
Step 5 测试验证 确认符合验收标准
Step 6 生成 Changelog 记录变更内容、影响模块、核心文件
Step 7 写入 context.md AI 自动执行,记录完成内容和下一步建议
三级通道看上去像是"加流程",实际是减流程——让该重的重、该轻的轻。
四、v1 → v2 的三个关键升级
除了上面说的三级通道,v2 还新增了另外两个东西:
1. 项目铁律 Constitution
这是 v2 里我最满意的设计之一。
过去所有约束都堆在 rules/ 里,但 rules/ 的定位是"AI 应该遵守,特殊情况可以有例外"。问题是——有些规矩是真的不能有例外,比如"金额字段必须用 Decimal"、"用户数据必须有操作日志",AI 一旦绕过后果很严重。
v2 把约束分成两层:
| 对比项 | 说明 |
|---|---|
rules/ 参考规范 |
AI 应该遵守,特殊情况可以有例外 |
| 项目铁律 Constitution | AI 绝对不能违反,违反时立即停止并报告 |
铁律存放在 project-custom.md 的"项目铁律"区块,标准通道 Step 0 必须先检查。
一个关键点:铁律由团队人工填写,AI 不自动生成。AI 不知道什么是"真正不能碰"的,必须人决定。
2. 三级变更通道
上一节讲过了,不重复。
3. .project/ 目录结构
这是让整个工作流真正"可落地"的载体。
.project/
├── context.md # AI 工作记忆替代品,每次对话开始读、结束更新
├── specs/
│ └── master/
│ ├── index.md # 模块状态总览 + 路由表 + 活跃工作项
│ ├── REQ-01.md # 需求规格
│ ├── REQ-02.md
│ ├── DES-01.md # 设计规格(对应 REQ-01)
│ └── DES-02.md
├── rules/
│ ├── ui-base.md # 公司 UI 规范
│ ├── frontend-base.md # 前端技术规范
│ ├── backend-base.md # 后端技术规范
│ ├── product-base.md # 产品规范
│ ├── api-libs.md # 公共 API 库规范
│ └── project-custom.md # 项目定制规范 + 铁律
└── changelog/
├── 20260312-143000.md # 每次标准通道变更的完整记录
└── 20260315-091200.md
几个关键文件的角色:
context.md:AI 的"工作记忆替代品"。每次对话开始读取,每次任务结束 AI 自动更新。这是对"AI 没有跨会话记忆"这个问题的正面回答——既然记不住,那就让它每次都读同一个文件。specs/master/index.md:模块状态总览 + 路由表 + 活跃工作项。标准通道 Step 1 的第一步就是读它。rules/vsproject-custom.md:一个是公司级(长期有效、跨项目复用),一个是项目级(定制化 + 铁律)。分开是为了复用。changelog/:每次标准通道变更都生成一份完整记录。用于追溯和复盘——也是后来看"AI 到底做了啥"最重要的材料。
五、实际用起来是什么样的
假设我要加一个"访客邀约表单"的新需求,标准通道跑下来大概是这样:
我:需要加一个访客邀约表单,要求 xxx。
Claude(Step 0):先检查项目铁律 … ok,无冲突。
Claude(Step 1):读 index.md,定位到 visitor 模块,读 REQ-visitor.md 和 DES-visitor.md。
Claude(Step 2):无需新增外部文档学习。
Claude(Step 3):影响面评估——会影响 visitor/form.vue、visitor/api.ts、
路由 /visitor/invite。风险:审批流程接口有依赖,需要确认字段契约。
Claude(Step 4):执行代码变更 …
Claude(Step 5):测试用例 …
Claude(Step 6):生成 changelog/20260420-150000.md
Claude(Step 7):更新 context.md,下一步建议:对接审批流程接口。
这一套流程下来,有三个好处:
- 我不用每次都把项目背景再讲一遍——AI 读
context.md和specs/就够了。 - AI 的产出有审计路径——出问题回头看
changelog/就行。 - 团队其他人接手时能立刻进入状态——
.project/就是全项目的认知地图。
六、没解决的 / 下一步要做的
坦白讲,SDD Workflow v2.0 不是完美的,现在还有几个坑:
- Spec 写错了 AI 会认真执行错的。Spec 本身的质量是瓶颈,目前靠人工审,还没好办法。
context.md越来越长。长到一定程度 AI 会抓不住重点,需要定期人工压缩,这个还没自动化。- 多人协作时 Spec 冲突。两个人同时改同一个 REQ,合并起来很痛苦——类似代码的 merge conflict,但 Spec 的冲突更难机械化处理。
- 跨项目复用。
rules/想做到公司级通用,但每次新项目都得重新沉淀一次,工具链不够顺。
这些都是后续几篇博客想展开的主题。
七、下期预告
这个系列打算写 4~5 篇,暂拟:
- [02] context.md 的写法:AI 的工作记忆怎么填
- [03] 三级变更通道的实战:为什么直通/快速通道是效率的关键
- [04] 项目铁律 Constitution 实录:我给 AI 画的那几条红线
- [05] SDD 在旧项目接入时的 7 个坑
欢迎交流。如果你也在自己搭 AI 辅助开发的工作流,留言聊聊你的做法。
浙公网安备 33010602011771号