3.3 PRD 驱动开发——一份好文档决定了 AI 产出的上限

3 阅读19分钟

模块三:产品设计与前端实战 | 第03讲:PRD 驱动开发——一份好文档决定了 AI 产出的上限

项目:VibeNote 智能笔记
本讲核心:PRD 不是写给老板看的作文,而是 AI 与人类共享的「可执行规格」。文档越清晰,模型越少猜;文档越含糊,代码越多返工。你可以把本讲当作「把模糊想法压成结构化约束」的训练课:练完这一讲,你的 Cursor 对话会明显变短,因为大量共识已经提前写进了文档。


一、为什么 PRD 在 AI 时代反而更重要

有一种流行错觉:「我都用 AI 写代码了,还要 PRD 吗?」答案是:更要。原因是分工变了——人类从「逐行敲代码」转向「定义问题与验收」;AI 从「辅助补全」转向「承担大量实现」。在这种情况下,PRD 就是主接口:接口垃圾,系统必然垃圾。

课程原文「3.3 PRD不是形式主义」指出,真正拉开差距的是能否把业务拆成稳定可执行步骤。对 Vibe Coding,可把 PRD 理解为 Prompt 的上位替代物:Prompt 解决一次对话,PRD 解决持续协作

flowchart LR
  P["PRD 规格"] --> A["AI 生成实现"]
  A --> C["代码产物"]
  C --> T["测试与验收"]
  T -->|缺口| P

二、PRD 质量如何「硬上限」AI 产出

模型不会读心,它只能在你给定的约束空间里搜索合理解。PRD 含糊时,模型会合理猜测——而猜测分布很宽,于是你会看到:

  • 目录结构每次都不一样
  • 组件边界随机漂移
  • 错误处理有时有、有时无
  • API 形状与前端假设不一致

这不是模型「笨」,而是输入熵太高。好的 PRD 做三件事:压缩熵固定术语明确验收

flowchart TB
  subgraph Bad["低质量 PRD"]
    B1["形容词多"]
    B2["边界不清"]
    B3["无验收标准"]
  end
  subgraph Good["高质量 PRD"]
    G1["用户故事 + 非目标"]
    G2["数据契约 + 错误码"]
    G3["Given/When/Then"]
  end
  Bad --> X["宽解空间 返工高"]
  Good --> Y["窄解空间 一次对齐"]

三、面向 AI 的 PRD 必备结构(推荐模板)

下面模板专为 Next.js 14 + TS + Tailwind + shadcn/ui 项目优化,你可原样复制为 docs/prd/vibenote-v3.md

3.1 元信息

  • 背景与目标(1 段)
  • 非目标(列表,至少 5 条)
  • 术语表(中英对照可选)
  • 干系人与决策人(solo 就写你自己)

3.2 用户与场景

  • Persona(1 个主用户即可)
  • Top 3 场景(触发—行动—回报)
  • 关键路径流程图(可用 Mermaid)

3.3 功能需求(按模块)

每条功能用统一骨架:

  • 用户故事
  • 交互说明(含空/错/加载)
  • 数据读写(字段、来源)
  • 权限与安全(如有)
  • 性能与限额(AI 必写)
  • 验收标准(可勾选)

3.4 技术约束

  • 框架版本、目录约定、App Router 还是 Pages(本专栏默认 App Router)
  • 组件库:shadcn/ui;禁止引入第二套 UI 体系除非 RFC
  • 环境变量清单(禁止客户端暴露密钥)

3.5 里程碑与依赖

  • PR 分段策略(对齐模块二)
  • 风险与回滚

四、把 VibeNote V3.0 写成一页「摘要 PRD」(示例段落)

目标:在 V2.0(Markdown + AI 工具栏)基础上,升级到专业级 UI:侧栏导航、编辑器/预览布局、暗色模式、响应式。
非目标:协作编辑、复杂权限、插件系统、移动端离线。
主路径:打开应用 → 选择笔记 → 编辑 → 自动保存成功反馈 → 使用 AI 功能 → 失败可重试。
验收:桌面与手机宽度下主路径无阻断;暗色模式对比度可读;AI 调用有 loading 与错误提示。

这段摘要应放在 PRD 顶部,让任何模型第一眼看见边界


五、可运行代码:从 PRD frontmatter 生成「AI 任务卡」(Node)

把 PRD 元信息结构化,便于脚本化生成给模型的「任务上下文」。

// scripts/prd-task-card.ts
// 运行:npx tsx scripts/prd-task-card.ts

type PrdCard = {
  title: string;
  version: string;
  must: string[];
  wont: string[];
  stack: string[];
};

const vibenoteV3: PrdCard = {
  title: "VibeNote V3.0 UI Upgrade",
  version: "0.1.0-draft",
  must: [
    "侧栏笔记列表 + 选中态",
    "编辑器与预览分区(桌面)/ Tab(移动)",
    "暗色模式切换 persisted",
    "AI 工具栏 loading / error / retry",
  ],
  wont: ["实时协同", "插件市场", "离线冲突合并"],
  stack: ["Next.js 14", "React", "TypeScript", "Tailwind", "shadcn/ui"],
};

function renderPrompt(card: PrdCard): string {
  return [
    `你是资深全栈工程师,按 PRD 实现:${card.title} (${card.version})`,
    `技术栈:${card.stack.join(", ")}`,
    `Must:\n- ${card.must.join("\n- ")}`,
    `Won't(严禁实现):\n- ${card.wont.join("\n- ")}`,
    `输出顺序:文件清单 → 关键组件 props 设计 → 代码`,
  ].join("\n\n");
}

console.log(renderPrompt(vibenoteV3));

这段脚本的价值是:PRD 改动一处,任务卡自动同步,避免你手工复制粘贴漏项。


六、PRD 与提示词工程:分工表

内容放 PRD放单次 Prompt
边界与非目标摘要引用
术语与命名不必重复
当天微调
验收标准勾选片段
调试堆栈

原则:长期不变进 PRD;一次性上下文进 Prompt。

再补一条实践:同一条需求不要在 PRD 与 Prompt 里用两套说法。我见过最常见的事故,是 PRD 写「笔记」,Prompt 写「文档」,结果 AI 生成两套类型名与两套路由。术语统一看似小事,实则是降低模型搜索空间的大杠杆。你可以在 PRD 顶部放 10 行术语表,然后在每次 Prompt 里写「术语以 PRD 为准」,这比反复责骂模型有效得多。


七、写好验收标准:让 AI 「自带测试脑」

差验收:「功能正常」。
好验收(示例):

  • Given 无网络,When 点击 AI 摘要,Then 显示可读错误与重试按钮。
  • Given 首屏加载,When 列表为空,Then 显示空状态与创建引导。
  • Given 切换暗色模式,When 刷新页面,Then 主题保持一致。

技巧:把验收写成 Given/When/Then,模型更容易生成对应的条件渲染与测试思路。


八、数据契约:PRD 里就要写清 DTO

即便你前端暂时 mock,也应在 PRD 写明 Note 的字段:

  • id: string
  • title: string
  • body: string(Markdown)
  • updatedAt: string(ISO)
  • excerpt?: string

否则 AI 会给 content/text/markdown 随机命名,前后端联调时爆炸。


九、风险段:AI 产品必须写的「红线条款」

  • 密钥不得出现在 client bundle
  • 输出内容需标注「AI 生成」
  • 日志不得打印全文笔记(隐私)
  • 提示注入:系统提示固定、用户内容隔离(对齐模块二 route 实践)

十、PRD 评审:15 分钟「红灯问题」清单

  1. 非目标是否足够多?
  2. Must 是否每条都有验收?
  3. AI 功能是否有超时/重试/降级?
  4. 是否定义了组件库边界(shadcn only)?
  5. 是否指定了路由与文件目录约定?

十一、常见失败模式

  1. PRD 写成市场部文案:形容多、规则少。

  2. 把实现细节写死:限制 AI 发挥且易过时;应写「约束」而非「每一行怎么写」。

  3. 缺少错误态:模型默认 happy path。

  4. 多张 PRD 彼此冲突:应用 versionchangelog

  5. 把 PRD 当一次性消耗品:评审完就丢,导致实现期需求偷偷漂移。

  6. 把「技术方案」写进 PRD 正文:方案应可替换,需求应更稳定;否则模型会把临时方案当永恒真理。

  7. 忽略 AI 成本与配额:最后上线发现「功能正确但用不起」。

  8. 没有主路径:PRD 按模块罗列功能,却没有告诉读者用户第一天应该怎么用产品。

这些失败模式不是「写作问题」,而是协作接口设计问题;修好它们,比换一个大模型更划算。


十二、与 AGENTS.md 的协同

把 PRD 链接写进 AGENTS.md:「实现需求前阅读 docs/prd/...」。这让 Cursor 规则与文档形成双保险。


十三、完整 PRD 模板(Markdown 全文可复制)

下面是一份「可直接建文件」的长模板。建议你保存为 docs/prd/vibenote-feature.md,并在每次迭代只改版本号与差异章节。

# PRD:VibeNote(功能名) vX.Y

## 1. 背景与问题
- 当前用户是谁?遇到什么问题?
- 我们为什么现在做(时间窗口)?

## 2. 目标与非目标
### 2.1 目标(可度量)
- ...

### 2.2 非目标(Won't)
- ...

## 3. 用户与场景
### 3.1 Persona
- ...

### 3.2 场景 A/B/C(触发-行动-回报)
- ...

## 4. 范围与优先级(MoSCoW)
| 需求 | MoSCoW | 说明 |
|---|---|---|
|  |  |  |

## 5. 信息架构与页面
- 路由:`/app/...`
- 关键页面说明(含移动端差异)

## 6. 交互与状态
### 6.1 Loading
### 6.2 Empty
### 6.3 Error
### 6.4 Success

## 7. 数据模型与 API
### 7.1 实体字段(TypeScript interface)
### 7.2 API 列表(路径/方法/请求/响应/错误码)

## 8. AI 相关(如有)
- 输入输出边界
- 超时/重试/降级
- 安全:提示注入、敏感信息

## 9. 性能与成本
- P95 目标
- Token/调用上限

## 10. 观测与埋点
- 事件列表

## 11. 验收标准(Given/When/Then)
- ...

## 12. 里程碑与 PR 切分
- PR-1 ...
- PR-2 ...

## 13. 开放问题
- ...

使用建议:不要一次填满所有章节;先填 2/3/5/11,再让 AI 帮你补 7/8 的技术草案,最后人工删风险。


十四、从「需求口语」到「规格语言」:三套改写示例

口语:「笔记列表要好看一点。」
规格:「列表使用 ScrollArea + Button ghost 变体;选中项 aria-current;键盘上下移动焦点。」

口语:「错误提示友好。」
规格:「网络错误展示 Alert destructive;提供重试;日志记录 requestId;不向用户暴露堆栈。」

口语:「AI 快一点。」
规格:「P95 < 3s;超时 8s 中断;重试最多 2 次;退避 300ms/800ms。」

你会发现:规格语言几乎可以直接进提示词,而口语不能。


十五、PRD 版本化:避免「文档分叉」拖死 AI

推荐规则:

  • PRD 文件顶部写 versionlast_reviewed
  • 每次合并主分支前,若实现偏离 PRD,要么改代码,要么改 PRD,并写一行 changelog
  • 禁止「代码已是事实,PRD随便」——否则下一轮 AI 会引用过期规格
flowchart LR
  PRD["PRD vN"] --> Impl["实现"]
  Impl -->|偏离| D{"刻意还是失误"}
  D -->|刻意| PRD2["PRD vN+1"]
  D -->|失误| Fix["修正实现"]

十六、让 PRD 可测试:把「质量属性」写成指标

除了功能,还应写 NFR(非功能需求):性能、可用性、无障碍、国际化准备度。对 VibeNote V3,至少写:

  • 可访问性:焦点环可见;图标按钮有 aria-label;对比度在暗色下仍达标。
  • 响应式md 以下编辑器与预览互斥展示(Tabs);md 以上双栏。
  • 稳定性:保存失败必须提示,不允许静默失败。

这些条目会显著减少「AI 生成的 UI 看起来专业但不专业」的概率。


十七、PRD 与 Figma/原型的关系:谁是源真理?

建议:PRD 是源真理,原型是插图。原因:文本规格更适合 diff 与 AI 解析;原型容易过期。若你有 Figma,请在 PRD 里只放链接 + 「关键尺寸/间距原则」,不要把每个像素写给 AI——否则提示词噪声过大。


十八、多人协作(未来):评论与评审怎么落在 PRD 上

即便你现在是 solo,也建议用 PR 评审 PRD:开 docs/prd 的 MR,评论区只问三类问题——是否服务 H0验收是否可测非目标是否足够。这能训练你把产品思维「版本化」。


十九、把 PRD 接入 Cursor:三条实操规则

  1. .cursor/rulesAGENTS.md 写明:改 UI 必须先 @docs/prd/...
  2. 每次大功能开干前,让 AI 先输出「对齐摘要」:列 Must/Won't/验收。
  3. 代码 PR 描述里贴 PRD 版本号,例如 PRD: vibenote-v3.md#0.3

二十、反面教材:一段「会坑死 AI」的 PRD 片段(不要学)

「做一个很酷的智能笔记,要有 AI,要高级,要体验好,要快。」

这段的问题:无边界、无验收、无数据、无状态机。模型只能自由发挥,然后你骂它「不听话」。不是它不听话,是你没给轨。


二十一、正面教材:同一段需求的「可执行改写」

「VibeNote V3:在 Next.js 14 App Router 下实现桌面双栏(编辑+预览),移动 Tabs 切换;侧栏列表展示最近 50 条笔记标题与更新时间;暗色模式写入 localStorage;AI 摘要按钮在请求期禁用并显示 Loader2;失败用 toastAlert 呈现,可重试;不实现协同编辑。」

这段仍然不完美,但已经包含 布局策略、数据范围、状态与边界——模型成功率会明显提升。


二十二、PRD → 任务拆解:给 AI 的分段指令模板

第一段:「根据 PRD 第 5/6 章,列出需要新增的组件树与 props。」
第二段:「先实现纯 UI(mock 数据),不接 API。」
第三段:「接入真实数据层,补齐错误态。」
第四段:「对照第 11 章验收,补齐缺失。」

这对应人类工程师的「分阶段合并」,也降低一次生成过大 diff 的风险。


二十三、与测试的接口:验收标准如何落到自动化

在 PRD 的 Given/When/Then 下,可加一行 「测试层级建议」:哪些适合单元测试(纯函数)、哪些适合组件测试、哪些只要 e2e 烟测。这样 AI 生成测试时不会乱用 Playwright 打满全站。


二十四、文档驱动开发的节奏:日更 vs 周更

  • 日更:当天实验结论、临时开关、已知缺陷(可放 docs/decisions/)。
  • 周更:PRD 主版本、路线图 MoSCoW。
    不要把实验性结论写进主 PRD 的正文,否则版本噪声会淹没团队(包括未来的你)。

二十五、如何把「用户反馈」回流进 PRD

每次用户访谈结束,提取三条:

  • 新假设 → 进入 PRD「开放问题」
  • 明确需求 → 进入 MoSCoW(谨慎升 Must)
  • 误解点 → 进入交互说明(补文案与引导)

没有回流机制的 PRD,会变成静态文物。


二十六、PRD 与安全的交界:必须写清的「数据分级」

笔记内容可能敏感。PRD 应写:

  • 哪些字段可进日志(通常只 id 与长度)
  • 哪些接口需要鉴权(未来模块)
  • AI 请求是否允许上传全文(若允许,提示用户风险)

这不仅是合规,也是 AI 实现边界


二十七、附录:VibeNote AI Route 的 PRD 片段示例(对齐模块二)

EndpointPOST /api/ai/writing
Body{ mode, title?, content, selection? }
Errors:400 参数;502 模型错误
约束runtime = nodejs;密钥仅服务端

把这段写进 PRD,前端生成 fetch 时代码就不会乱跑。


二十八、从 PRD 到代码仓库的「映射表」(减少 AI 迷路)

再给你一张文件级映射,适合贴在 PRD 附录。它的作用是把「功能章节」映射到「目录」,让模型少猜:

PRD 章节预期落地路径(示例)
布局与导航app/(main)/layout.tsxcomponents/app-sidebar.tsx
笔记列表components/note-list.tsxlib/notes-store.ts
编辑器components/note-editor.tsxcomponents/markdown-preview.tsx
AI 工具栏components/ai-writing-toolbar.tsx
主题components/theme-provider.tsxapp/layout.tsx

注意:路径是约定而非真理;只要你写清楚,AI 就能自洽。最怕的是 PRD 写「实现侧栏」,但仓库里已有 Sidebar.tsxAppSidebar.tsx 两个文件,PRD 却不指定用哪个——这会产生结构性分叉


二十九、长文 PRD 的「阅读顺序」提示:给模型与人类

在 PRD 文首增加 8 行「阅读指南」:

  1. 先读目标与非目标
  2. 再读用户故事与验收
  3. 再读数据模型
  4. 最后读里程碑

这能显著降低「模型读了后半段忘了前半段」的问题——配合 Cursor 的 @ 引用,你也可以分章节 @ 给模型。


三十、用「决策记录」承接 PRD 解释不了的技术权衡

当 PRD 不想膨胀时,把技术权衡放到 docs/adr/0001-xxx.md

  • 背景
  • 决策
  • 后果

例如:「为何暗色模式用 next-themes 而不是手写 class」。ADR 与 PRD 的关系是:PRD 说做什么,ADR 说为什么这样做


三十一、PRD 与 AI 输出的「对齐会议」脚本(10 分钟)

  1. 让 AI 逐条复述 Must/Won't(不允许换词)。
  2. 让 AI 列出它将创建/修改的文件清单。
  3. 人类只纠正偏差,不讨论审美。
  4. 确认验收标准是否将被测试覆盖。

你会发现:10 分钟对齐能省掉10 小时 diff 扯皮


三十二、如何把 PRD 变成「可执行的 JSON Schema」(进阶)

当你的团队更大时,可把 PRD 核心字段结构化存库。下面是一个极简 schema 思路(不必一次落地):

{
  "feature": "vibenote-v3-sidebar",
  "must": ["sidebar", "responsive-nav"],
  "wont": ["realtime-collab"],
  "acceptance": [
    { "id": "A1", "given": "mobile", "when": "open editor", "then": "preview in tab" }
  ]
}

这类结构适合让脚本生成测试用例骨架,也让 AI 更少自由发挥。


三十三、文档写作风格:用动词,不用形容词

PRD 里禁止使用「优雅、炫酷、极致」 unless 你给出可验证定义。例如把「极致性能」改成「首屏 JS 体积不超过 X KB(由 CI 统计)」。形容词是 AI 的毒药,因为模型会各自理解。


三十四、PRD 与国际化:现在不写,将来会哭

即便 VibeNote 先做中文,也建议在 PRD 写「文案集中管理策略」:例如 messages/zh.json 预留结构。否则你会在组件里散落硬编码字符串,AI 每次生成都可能换一种说法,产品语气漂移。


三十五、把 PRD 当作「合同」:变更流程怎么走

小改:直接改 PRD 并 bump patch 版本。
大改:开评审评论,说明「改变了哪条假设」。
任何 Must 变更必须同步验收标准——否则合同失效。


三十六、再谈熵:为什么「越详细越好」也可能是错的

PRD 的目标是降低实现熵,不是堆砌字数。过度细节(例如指定每个 CSS 数值)会让文档脆弱:设计一变,全文过期。正确粒度是:约束足够硬、实现足够松


三十七、给独立开发者的时间表:PRD 要写多久?

经验值:0.5~2 小时写首版 PRD,然后每迭代 15 分钟维护。它比「边聊 AI 边改需求」便宜太多。你若连这半小时都不肯花,本质上是在用返工税补贴懒惰。


三十八、与模块三后续讲次的衔接

第04讲会把 PRD 的「交互与状态」落成 UI 细节;第05讲会把组件树拆到可实现;第07讲用 V3 实战把 PRD 一次跑通。你会看到:同一 PRD,在不同讲次逐层细化,而不是重复劳动。


三十九、PRD 与「生成式编程」的边界:哪些该人类写死

即便 AI 能写代码,以下条目仍建议人类在 PRD 里显式写死,不要轻易交给模型推断:

  • 密钥与合规红线(哪里能放 key、哪里不能打印日志)
  • 主路径优先级(保存比皮肤重要)
  • 错误哲学(静默失败是否允许:通常不允许)
  • 术语表(Note 还是 Document,全项目统一)

相反,以下可以交给 AI 在 PRD 约束下自由发挥:

  • 具体组件拆分与文件命名(只要符合目录约定)
  • Tailwind class 的组合(只要满足无障碍与响应式约束)
  • 单元测试样例(只要覆盖验收标准)

把边界写清楚,你会同时获得 安全速度


四十、从「写 PRD」到「养 PRD」:维护成本怎么控

PRD 最怕一次性写作后束之高阁。推荐每周五 10 分钟做三件事:

  1. 删除已完成的 Must,把新学写进「结论」段
  2. 把 Won't 里被频繁质疑的条目拿出来,决定是继续不做还是升级假设
  3. 对照代码目录,删掉映射表里已不存在的路径

养 PRD 的本质,是养团队的共享记忆;solo 时,是养未来自己的记忆


四十一、复盘清单

  • 你已有 PRD 文件且链接进 AGENTS.md 吗?
  • Must 是否每条都能映射到 Given/When/Then?
  • Won't 是否足够「令人心疼」?
  • 是否为 AI 功能写了超时/重试?

四十二、把 PRD 当作「上下文压缩包」:给未来自己留一条路

六个月后的你很可能忘记当初为什么拒绝做协同编辑。PRD 里一行 Won't,配上两句「替代验证手段」,能避免你未来在兴奋中推翻正确决策。更进一步,你可以在 PRD 末尾维护「已证伪假设」列表:曾经相信什么、被什么证据推翻、因此砍掉了哪些功能。对 AI-native 团队来说,这份列表和代码同样值钱——因为模型没有组织记忆,文档就是组织记忆的外存


四十三、再补一张信息流转图:PRD 在系统里的位置

flowchart TB
  U["用户/市场信号"] --> PRD["PRD 规格"]
  PRD --> Rules["AGENTS.md / Cursor Rules"]
  PRD --> Prompt["任务 Prompt"]
  Rules --> Code["实现"]
  Prompt --> Code
  Code --> Metrics["指标与日志"]
  Metrics --> U

四十四、思考题

  1. 你上一份 PRD 里,哪三条信息缺失导致 AI 返工?
  2. 如何把 PRD 与 Git 分支命名关联(例如 feat/v3-sidebar)?
  3. 若 PRD 与模块二 Workflow 冲突,以谁为准?
  4. 你会如何把「暗色模式」从形容词需求改写成 3 条可验收标准?
  5. 如果你的 PRD 与实现已经偏离,你会先改文档还是先改代码?依据是什么?
  6. 请为你自己的项目写一段「反面教材 PRD」,再立刻改写为可执行版本,对比差异。把对比结果贴进仓库 docs/ 作为团队纪律样本,避免同样错误重复发生,让组织记忆真正沉淀下来,而不是散落在聊天记录里一天后就找不到。

四十五、下讲预告

当你习惯用 PRD 约束 AI,你会获得一种很朴素的工程快感:争论发生在文档层,合并发生在代码层。文档上的分歧便宜,代码里的分歧昂贵。下一讲我们会进入用户真正摸得着的层面:UI 与 UX。你会学到如何把 PRD 里的「状态机」翻译成界面上的可理解反馈,以及为什么 shadcn/ui 不是「皮肤」,而是一套让 AI 更不容易翻车的组件契约。

第04讲聚焦 UI 与 UX 差别:为什么页面好看却不好用?我们将系统讲 Loading / Empty / Error、设计原则,并把 shadcn/ui 放进工程语境里。


参考:课程原文 课程内容/3.3 PRD不是形式主义:它决定了AI产出的上限.md(仓库内路径;若你本地另有 reference/advanced/03-prd-doc-driven.md,可作为补充阅读)。

最后送你一句在团队里最好用的问法:「如果明天只能实现 PRD 里的一条 Must,你选哪条?」能答上来,说明你真的懂优先级;答不上来,说明 PRD 还只是愿望合集——请先回到上一讲的 MoSCoW 与 Won't。