PRD写作五条硬规则:从需求评审返工到可验证验收
写 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 写作水平的分水岭其实不在文笔而在你有没有把对方脑子里的问号当成自己的责任。写得漂亮但漏洞百出的文档和写得朴素但滴水不漏的文档在真实项目里的差距是几周的返工和几十次的扯皮。那些看着不起眼的细节——一个空态、一句文案、一个待确认的标注——才是把一群人拧成一股绳的东西。