写 PRD 这件事,我前后做了八年多,带过新人,也被新人带过。最荒诞的一次是:我熬到凌晨两点写完一份三十页的需求文档,第二天评审会开场十分钟就被问穿——"用户连续点两次提交会怎样"、"这个字段为空的时候页面长什么样"、"你说的'尽快返回'是几百毫秒还是三秒"——三个问题我一个都答不上来。那一刻我才意识到,PRD 写得长不等于写得清楚,字数从来不是文档的护城河,把别人脑子里的问号提前消灭掉才是。
后来我把这些年踩过的坑一条条记在本子上,慢慢收敛成五条自己反复验证过的写作规则。它们不是那种挂在墙上的方法论框架,更像五道出厂质检关口:每写完一份 PRD,我都会拿这五条从头过一遍,过不去的就回去改。这篇文章就把这五条完整拆开讲清楚——每一条解决的是什么问题、具体怎么落地、落地时最容易在哪一步走偏,中间穿插我自己在评审现场被追问的真实场景、可以直接抄走的文档骨架、需求条目的标准写法,以及一份评审会高频问题速查表。刚接手第一个需求的准产品、写了几年文档但总被研发追问的老手、甚至被拉来临时写需求的运营同学,应该都能从中拿到能立刻用上的东西。
1. 写之前先想清楚:PRD 到底在解决谁的什么问题
1.1 一份文档的三类读者,三种完全不同的读法
很多人写 PRD 的默认姿势是"我要把这件事讲明白",于是从背景写到价值、从愿景写到规划,洋洋洒洒几千字。问题在于,PRD 从来不是给自己看的自传,它是一份多读者、多用途的协作文档。同一份文档,研发、测试、设计三拨人翻开的姿势完全不同。
研发关心的核心就一句话:边界在哪、我该做多少。他们会逐字抠"支持多选"是不是意味着要支持全选、是不是要支持跨页选择、选完之后能不能批量撤销。你少写一个字,他们就得靠猜;猜的成本,最后会以返工的形式还给你。
测试关心的则是另一套东西:怎么证明你做对了。他们需要的是可判定真伪的验收条件——什么输入产生什么输出、什么情况下报什么错、哪些场景必须覆盖。你写"体验要流畅",测试只能干瞪眼;你写"列表数据超过 200 条时启用分页,每页 20 条",他们立刻能列出七八个用例。
设计、运营、客服这些角色读的是第三层:这东西长什么样、出了事怎么解释。他们要的是界面结构、文案口径、以及对外的解释边界。很多线上客诉的根源不在代码,而在于客服手里没有一份能说清楚"为什么会出现这种情况"的说明。
我现在的做法是在文档开头放一段三十字以内的"一句话说明",然后针对三类读者各留一个入口:给研发的规则清单、给测试的验收矩阵、给运营的文案与话术附录。同一份文档,三条阅读路径,谁都不必从头读到尾。
1.2 我为什么把大而全的模板砍成了三段式
刚入行那会儿,我收集过各种"完整版 PRD 模板",动辄二十几个章节,从项目背景、市场分析、竞品对标一直写到风险评估、里程碑规划。用了半年我就放弃了,原因很实在:这些章节大部分内容不会有人读第二遍,而真正会被反复查的那几页,往往只占全文的十分之一。
后来我把文档结构收敛成三段式,一直用到现在:
| 段落 | 内容定位 | 篇幅占比 | 谁最常读 |
|---|---|---|---|
| 第一段:摘要层 | 一句话说明、目标与非目标、核心指标、关键约束 | 约 10% | 所有人,尤其决策者 |
| 第二段:规则层 | 流程、状态、字段、交互规则、异常处理 | 约 70% | 研发、设计 |
| 第三段:验收层 | 验收条件清单、埋点定义、上线检查项、附录 | 约 20% | 测试、运营、数据 |
砍掉的那些章节去哪了?市场分析和竞品对标进立项材料,里程碑规划进项目管理系统,风险评估进评审纪要。文档的职责是把"要做成什么样"讲成唯一解,不是把所有相关信息塞进一个文件。这个取舍背后有个很朴素的判断:一份文档的价值,和它被查阅的频率成正比,和它的厚度基本无关。
顺带说一个很多人忽略的点:摘要层里"非目标"这一栏,我放在最显眼的位置,甚至排在目标前面。理由在下一节展开。
2. 五条真正改变工作方式的写作课程
2.1 第一条:先写清楚"不做什么",再写"做什么"
这是我吃过最大亏的一条。早期的文档我只会写"本期要实现 A、B、C",结果做到一半,各方对"顺带做一下 D"的理解完全分裂:研发觉得 D 是 A 的自然延伸,顺手就做了;设计觉得 D 不在范围内,没出图;测试觉得 D 没写进文档,不测。最后 D 变成一个没有设计稿、没有用例、还上了线的功能,出了问题谁都说不清是谁的责任。
"不做什么"这一栏的作用,是把范围边界显性化。写法上我有个固定句式,效果比散着写强很多:
本期不做:多端同步、历史数据回溯、批量导入。原因分别是——多端同步依赖账号体系改造(排在下个季度)、历史数据回溯涉及存量数据清洗(成本约为本期的 1.5 倍)、批量导入暂无明确使用场景(等三个以上业务方提出再评估)。
一句话里塞了三样东西:不做什么、为什么不做、什么条件下会做。第三点特别关键,它把"否决"变成了"有条件的延后",评审时对方的接受度会高很多,也不至于让提需求的人觉得被敷衍。
还有一个隐藏收益:写非目标的过程,本身就是一次自查。我经常在写这一栏的时候发现自己对需求的理解有洞——比如想写"本期不做消息推送",写到一半才反应过来,用户完成核心动作后的反馈完全没有着落,这个"不做"其实是个伪命题。
注意:非目标不是甩锅清单。写"不做"必须配上理由和触发条件,否则它只会变成下一轮扯皮的起点。
2.2 第二条:需求要写成可验证的断言,不是美好愿望
翻开很多文档,你会看到这样的句子:"页面加载速度要快"、"交互要顺畅"、"尽量降低用户操作成本"、"保证数据准确"。这些话没有一句是错的,也没有一句是有用的——因为它们无法被判定真伪。研发照着自己的理解做,测试照着感觉测,上线后用户说慢,谁都没法证明自己错了。
我的改法是:所有模糊形容词,一律翻译成"条件 + 阈值 + 观测方式"三段式。
| 原始写法 | 改造后 | 改造逻辑 |
|---|---|---|
| 页面加载要快 | 弱网环境(下行 1Mbps、延迟 200ms)下首屏可见内容不超过 2 秒,超过则展示骨架屏 | 补环境、补阈值、补降级方案 |
| 搜索要准 | 关键词完全匹配的结果排在部分匹配之前;无结果时展示空态文案与三条推荐词 | 把"准"拆成排序规则和空态规则 |
| 操作要顺畅 | 从列表页到详情页返回时,保留原滚动位置与筛选条件 | 把主观感受落成可复现的交互行为 |
| 保证数据准确 | 每日对账任务在次日 06:00 前完成,差异记录写入异常表并触发告警 | 补时间点、补落库位置、补告警方式 |
这张表我至今留在笔记本第一页。它的价值不在格式,而在强迫自己回答一个问题:如果我是测试,我要怎么证明这条需求被满足了?答不上来的,说明还没想清楚。
阈值怎么定?我的经验是能参考历史数据就别拍脑袋。比如"接口响应时间",先去翻现有同类接口的线上分位值,取 P95 作基线再上浮 20% 作为新需求的初版目标,然后拿着这个数字去和研发对一遍可行性。凭空调一个"200 毫秒"出来,除了让研发当场翻脸,没有任何好处。
2.3 第三条:用状态和事件描述流程,别只画流程图
流程图是个好东西,但它有个致命缺陷:画得下正常路径,画不下所有分支。一个四步流程,画出来清清爽爽,实际上每个节点都有成功、失败、超时、取消、重试五种可能,画全了就是一张蜘蛛网,没人看得懂。
我后来改用"状态 + 事件 + 守卫条件"这套描述方式,思路更接近工程实现,研发读起来也顺。以最常见的订单类场景为例:
状态集合:待支付 / 支付中 / 已支付 / 已取消 / 已退款 事件与迁移: - 创建订单(无 → 待支付) - 发起支付(待支付 → 支付中) 守卫:订单未超时 且 无进行中的支付请求 - 支付回调成功(支付中 → 已支付) 副作用:写入支付流水、发送通知、扣减库存 - 支付回调失败(支付中 → 待支付) 副作用:记录失败原因、允许重试,重试上限 3 次 - 超时未支付(待支付 → 已取消) 守卫:创建时间距今超过 30 分钟 - 用户主动取消(待支付 → 已取消) 守卫:状态为待支付 - 已支付后发起退款(已支付 → 已退款)这么写有三个好处。第一,状态是封闭的,一共五态,穷举得完,研发不用猜"还有没有别的状态"。第二,每个迁移都挂了触发事件和守卫条件,等于把 if 条件写清楚了。第三,副作用单列,谁负责发通知、谁负责扣库存,一目了然,避免出现"我以为你会发"的空档。
对于并发场景,光写状态还不够,得补上幂等和互斥的说明。比如"同一订单在支付中状态下再次收到支付请求,直接返回当前状态,不重复发起",这句话看着简单,能省掉上线后一整轮排查。
实操心得:状态机写完,我通常会请研发花十分钟过一遍,重点问一句"有没有哪个状态是你实现时觉得多余或者缺了的"。多数时候他们会补充两三个我漏掉的中间态,比如"退款中",这类补充越早越好。
2.4 第四条:异常路径和边界条件才是文档的主角
新人文档的通病是只写阳光大道:用户点了按钮、数据正常返回、流程顺利走完。可线上故障从来不发生在阳光大道上。我统计过自己经手的问题单,超过七成集中在这几类:空数据、超长内容、并发操作、网络中断、权限不足、数据不一致。
所以我现在的写法是反过来的:先把正常路径用三五行写完,剩下的篇幅全给异常。具体做法是列一张"边界清单",逐项确认处理策略。
| 边界类型 | 典型场景 | 必须写清楚的策略 |
|---|---|---|
| 空数据 | 列表无记录、搜索无结果、字段未填 | 空态展示什么、是否给引导、是否影响其他模块 |
| 数量极值 | 单页 0 条 / 1 条 / 上万条 | 分页规则、加载策略、是否截断 |
| 内容超长 | 昵称 200 字、备注带表情符号 | 截断规则、换行规则、存储长度上限 |
| 并发操作 | 连点提交、多端同时编辑 | 按钮置灰时长、请求去重、冲突提示 |
| 网络异常 | 弱网、断网、请求超时 | 重试次数、超时阈值、本地缓存与恢复 |
| 权限变化 | 操作中途被移出团队 | 实时校验点、失败提示、数据可见性 |
| 数据不一致 | 缓存与库不一致、异步延迟 | 以哪边为准、多久同步、如何兜底 |
这张表不是写给自己看的,它是写给测试的用例来源,也是写给研发的实现清单。我一般在文档里把这七类逐条填完,评审会能省掉一半的追问。
这里有个细节值得单独说:异常处理的措辞要落到具体行为,不能停在"给予友好提示"。什么叫友好?文案写什么?是弹窗还是页内提示?用户点掉之后去哪?我见过太多文档在这句话上栽跟头——上线后文案是研发临时想的,风格和产品其他地方完全不一致,运营看到当场血压升高。
2.5 第五条:每一次变更都要留下"为什么"
需求变更是常态,问题不在变,而在变了之后没人记得为什么变。我经历过最混乱的一次:同一个功能在两个月里改了四版规则,第五次讨论时有人提出"能不能回到最初的方案",全场沉默——因为没人说得清最初为什么被否掉,也没人拿得出当时的讨论结论。结果是把已经踩过的坑又踩了一遍。
后来我强制自己维护一份变更记录,格式固定,只有四列:
| 版本 | 变更内容 | 变更理由 | 影响面 |
|---|---|---|---|
| v1.2 | 支付超时时间由 15 分钟调整为 30 分钟 | 数据显示 15 分钟内完成支付的比例仅 68%,用户中途切换应用回来常已失效 | 需同步调整超时提醒文案;测试用例需覆盖 29 分钟边界 |
四列里最容易被跳过的是"变更理由",而它恰恰是唯一无法从代码和文档正文里反推出来的信息。代码能告诉你现在是什么样,只有变更记录能告诉你为什么是这样。
除了变更记录,我还坚持给文档打版本号和状态标记,比如"v1.2 / 评审通过 / 生效中"、"v1.3 / 草稿 / 待评审"。这个小动作解决了一个非常现实的困扰:文档散落在各个地方,会议纪要里贴一版、群里发一版、邮件附件一版,到底哪版算数?把状态写进文件名和页眉,能省掉无数次"你手上那版是几号的"。
3. 一套可以直接拿去用的骨架与写法示例
3.1 骨架全文,以及每部分为什么这么排
下面这套结构我用了三年多,中间只微调过两次,基本稳定。用 Markdown 写,转成任何格式都不费劲。
# 需求名称(v1.2 / 评审通过) ## 一、摘要 1. 一句话说明:给谁,解决什么问题,怎么做 2. 目标(不超过 3 条,每条都要有可衡量的指标) 3. 非目标(写明不做、为什么不做、什么条件下会做) 4. 关键约束(时间、依赖、合规、技术限制) ## 二、场景与流程 1. 用户角色与使用场景 2. 主流程(状态机描述) 3. 异常流程与边界清单 ## 三、详细规则 1. 字段定义(名称、类型、长度、必填、校验、默认值) 2. 交互规则(触发条件、反馈形式、文案) 3. 业务规则(计算逻辑、优先级、冲突处理) 4. 权限与可见性 ## 四、验收 1. 验收条件清单(每条可判定真伪) 2. 埋点定义(事件名、参数、触发时机) 3. 上线检查项 ## 五、附录 1. 变更记录 2. 待确认问题清单 3. 相关链接排序逻辑很简单:从结论到细节,从共识到分歧。摘要层放结论,让所有人十秒内知道这需求做不做、做到什么程度;越往后越细,读到最后的只有真正要动手的人。
顺便说一个常被忽略的章节:附录里的"待确认问题清单"。写文档的过程中总会出现一些当下定不下来的点,与其硬编一个答案,不如老实列出来,标注"待确认 / 责任人 / 期望确认时间"。这份清单在评审会上非常好用——它把"你没想清楚"变成了"这些是有明确归属的开放项",讨论会立刻变得有建设性。
3.2 一条需求的标准化写法,以及三个对比示例
我发现很多人写需求条目的颗粒度是乱的:有的条目写成了三行散文,有的条目拆成了十几个碎点。统一颗粒度的办法是给它一个固定模板,我常用的是五要素:触发条件、前置约束、期望行为、异常处理、验收口径。
拿一个模拟项目举例,场景是记账类应用里的"周期性账单提醒"功能。
反例一(太笼统):
系统应在账单到期前提醒用户。
问题:提醒几次?提前多久?通过什么渠道?用户关了通知怎么办?这条需求等于把设计工作全部甩给了研发。
反例二(太啰嗦):
系统在账单到期前三天上午十点给用户发一条推送,推送标题是"账单提醒",内容是"您有一笔账单即将到期"。如果用户没看到,第二天再发一次。如果还没看到,第三天再发一次。推送点击后进入账单详情页。如果用户关闭了推送权限,那么……(后续省略八百字)
问题:这是把实现细节当需求写,一旦产品策略调整(比如改成提前五天),整段要重写。
改造后(五要素写法):
条目:到期提醒 触发条件:账单到期日 - 提前量(默认 3 天,可配置区间 1-15 天) 前置约束:用户已开启该类提醒;账户状态正常;同一账单同一提前量只触发一次 期望行为:发送一条站内提醒,标题固定为"账单到期提醒",正文包含账单名称与到期日; 点击进入该账单详情页;同时在应用内消息中心生成一条记录 异常处理: - 用户关闭该类提醒 → 不触发,不记录 - 同一账单重复生成 → 以账单 ID 去重,保留最早一次 - 发送失败 → 重试 1 次,仍失败则记录失败日志,不阻塞后续账单 验收口径: - 提前量为 3 天时,到期日前第 3 天 09:00-09:10 之间可见提醒 - 关闭提醒开关后,未来 7 天内无新增提醒记录 - 连续 10 笔账单同时到期时,消息中心按到期日升序展示这份写法的好处在于可替换:提前量是参数,文案是配置项,策略调整时只需要改参数说明,不用重写整段。研发拿到手也清楚哪些是硬规则、哪些是可以谈的细节。
再说一个真实教训。早些年我写需求喜欢用"应该"、"建议"、"可以考虑"这类词,本意是留点弹性,结果研发全部按"不做"处理——因为"建议"在他们眼里就是可选项。现在我文档里只允许三种措辞:必须、不允许、默认。要留弹性就明确写"由 XX 配置项控制,默认值 YY",把弹性变成一个显式参数,而不是一句模糊的形容词。
3.3 验收标准和埋点,别留给上线前最后一小时
验收条件这一节,我见过太多文档写的是"功能正常可用"。这句话对测试毫无意义。合格的验收条件应该是这样的:
- 列表为空时展示空态插图与"去创建"按钮,点击跳转创建页,返回后列表自动刷新
- 单次最多选择 50 项,选中 50 项后其余项置灰且提示"最多选择 50 项"
- 提交后 3 秒内出现结果反馈,成功进入详情页,失败留在当前页并保留已选内容
三条都具备"输入—行为—可观测结果"的结构,测试能直接转成用例,研发能直接对照自查。
埋点部分同理。很多团队把埋点当成上线前的收尾工作,结果数据回来看不懂,事件名各写各的。我的做法是在写需求时就把埋点表定下来:
| 事件名 | 触发时机 | 关键参数 | 用途 |
|---|---|---|---|
| remind_show | 提醒在消息中心展示时 | bill_id、remind_days、channel | 统计提醒触达率 |
| remind_click | 用户点击提醒 | bill_id、remind_days、position | 评估提醒有效性 |
| remind_setting_change | 用户修改提前量 | old_days、new_days | 观察用户偏好分布 |
参数里的 remind_days 特别关键——没有它,你永远无法回答"提前几天提醒用户点击率最高"这个直接影响策略的问题。埋点设计的核心判断是:这个参数能不能支撑未来三个月最可能被问到的那三个问题。答不上来的参数,先别埋,埋了也是垃圾。
4. 评审现场实录与高频问题排查手册
4.1 评审会上最常被追问的六类问题
评审会是我检验文档质量的唯一标准。写得糊的地方,会在那里被逐条撕开。我把这些年被问得最多的问题归了类,基本覆盖了文档的常见缺口:
第一类是边界追问:"如果这个字段为空呢""如果用户有一千条数据呢""如果两个人同时操作呢"。这类问题出现频率最高,解决方式就是把 2.4 节那张边界清单填满。
第二类是状态追问:"点了取消之后还能恢复吗""支付超时了但钱扣了怎么处理"。这类问题指向状态机没写全,尤其是中间态和终态之间的可达性。
第三类是口径追问:"你说的活跃用户是怎么算的""这个数是当天的还是累计的"。凡是涉及数据的地方,必须写清算法和时间窗口,否则同一个词在不同人嘴里是两个意思。
第四类是依赖追问:"这个能力依赖谁提供""对方什么时候能给"。跨团队协作的需求,依赖项必须写进摘要层的"关键约束",并标注责任人和时间点。
第五类是逆操作追问:"删了能恢复吗""撤回了对方看到什么"。凡是有创建就一定有删除,有提交就一定有撤回,逆操作的设计往往比正向操作更容易出问题。
第六类是灰度和回滚追问:"先放多少量""出问题怎么回退"。这类问题在评审后期出现,答不上来通常意味着方案还没想透。
我现在的习惯是在评审前自己先把这六类问题过一遍,能答的直接补进文档,答不上的标进"待确认清单"。一轮自查下来,评审时间通常能压掉三分之一。
4.2 一份可以贴在显示器边上的速查表
| 症状 | 根因 | 处理动作 |
|---|---|---|
| 评审会被反复问同一个问题 | 文档里该点分散在多处且表述不一 | 收敛为单一定义,其余位置引用而非重复描述 |
| 研发做完说"和你想的不一样" | 需求用了模糊形容词 | 全部改写为条件 + 阈值 + 观测方式 |
| 测试用例覆盖不全 | 异常路径没写 | 补边界清单七类,逐条给出处理策略 |
| 上线后文案风格混乱 | 文案没在文档里定稿 | 所有用户可见文案进文档,标注是否可配置 |
| 需求改了没人知道 | 缺变更记录与通知机制 | 建立四列变更表,每次变更同步相关方 |
| 数据回来看不懂 | 埋点参数缺失或命名混乱 | 评审前定埋点表,参数按"未来三个月会被问什么"设计 |
| 上线后无法回退 | 方案未考虑灰度与开关 | 摘要层固定列出开关项、灰度比例、回退步骤 |
这张表我贴在显示器边上很久了,属于那种看着简单但每次都能救命的东西。特别是最后一行——任何一次上线,都应该能在十分钟内退回到上一个状态。如果做不到,说明方案里缺了开关设计,这是要在文档阶段就解决的,不是上线当天临时想的。
4.3 几个我坚持了很多年的小习惯
第一个习惯:写完先放两小时再读一遍。刚写完的时候脑子是热的,会自动补全所有没写清楚的地方。放一会儿再读,那些"我自己都看不懂"的句子会自己跳出来。
第二个习惯:找一个人当面讲一遍。不用讲全文,就讲主流程和异常处理。讲的过程中卡壳的地方,一定是文档里写糊的地方——语言比文字更容易暴露逻辑漏洞。
第三个习惯:给文档定一个"够用就好"的完成线。我见过太多人陷进文档里出不来,反复打磨措辞,结果需求迟迟不能进入开发。我的判断标准是:研发看完能列出任务拆解、测试看完能列出用例大纲,这份文档就够用了。文档的目的是让事情开始动,不是让自己安心。
第四个习惯:把踩过的坑记在同一个小本子上。前面那五条规则、那张速查表,全都是从这个本子里长出来的。工具会换、团队会换,但那些让沟通失效的具体原因,翻来覆去就那么几种。记下来,下次就不会再踩。
这几年我最深的体会是,PRD 写作水平的分水岭,其实不在文笔,而在你有没有把对方脑子里的问号当成自己的责任。写得漂亮但漏洞百出的文档,和写得朴素但滴水不漏的文档,在真实项目里的差距是几周的返工和几十次的扯皮。那些看着不起眼的细节——一个空态、一句文案、一个"待确认"的标注——才是把一群人拧成一股绳的东西。