摘要
以Chrome英文翻译插件为案例,详解SDD文档驱动开发:proposal定需求、design定架构、tasks拆任务、AI严格按任务编码,文档先行让AI辅助开发有据可依、可追溯、可回退。
当 AI 编码遇到"幻觉"
Vibe Coding 让非程序员也能用自然语言生成软件,但一个常见问题是:AI 生成的代码不可控、不可追溯。关掉聊天窗口,之前的决策逻辑就消失了。AI 可能产生幻觉,偏离原始需求,或者引入意料之外的功能。
SDD(Specification-Driven Development,文档驱动开发)的解法是:先写文档,再写代码。文档定义需求边界和验收标准,AI 严格按照文档执行,每完成一个任务等待确认再继续。
用一个 Chrome 英文网页翻译插件作为案例,完整走一遍 SDD 流程。
SDD 文档体系
SDD 的核心是五类文档,每类文档解决一个层面的问题:
arduino
proposal.md → 定义"做什么"(需求边界)
design.md → 定义"怎么做"(技术选型与架构)
tasks.md → 定义"分几步做"(任务拆解与优先级)
页面设计文档 → 定义"长什么样"(UI 布局与状态)
project_rules.md → 定义"怎么约束 AI"(开发规则)
这五类文档形成了一条从需求到实现的完整链路,每一层都建立在前一层的基础上。
第一层:proposal.md------定义"做什么"
proposal 是 SDD 的起点,回答三个核心问题:
- 是什么:MVP 最小可行性单元是什么?
- 做什么:核心功能有哪些?
- 不做什么:边界在哪里?
以 Chrome 翻译插件为例,proposal 明确:
核心价值链路:提取网页正文 → 转换为 Markdown → 调用 AI 翻译 → 打字机效果展示 → 下载 / 本地恢复
同时明确"不做什么":
- 不提供历史翻译记录查询
- 不提供多语言互译(仅英文 → 中文)
- 不提供云端同步或账号体系
"不做什么"比"做什么"更重要------它定义了项目的边界,防止范围蔓延。AI 在"不做什么"之外的领域产生幻觉时,可以拿 proposal 说"不"。
proposal 还定义了输出内容的严格格式:
markdown
# [文章标题]
> **作者**: [作者名]
> **原文链接**: [URL]
[翻译后的正文]
格式必须精确到标点符号和缩进------这是文档驱动开发的"规范"部分,后续所有实现都以此为准。
第二层:design.md------定义"怎么做"
需求确定后,进入技术架构设计。design.md 的核心产出是技术选型对比和模块划分。
技术选型不是拍脑袋,而是对比分析后的结论。以正文提取方案为例,design 文档中列出了三种候选方案并逐一排除:
| 方案 | 优点 | 缺点 | 结论 |
|---|---|---|---|
document.body.innerText |
实现简单 | 混入干扰内容,丢失结构与图片 | 不采用 |
| 自定义 DOM 启发式算法 | 无需依赖 | 规则难穷尽,跨站点泛化能力差 | 不采用 |
@mozilla/readability |
Firefox 阅读模式同款,大量验证 | 需配合 Turndown | 采用 |
每个选型都写明了取舍理由,后续如果遇到问题可以回溯到设计文档重新评估,而不是在代码中临时改方案。
design 文档还定义了三层架构和模块职责:
css
Side Panel(React UI)
↓ 消息通信
Background Service Worker(编排调度)
↓ 注入/消息通信
Content Script(页面 DOM 提取)
依赖方向 :sidepanel / background / content 依赖 shared / services,反向不依赖。这个约束在 project_rules 中固化,AI 在编码时不得违反。
第三层:tasks.md------拆解为可独立执行的任务
设计确定后,将整个项目拆解为多个可独立完成、可单独验证的任务。任务拆解遵循三个原则:
独立可完成:每个任务有明确的边界和交付物。比如 T1 "项目工程骨架初始化"只做构建配置和目录结构,不做任何业务逻辑。
可见效果:每个任务完成后都能看到阶段性成果。T1 完成后能在 Chrome 中加载并打开空白侧边栏,T2 完成后能看到布局和状态切换。
减少依赖:优先采用 mock 数据、默认配置等手段解耦,尽量并行开发。T2(侧边栏静态页面)、T3(Options 设置页)、T4(正文提取模块)、T5(AI 翻译服务)四个任务可以并行推进。
任务优先级用 P0/P1/P2 标记:
markdown
T1(骨架,P0)→(T2、T3、T4、T5 并行,均为 P0/P1)
→ T6(端到端联通,P0)
→(T7、T8、T9 并行,均为 P0)
→ T10(异常处理,P1)
→ T11(打磨,P2)
P0 是核心主线,必须优先完成。P1 是重要增强,P2 是可选优化。这个优先级体系保证了即使时间不够,核心功能也能交付。
第四层:页面设计文档------定义"长什么样"
UI 页面有独立的布局设计文档,精确到每个模块的布局和状态。侧边栏页面分为四个模块:
css
┌──────────────────────────────────────┐
│ 英文翻译助手 [设置] │ ← Header
├──────────────────────────────────────┤
│ [ 一键翻译 ] │ ← 主按钮
│ [ 下载 Markdown ] [ 重新翻译 ] │ ← 次按钮
├──────────────────────────────────────┤
│ 翻译结果(md-wx 渲染,打字机效果) │ ← Result Area
├──────────────────────────────────────┤
│ 状态:翻译完成 │ ← Status Bar
└──────────────────────────────────────┘
页面还定义了五种状态及其展示内容:空态、加载中、翻译中、完成、失败。每种状态对应什么 UI 元素,在实现前就确定下来,AI 不需要自行猜测。
第五层:project_rules.md------约束 AI 开发行为
这是 SDD 中专门面向 AI 的文档。AI 编码助手需要明确的规则约束,project_rules 定义了:
- 任务范围控制:严格按照 tasks.md 中定义的任务范围执行,不得超出边界
- 单一任务原则:每次只执行一个任务,完成后等待确认再继续
- 禁止自动扩展:不得基于技术架构文档自行扩展任务范围
- 异常处理:任务描述不清晰时应先询问,而不是自行决定
这些规则本质上是对 AI "过度热情"的约束------AI 倾向于在完成主任务后顺便修一个 bug、加一个功能,project_rules 明确禁止这种行为。
SDD + AI 的完整工作流
把五类文档串联起来,得到 SDD 的完整工作流:
markdown
1. 写 proposal → 定义需求边界和 MVP
2. 写 design → 技术选型对比,架构设计
3. 写 tasks → 拆解任务,标记优先级
4. 写页面设计 → 定义 UI 布局和状态
5. 写 project_rules → 约束 AI 编码行为
↓
6. 执行 T1 → 验收 → 确认 → 执行 T2 → ...
每一步都产出文档,文档可记录、可共享、可追溯。AI 编码时以文档为依据,不会因为"聊着聊着就跑偏"。
文档先行解决了什么
Vibe Coding 常见的痛点,SDD 都有对应的解法:
| 痛点 | SDD 解法 |
|---|---|
| AI 产生幻觉,偏离需求 | proposal 定义边界,超出即为幻觉 |
| 关掉窗口,决策逻辑消失 | 文档永久保存,可随时回溯 |
| 范围蔓延,功能越做越多 | tasks 锁定范围,project_rules 禁止扩展 |
| 代码不可回退 | 文档 + Git 双重版本控制,可追溯每次修改 |
| 验收标准不明确 | 每个任务有明确的交付物和验收标准 |
总结
SDD(Specification-Driven Development)不是新概念,但在 AI 编码时代有了新的价值。五类文档------proposal、design、tasks、页面设计、project_rules------形成了一条从需求到代码的完整链路。AI 不再需要猜测需求,开发过程不再依赖聊天窗口的记忆,每个决策都有文档可查。Chrome 英文翻译插件是 SDD 的一个案例,但它展示的方法论适用于任何 AI 辅助开发的项目:先写文档,再写代码,让 AI 在规范的轨道上发挥作用。