模块三:产品设计与前端实战 | 第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: stringtitle: stringbody: string(Markdown)updatedAt: string(ISO)excerpt?: string
否则 AI 会给 content/text/markdown 随机命名,前后端联调时爆炸。
九、风险段:AI 产品必须写的「红线条款」
- 密钥不得出现在 client bundle
- 输出内容需标注「AI 生成」
- 日志不得打印全文笔记(隐私)
- 提示注入:系统提示固定、用户内容隔离(对齐模块二 route 实践)
十、PRD 评审:15 分钟「红灯问题」清单
- 非目标是否足够多?
- Must 是否每条都有验收?
- AI 功能是否有超时/重试/降级?
- 是否定义了组件库边界(shadcn only)?
- 是否指定了路由与文件目录约定?
十一、常见失败模式
-
PRD 写成市场部文案:形容多、规则少。
-
把实现细节写死:限制 AI 发挥且易过时;应写「约束」而非「每一行怎么写」。
-
缺少错误态:模型默认 happy path。
-
多张 PRD 彼此冲突:应用
version与changelog。 -
把 PRD 当一次性消耗品:评审完就丢,导致实现期需求偷偷漂移。
-
把「技术方案」写进 PRD 正文:方案应可替换,需求应更稳定;否则模型会把临时方案当永恒真理。
-
忽略 AI 成本与配额:最后上线发现「功能正确但用不起」。
-
没有主路径: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 文件顶部写
version与last_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:三条实操规则
- 在
.cursor/rules或AGENTS.md写明:改 UI 必须先@docs/prd/...。 - 每次大功能开干前,让 AI 先输出「对齐摘要」:列 Must/Won't/验收。
- 代码 PR 描述里贴 PRD 版本号,例如
PRD: vibenote-v3.md#0.3。
二十、反面教材:一段「会坑死 AI」的 PRD 片段(不要学)
「做一个很酷的智能笔记,要有 AI,要高级,要体验好,要快。」
这段的问题:无边界、无验收、无数据、无状态机。模型只能自由发挥,然后你骂它「不听话」。不是它不听话,是你没给轨。
二十一、正面教材:同一段需求的「可执行改写」
「VibeNote V3:在 Next.js 14 App Router 下实现桌面双栏(编辑+预览),移动 Tabs 切换;侧栏列表展示最近 50 条笔记标题与更新时间;暗色模式写入
localStorage;AI 摘要按钮在请求期禁用并显示Loader2;失败用toast或Alert呈现,可重试;不实现协同编辑。」
这段仍然不完美,但已经包含 布局策略、数据范围、状态与边界——模型成功率会明显提升。
二十二、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 片段示例(对齐模块二)
Endpoint:POST /api/ai/writing
Body:{ mode, title?, content, selection? }
Errors:400 参数;502 模型错误
约束:runtime = nodejs;密钥仅服务端
把这段写进 PRD,前端生成 fetch 时代码就不会乱跑。
二十八、从 PRD 到代码仓库的「映射表」(减少 AI 迷路)
再给你一张文件级映射,适合贴在 PRD 附录。它的作用是把「功能章节」映射到「目录」,让模型少猜:
| PRD 章节 | 预期落地路径(示例) |
|---|---|
| 布局与导航 | app/(main)/layout.tsx、components/app-sidebar.tsx |
| 笔记列表 | components/note-list.tsx、lib/notes-store.ts |
| 编辑器 | components/note-editor.tsx、components/markdown-preview.tsx |
| AI 工具栏 | components/ai-writing-toolbar.tsx |
| 主题 | components/theme-provider.tsx、app/layout.tsx |
注意:路径是约定而非真理;只要你写清楚,AI 就能自洽。最怕的是 PRD 写「实现侧栏」,但仓库里已有 Sidebar.tsx 与 AppSidebar.tsx 两个文件,PRD 却不指定用哪个——这会产生结构性分叉。
二十九、长文 PRD 的「阅读顺序」提示:给模型与人类
在 PRD 文首增加 8 行「阅读指南」:
- 先读目标与非目标
- 再读用户故事与验收
- 再读数据模型
- 最后读里程碑
这能显著降低「模型读了后半段忘了前半段」的问题——配合 Cursor 的 @ 引用,你也可以分章节 @ 给模型。
三十、用「决策记录」承接 PRD 解释不了的技术权衡
当 PRD 不想膨胀时,把技术权衡放到 docs/adr/0001-xxx.md:
- 背景
- 决策
- 后果
例如:「为何暗色模式用 next-themes 而不是手写 class」。ADR 与 PRD 的关系是:PRD 说做什么,ADR 说为什么这样做。
三十一、PRD 与 AI 输出的「对齐会议」脚本(10 分钟)
- 让 AI 逐条复述 Must/Won't(不允许换词)。
- 让 AI 列出它将创建/修改的文件清单。
- 人类只纠正偏差,不讨论审美。
- 确认验收标准是否将被测试覆盖。
你会发现: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 分钟做三件事:
- 删除已完成的 Must,把新学写进「结论」段
- 把 Won't 里被频繁质疑的条目拿出来,决定是继续不做还是升级假设
- 对照代码目录,删掉映射表里已不存在的路径
养 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
四十四、思考题
- 你上一份 PRD 里,哪三条信息缺失导致 AI 返工?
- 如何把 PRD 与 Git 分支命名关联(例如
feat/v3-sidebar)? - 若 PRD 与模块二 Workflow 冲突,以谁为准?
- 你会如何把「暗色模式」从形容词需求改写成 3 条可验收标准?
- 如果你的 PRD 与实现已经偏离,你会先改文档还是先改代码?依据是什么?
- 请为你自己的项目写一段「反面教材 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。