在 Vibe Coding 工作流中,需求文档是你与 AI 之间唯一的契约:它决定了 AI 是"精准实现你的意图",还是"凭感觉自由发挥"。一份高质量的需求文档,是投入产出比最高的一件事——写它花掉的半小时,往往能省下后面数小时甚至数天的返工。本教程在《VibeCoding 从 MD 开始》的基础上,深入回答三个问题:好需求文档的标准是什么、由哪些要素组成、如何一步步写出来,并给出通用模板与完整实战示例。

前置教程

如想快速开始学习本教程,你可能需要先完成以下前置教程:

1. 需求文档是 Vibe Coding 的胜负手

1.1 需求文档是意图的唯一载体

传统开发中,需求文档只是开工前的"一张纸",真正的意图通过代码、评审、沟通层层传递。而在 Vibe Coding 中,AI 看不到你的头脑,也读不到你的聊天记录——需求文档是它理解你意图的唯一输入。输入的质量直接决定输出的质量,这是计算科学里"垃圾进、垃圾出"(Garbage In, Garbage Out)原则最直白的体现。

举一个最常见的例子。给 AI 一句"帮我做一个登录功能",它会默认选择最常见的技术方案:可能是用户名密码,可能是手机验证码;可能返回 Token,也可能用 Session;可能存数据库,也可能写死数组。你得到的是一份"通用答案",而不是"你要的东西"。

在 Vibe Coding 里,需求文档不是流程文档,而是工程制品。你写清楚一分,AI 就少猜十分。

1.2 模糊需求的双输循环

需求含糊时,Vibe Coding 会陷入典型的返工循环:

graph LR A[一句话需求] --> B[AI 只能猜测意图] B --> C[实现偏离预期] C --> D[反复返工] D --> B E[结构化需求文档] --> F[AI 精准实现] F --> G[一次通过验收] style A fill:#fadbd8,stroke:#c0392b,stroke-width:2px style B fill:#ffecd6,stroke:#e67e22,stroke-width:2px style C fill:#fadbd8,stroke:#c0392b,stroke-width:2px style D fill:#fadbd8,stroke:#c0392b,stroke-width:2px style E fill:#d5f5e3,stroke:#27ae60,stroke-width:2px style F fill:#d6eaf8,stroke:#1a6b8a,stroke-width:2px style G fill:#d5f5e3,stroke:#27ae60,stroke-width:2px

上方是"双输循环":你气得够呛,AI 觉得委屈,双方都在消耗;下方是"一次通过":AI 拿到明确指令,你拿到符合预期的实现。

1.3 好需求文档的三个标准

判断一份需求文档好不好,不需要凭感觉,只需对照三个标准:

标准 含义 不合格的表现
可理解 人和 AI 读起来都不含糊,无歧义 "界面要好看一点""体验要流畅"
可执行 每条需求都能转化为具体的代码行为 "实现智能推荐"但没有规则说明
可验收 有客观的判定标准,能验证"做完了" "性能要快"但没有数字指标

后续章节的所有要素与技巧,本质上都是在为这三个标准服务。写需求时不断自问三句话:AI 能读懂吗?AI 知道怎么做吗?做完怎么证明? 三句都答得上,文档就是合格的。

2. 好的需求文档的组成要素

2.1 背景与目标

背景用一两句话说清"要解决什么问题",目标写清"做到什么程度才算成功"。目标必须可量化,否则无从验收。

写法 示例
做一个番茄钟,帮助用户管理时间
做一个网页番茄钟,无需登录、打开即用,单次专注结束后给出明确提醒,帮助用户按 25 分钟工作 / 5 分钟休息的节奏工作

第二行既说明了问题(工作容易失去节奏),也给出了可感知的目标(明确提醒、开箱即用),AI 据此能判断功能边界。

2.2 用户与使用场景

写清楚"谁在用、在哪里用、为什么用"。用户画像和场景看似不涉及代码,实际上强烈影响 AI 对交互细节与边界的取舍:

  • 谁在用:程序员、学生,还是老年用户?决定字号、操作复杂度。
  • 在哪里用:桌面浏览器常驻,还是手机锁屏状态?决定后台行为与提醒方式。
  • 为什么用:解决什么痛点?决定哪些功能是必须的,哪些是冗余的。

2.3 功能需求

功能需求是文档的主体,推荐用编号(FR-1、FR-2)逐条列出,每条遵循"输入-处理-输出"结构:

字段 说明 示例
编号 唯一标识,便于引用与追踪 FR-1
名称 一句话概括功能 番茄倒计时
输入 触发条件与参数 点击"开始",时长 25 分钟
处理 内部规则与逻辑 每秒递减,到 0 自动停止并提醒
输出 界面与数据结果 显示剩余时间,播放提示音

功能需求是 AI 生成代码的直接依据。逐条编号还有一个好处:对话中只需说"FR-3 再改一下",AI 就能精确定位,不用复述整段需求。

2.4 非功能需求

非功能需求描述"系统应该多好",是 AI 最容易忽略、也最能拉开实现差距的部分。常见四类:

类别 说明 示例
性能 响应速度、资源占用 首屏加载不超过 1 秒
安全 数据保护、鉴权、防注入 密码使用 bcrypt 加密存储
兼容 浏览器、系统、设备范围 兼容 Chrome 与 Edge 最新两个大版本
可维护 代码结构、日志、可配置 数据库名统一为 ai_ml_tutorial,配置集中在 config.py

不写非功能需求,AI 就会用"最简单能跑"的方式实现:明文存密码、单线程阻塞、不处理并发。加上一行约束,实现质量立刻不同。

2.5 技术约束

技术约束划定 AI 的"活动范围",包括技术栈、数据库、已有代码与兼容要求:

  • 技术栈:语言、框架、版本(如 Python 3.10 + FastAPI)
  • 数据存储:数据库类型、表名、字段约定
  • 复用与兼容:必须对接的现有模块、不得破坏的旧接口
  • 部署形态:单文件、容器、静态托管等

约束写清楚后,AI 不会擅自引入你没装的环境或依赖,实现才能真正落地。

2.6 验收标准

验收标准把"做完了"定义成客观可测的断言,是三个标准中"可验收"的直接体现:

## 6. 验收标准

- [ ] 设置 25 分钟,倒计时结束后自动响铃
- [ ] 刷新页面后剩余时间不丢失
- [ ] 完成 3 个番茄,统计页显示 3

每条验收标准都应当能通过运行应用来验证,而不是凭观感判断。把验收标准交给 AI,它就能自我检查、自我修正,极大减少来回对话。

2.7 边界与例外

边界与例外描述"不正常的输入和场景",这是需求文档中最容易被省略、却最常导致返工的部分:

  • 空数据:无记录时界面如何显示
  • 异常输入:非法参数、超长文本、重复提交
  • 极端场景:倒计时归零、断网、杀进程、多标签页
  • 错误处理:失败时提示什么、如何恢复
graph LR A[好的需求文档] --> B[背景与目标] A --> C[用户与场景] A --> D[功能需求] A --> E[非功能需求] A --> F[技术约束] A --> G[验收标准] A --> H[边界与例外] style A fill:#d6eaf8,stroke:#1a6b8a,stroke-width:2px style B fill:#d5f5e3,stroke:#27ae60,stroke-width:2px style C fill:#d5f5e3,stroke:#27ae60,stroke-width:2px style D fill:#ffecd6,stroke:#e67e22,stroke-width:2px style E fill:#ffecd6,stroke:#e67e22,stroke-width:2px style F fill:#ebdef0,stroke:#8e44ad,stroke-width:2px style G fill:#fdebd0,stroke:#d35400,stroke-width:2px style H fill:#fadbd8,stroke:#c0392b,stroke-width:2px

七大要素各有分工:前两个定方向,功能与非功能定内容,技术约束定边界,验收标准与边界例外保证"做得出、验得准"。

3. 把需求写清楚的核心技巧

要素规定了"写什么",本节解决"怎么写"。以下技巧都是为了让 AI 少猜、不猜。

3.1 用"输入-处理-输出"描述功能

把每个功能拆成三段式描述,AI 就能直接映射到函数或接口:

FR-2:倒计时
- 输入:开始时间与目标时长(分钟)
- 处理:每秒递减剩余秒数;归零时停止并触发提醒;期间支持暂停与继续
- 输出:界面实时显示"分:秒"格式的剩余时间

有了明确的三段式,AI 无需追问"倒计时到底要干什么"就能动手写代码。

3.2 每条需求只做一件事

单一职责不只适用于代码,同样适用于需求条目。一条需求混合多个动作,AI 容易顾此失彼:

写法 示例 问题
支持用户注册、登录和找回密码 三个动作揉在一起,实现和验收都难
FR-1 用户注册;FR-2 用户登录;FR-3 找回密码 每条独立实现、独立验收、独立修改

需求条目拆得越小,AI 的上下文负担越轻,出错概率越低。

3.3 用数据与示例消除歧义

"时间""列表""状态"这类词在不同人眼里含义不同。给 AI 具体的数据结构、字段表和示例值,歧义就会消失:

统计接口返回格式:

| 字段 | 类型 | 说明 |
|------|------|------|
| total | integer | 今日完成番茄数 |
| date | string | 日期,格式 YYYY-MM-DD |

再补一个最小示例(如 {"total": 3, "date": "2026-08-21"}),AI 对字段类型与格式的理解就不会跑偏。

3.4 验收标准要可测试

"快""好看""体验好"是不可测试的主观词,AI 无法据此自检。把每个主观词换成可测量的断言:

不可测试 可测试
页面加载要快 首屏加载不超过 1 秒
提醒要及时 倒计时归零后 1 秒内播放提示音
界面要友好 未登录时点击收藏,提示"请先登录"而非无响应

一条需求文档的水平,看验收标准的写法就知道了。写得出可测试的验收标准,说明你想清楚了"到底要什么"。

3.5 为 AI 提供参考锚点

孤立的需求文档让 AI 无从对齐现有代码。给出参考锚点,AI 就能沿着一致的方向扩展:

  • 链接现有代码或文档:参考现有实现:api/user.md
  • 给出项目约定:指向 CLAUDE.mdREADME.md、数据库 schema.sql
  • 给出同类实现:粘贴一段期望的示例代码或接口,作为风格基准

参考锚点是"可理解"标准的加速器——文档不必把每件事写全,让 AI 自己去看锚点即可。

4. 完整模板与实战示例

4.1 通用需求文档模板

把七大要素组织为可直接复用的模板:

# 项目名称需求文档

## 1. 背景与目标

一句话说明要解决的问题,以及达到什么可量化的效果。

## 2. 用户与使用场景

- 用户:谁在使用
- 场景:在哪里、什么条件下使用

## 3. 功能需求

### 3.1 功能名称

- FR-1:功能描述(输入 → 处理 → 输出)
- FR-2:功能描述(输入 → 处理 → 输出)

## 4. 非功能需求

- 性能:数字化的指标
- 安全:数据保护与鉴权要求
- 兼容:支持的环境范围
- 可维护:结构、配置与日志约定

## 5. 技术约束

- 技术栈与版本
- 数据存储与字段约定
- 必须复用的现有代码

## 6. 验收标准

- [ ] 可测试的断言一
- [ ] 可测试的断言二

## 7. 边界与例外

- 空数据、异常输入、极端场景的处理

4.2 实战示例:把一句需求写成完整文档

假设你只有一句原始想法:"帮我做一个番茄钟。"直接把它交给 AI,得到的往往是通用模板堆砌的平庸实现。花二十分钟写成下面的文档,情况完全不同:

# 番茄钟网页应用需求文档

## 1. 背景与目标

很多人在电脑前连续工作容易失去节奏。做一个开箱即用的网页版番茄钟:无需登录、打开即用,按 25 分钟工作 / 5 分钟休息的节奏计时,帮助用户保持专注。

## 2. 用户与使用场景

- 用户:需要定时休息的程序员、自媒体创作者
- 场景:浏览器标签页常驻,切换工作窗口时倒计时仍然准确

## 3. 功能需求

### 3.1 计时

- FR-1:默认工作 25 分钟、休息 5 分钟,可在设置面板自定义时长
- FR-2:倒计时精确到秒,刷新页面后剩余时间不丢失
- FR-3:支持开始、暂停、继续、重置

### 3.2 提醒

- FR-4:阶段结束时播放系统提示音,并在页面标题栏显示"时间到"
- FR-5:工作与休息阶段自动交替,可手动跳过当前阶段

### 3.3 统计

- FR-6:本地记录每日完成的番茄数,按周展示统计

## 4. 非功能需求

- 性能:主页面首屏加载不超过 1 秒,切换标签页无卡顿
- 安全:数据仅存浏览器 localStorage,不上传服务器
- 兼容:兼容 Chrome、Edge 最新两个大版本

## 5. 技术约束

- 技术栈:原生 HTML + CSS + JavaScript,不使用框架
- 无需后端,纯前端应用,单文件可部署
- 数据存储:仅使用 localStorage

## 6. 验收标准

- [ ] 设置 25 分钟工作,倒计时结束后自动响铃并进入休息
- [ ] 刷新页面后剩余时间恢复
- [ ] 完成 3 个番茄,统计页显示 3
- [ ] 无网环境直接打开 HTML 文件可正常使用

## 7. 边界与例外

- 倒计时为 0 立即结束,不出现负值
- 页面在后台标签页时倒计时仍准确(用时间戳差值而非 setInterval 计数)
- 重复点击"开始"不会创建多个并行计时器

对比前后的差别:原始一句话没有目标、没有验收、没有边界,AI 只能猜测;完整文档让 AI 一次拿到全部决策信息,从"做出来"变成"做对"。

4.3 如何把文档交给 AI

文档写好之后,交给 AI 的方式同样影响结果:

  • 一次给全:把完整文档作为首轮输入,让 AI 先通读再动手,避免边做边问。
  • 按块推进:功能多时按 FR 分批实现,每批一个验收循环,不让单次上下文过长。
  • 验收驱动修正:运行后把"哪条验收标准没过、实际表现是什么"反馈给 AI,比笼统的"不对"有效得多。
  • 沉淀回文档:AI 的合理决策与你的取舍,同步记入文档,让文档始终是唯一事实来源。

5. 常见误区与最佳实践

5.1 八个常见误区

误区 典型表现 正确做法
只列功能清单 没有背景与目标 先写清"为什么做、做到什么程度"
目标不可量化 "提升用户体验" 换成可测量的指标
忽略非功能需求 只有"能跑就行" 补上性能、安全、兼容约束
验收标准含糊 "体验要流畅" 写成可测试的数字断言
一次塞入全部需求 数十条挤在一段 编号分块,按优先级推进
不给参考锚点 与现有代码脱节 链接已有实现与项目约定
把猜测当需求 自己都不确定就写死 不确定处标注"待确认"
写完不更新 文档与实现脱节 每次迭代同步修订文档

5.2 让需求文档持续演进

需求文档不是一次性产物,而是随项目演进的活文档。实践中推荐两条纪律:

  • 决策记录:每个影响实现的关键决策(改方案、加字段、调边界)追加到文档末尾的决策记录中,供后续 AI 读取。
  • 文档与代码同改:AI 改完代码,顺手把文档一并更新;你改文档,也意味着接下来要动代码。两者脱节是返工的根源。
## 决策记录

- 2026-08-21:统计存储从 IndexedDB 简化为 localStorage,降低实现复杂度
- 2026-08-21:休息阶段提醒改为静音震动,避免打扰周围同事

6. 总结

6.1 核心要点回顾

  • 需求文档是意图的唯一载体:Vibe Coding 中 AI 只能读文档,输入质量决定输出质量。
  • 三大标准:可理解、可执行、可验收,是判断文档好坏的尺子。
  • 七大要素:背景与目标、用户与场景、功能需求、非功能需求、技术约束、验收标准、边界与例外。
  • 五大技巧:输入-处理-输出描述、单一职责、数据消歧、可测试验收、参考锚点。
  • 文档持续演进:配合决策记录与文档同改,让需求文档始终是唯一事实来源。

6.2 常见问题与解答

问:需求文档要写到多详细才算"够"?

答:没有一个固定字数,判断标准是三个"自问":AI 能读懂吗?AI 知道怎么做吗?做完怎么证明?三问都通过即可,不必追求面面俱到。小型工具可以一张 A4 纸,复杂系统则要逐模块细化。

问:非功能需求对 AI 编程真的重要吗?

答:非常重要。AI 的默认实现是"最简单能跑",你不写性能、安全、兼容约束,它就用明文密码、单线程、不处理并发。非功能需求是拉开"能用"与"好用"差距的关键。

问:需求文档和提示词是什么关系?

答:需求文档是持久的、面向整个项目的输入;提示词是一次性的、面向单个任务的指令。实践中的做法是:需求文档沉淀规范与约束,提示词引用文档的编号片段驱动具体功能(如"按 FR-3 实现,参考文档第 4 章约束")。

问:验收标准会不会写得太死,限制了 AI 的发挥?

答:恰恰相反。验收标准约束的是"结果",不约束"实现方式"。AI 可以自由选择算法、数据结构与代码组织,只要满足可测试的验收断言即可。限制发挥的是模糊需求,而不是清晰的验收标准。