
简介这是一份可直接编辑使用的产品需求文档PRDWord模板面向产品经理、需求分析师、研发和测试人员帮助团队在项目启动或版本迭代时快速产出结构清晰、可评审的需求文档。模板从总体说明到UC用例逐层展开覆盖修订历史、项目概述、功能范围、用户范围、词汇表、非功能需求、其他说明等关键模块同时以‘用户可以在网上退票’为示例展示用例编号、名称、角色、优先级和描述的标准写法让使用者能很快上手并避免遗漏需求要素。资源包仅含1个docx文档大小463KB轻量便携下载后可直接套用填写。目前已有1461人浏览学习既适合新手作为PRD写作的参考蓝本也可作为团队统一模板、提升协作与评审效率的实用工具无论新项目规划还是功能迭代都能节省从头编写格式的时间。1. 一份PRD模板为什么比一百个PRD样例更值钱很多刚入行的人喜欢下载某个具体产品的PRD样例但真正在跨团队协作里发挥作用的是藏在页面里的字段结构而不是那一页页的业务描述。这份以12306中国铁路客户服务中心为实例的产品需求文档(PRD)模板表面上只是一组标题和空表格实际上已经把“总体说明—功能范围—用户范围—UC用例—非功能需求”串成了一条可追溯的需求传递链。这里不逐页翻译模板而是直接讲每个字段为什么存在、在研发协作里扮演什么角色并给出一套把模板工程化成docx、再让它能被AI生成测试用例的可复现做法。2. 拆解模板骨架总体说明、功能范围与UC用例如何咬合2.1 修订历史与项目概述是第一道管控闸门修订历史不是一行装饰。模板里把日期、版本、说明、作者四列放在最前面本质上等于给需求文件建立了一条审计记录。行业里的常见做法是每个需求变更都要在此登记版本号用V0.x表示草稿评审通过后再升为V1.0。实际工程中很多团队为了省事跳过这一节结果上线前业务方拿着旧版PRD来质疑“当时没说过这个限制”。修订历史是唯一能自证的地方所以拿到模板第一件事是检查修订历史里是否有日期、版本和作者三个必填列没有就补上。在版本管理上docx不是一个diff友好的格式。我一般会这样做把docx源文件收在Git仓库里再用pandoc导出一个同名markdown文件用来做diff。pandoc 12306_PRD.docx -t markdown -o 12306_PRD.md git diff --stat其中-t markdown表示输出格式为markdown-o指定输出文件名。先转换再进Git能避免docx二进制文件在分支合并时出现无法阅读的冲突标记。如果团队里有人觉得维护修订历史太烦可以把这个命令保存成保存时自动触发的脚本每次生成新版PRD时顺带更新修订历史表比人工记录可靠得多。2.2 功能范围与用户范围划清系统的物理边界模板第1.3节给出了一个总流程和一张功能优先级表登录验证、管理员功能、普通用户功能、车票车次管理、列车时刻查询、票价查询、余票查询等。它要解决的核心问题是“哪些功能做哪些不做”同时用高、中、低给功能标定优先级。研发排期时高优先级功能进入第一个迭代中的进入第二个迭代低的可能下个版本再说。优先级字段如果不填开发会默认所有功能都要做排期和测试范围会同时失控。用户范围一节定义了普通用户、游客、管理员、审核员、合作方五类角色。请特别注意游客拥有浏览和查询权限但没有购票权限审核员负责乘客信息审核合作方是支付方式支持者。这些角色定义直接约束了后续UC用例里的“使用角色”字段是否有效。为了让边界更清晰可以在模板基础上补一张角色权限矩阵角色注册登录查询车次购票退票审核乘客普通用户是是是是是否游客否否是否否否管理员否是是是是是审核员否是是否否是合作方否是否否否否这张表完成后后续编写UC时就不会出现“游客可以退票”这种逻辑矛盾。我评审时见过不少PRD的UC里写的使用角色是“用户”但用户范围里根本没有这个角色统称测试只能去猜猜错了就白测。用户范围不只是写给产品看的一页说明它给测试圈提供了一份合法的角色清单。2.3 UC用例是PRD的可执行单元模板中“用户可以在网上退票”这个用例值得拆一遍。它的字段包括编号UC-1、名称、使用角色、优先级、描述、前置条件、后置条件、界面、规则描述。为什么需要这些字段因为自然语言描述歧义太大而前置条件和后置条件是开发写代码时的第一个判断依据。以退票为例前置条件是“用户有已完成订单进入已完成订单界面”这个条件限定了入口后置条件是“查看订单详情即可选择退票”它锁定的是系统执行完动作后的状态。实践中很多人把描述写成散文把前置条件写成“用户想退票”这等于没写。更准确的写法是“订单状态为已完成且未超过退票时限用户已登录并通过实名认证”。有了这样的前置条件测试才能构造出边界场景。在模板里正确的使用方式是描述写操作步骤前置条件写系统必须满足的状态后置条件写操作成功后的系统状态规则描述写业务约束与分支。规则描述是异常测试用例的主要来源例如“已检票车票不可退”“改签后的车票按改签时间计算退票手续费”这类规则不写清楚开发默认就不做限制。另外值得注意模板里UC_1后面跟着空白的UC_2、UC_3等占位。这是刻意留出来的目的是让每个用例编号保持全局唯一。一旦引入“UC-1”“UC-2”这样的短编号就不建议用删除线重排的方式再编号因为PRD里的用例编号会被开发设计文档、测试用例和缺陷单引用。更稳妥的写法是用模块前缀加序号比如TICKET-UC-001、USER-UC-001这样即使后面删除某个用例也不会影响其他模块的编号连续性。2.4 非功能需求往往决定上线后是否被骂模板第1.6节列了数据监控、性能、用户体验三大类。这一节最容易空着不填因为不够直观。模板里有一句“前端用户购票体验需要滚动流畅且能自动刷新数据”这句话如果原样交给研发会被打回因为不可度量。建议拆成可验收的参数车次列表每15秒自动刷新一次刷新期间页面不能白屏滚动帧率在低端机上不低于55 FPS支付接口请求超时设置为5秒并给出重试入口。非功能需求的字段位置很重要不要塞进“其他说明”那里通常没人看。模板专门给“非功能需求”留了独立小节评审时要逐个参数过一遍。如果某个指标实际达不到也要在这里写明降级策略比如“高峰期允许排队等待但前端需给出预计等待时间”。这样后台做限流时有依据前端也不会把超时当成彻底失败。3. 用python-docx把PRD模板工程化样式、占位符与目录3.1 为什么要用脚本维护PRD而不是纯手抄PRD模板一旦进入多项目复用阶段纯手抄的效率很低。复制一份docx再手工改标题很容易出现上一个项目的残留信息样式不统一还会让目录页码和标题层级错乱。我一般会把模板做成两个层次一个空白模板文件用来建新PRD一个生成脚本用来从结构化数据批量拼装UC正文。通用部分如封面、说明、角色表保持不变差异部分如功能清单、UC列表、指标全部由数据驱动。3.2 用样式表统一标题和正文python-docx是对接Word文档最直接的库。第一步是定义样式让所有标题、正文、表格从开始就使用同一套字体和字号。下面的代码会生成一个带基本样式的空白docxfrom docx import Document from docx.shared import Pt, RGBColor doc Document() # 设置正文默认字体 normal doc.styles[Normal] normal.font.name 微软雅黑 normal.font.size Pt(10.5) # 给Heading 1到Heading 3统一样式 for i, size in [(1, 16), (2, 14), (3, 12)]: style doc.styles[fHeading {i}] style.font.name 微软雅黑 style.font.size Pt(size) style.font.color.rgb RGBColor(0x1F, 0x3A, 0x5F) doc.save(PRD_blank.docx)代码逻辑先获取Normal样式再覆盖Word内置的Heading 1到3。字号分别指定为16、14、12磅颜色统一为深蓝灰。这里有一个参数容易踩坑python-docx的font.name只能设置西文字体中文字体有时需要通过rFonts才能生效。如果设置后中文仍显示宋体可以加一行代码from docx.oxml.ns import qn style.font.element.rPr.rFonts.set(qn(w:eastAsia), 微软雅黑)这样强制把东亚字体也设置为微软雅黑。字体确认没问题后再插入标题时Word里的导航窗格能正确展示文档结构自动目录也才会识别完整。3.3 用占位符做内容替换样式解决“看起来一致”占位符解决“内容来源固定”。常用做法是在模板里写入{{PROJECT_NAME}}、{{VERSION}}这样的占位符生成新PRD时统一替换。python-docx对段落的text属性直接赋值会丢失原来的run格式所以替换时要注意def fill_placeholders(doc, mapping): for para in doc.paragraphs: for key, value in mapping.items(): if key in para.text: para.text para.text.replace(key, value)这里有一个重要陷阱para.text ...会把该段落的所有run合并重写如果占位符与文字混排周围的加粗、颜色都会丢。更安全的方式是在run级别替换只替换包含占位符的那一个rundef fill_placeholders_safe(doc, mapping): for para in doc.paragraphs: for run in para.runs: for key, value in mapping.items(): if key in run.text: run.text run.text.replace(key, value)para.runs返回段落内所有run对象每个run对应一段连续的相同格式文本。这个版本不会影响其他run的样式但要求占位符不能跨run。我的建议是模板里的占位符一律独占一行前后不加其他字符这样无论用哪种方式替换都安全。3.4 批量生成UC用例表格最耗时间的部分是把UC列表转换成docx里的表格。如果UC维护在Excel或数据库里可以直接批量生成。假设ucs.xlsx包含uc_id、uc_name、role、priority、pre、post、steps这些列生成代码如下import pandas as pd from docx import Document uc_df pd.read_excel(ucs.xlsx) doc Document(PRD_blank.docx) for _, row in uc_df.iterrows(): doc.add_heading(fUC_{row[uc_id]}{row[uc_name]}, level2) table doc.add_table(rows6, cols2) table.style Table Grid fields [ (编号, str(row[uc_id])), (使用角色, row[role]), (优先级, str(row[priority])), (前置条件, row[pre]), (后置条件, row[post]), (描述, row[steps]), ] for i, (key, value) in enumerate(fields): table.rows[i].cells[0].text key table.rows[i].cells[1].text value doc.save(PRD_filled.docx)这段代码先按行读取Excel然后在文档中插入二级标题再添加一个6行2列的表格。table.style Table Grid决定表格是否有可视边框不设置的话Word默认无边框打印出来很难看。字段顺序决定表格行序编号永远是第一行描述是最后一行。表格没有自动列宽功能建议控制每个字段的字数超长内容拆到“界面”或“规则描述”小节。python-docx常用操作汇总如下方法/属性作用关键参数doc.add_paragraph(text, style)添加段落style可传Normal或自定义样式doc.add_heading(text, level)添加标题level1~9对应Word内置Headingdoc.add_table(rows, cols)新增表格返回Table对象table.style Table Grid设置表格边框使用Word自带样式名称run.text value替换run文本保留其他run的格式doc.styles[fHeading {n}]修改标题样式只对当前文档生效这套生成方式最大的好处是UC的评审意见只改动Excel里的那一行重新跑脚本就能生成新版PRD不需要人肉在Word里做删除线。输出结果还能被后续的测试用例生成脚本直接复用。4. 从UC用例到测试用例模板里的参数决定AI生成质量4.1 为什么AI生成的测试用例经常不可用现在很多团队尝试用“AI根据PRD生成测试用例”跑下来问题大多不是AI不够聪明而是PRD模板没有把关键字段填满。UC部分如果只有一段描述文字没有前置条件、后置条件、规则描述AI就只能靠常识补全操作步骤生成出来的异常流几乎等于零。模板里“规则描述”这一栏留空AI会把所有分支都当成正常流。所以想让AI输出可用用例先要改模板字段结构再谈模型能力。4.2 结构化UC字段的作用以退票用例为例一份适合AI消费的UC应当是这样的结构化数据字段内容编号TICKET-UC-001名称用户可以在网上退票使用角色普通用户优先级高前置条件用户已登录且实名认证存在已完成且未检票的订单后置条件订单状态变为“已退票”退款单生成基本流程1.进入我的123062.点击已完成订单3.选择车票点击退票4.确认退票规则描述已检票车票不可退距发车不足30分钟需到窗口退退票手续费按梯次计算规则描述是异常流的核心来源。“已检票车票不可退”能生成一条验证异常流“距发车不足30分钟需到窗口退”能生成边界值用例。如果没有这一栏生成的测试只能覆盖第1步到第4步的正常流程边界和异常完全丢失。4.3 把UC模板批量转换成测试用例骨架如果模板里的UC是统一表格维护的可以直接用脚本把Excel中的UC展开成测试用例骨架。下面是一个最小转换器import json uc { id: TICKET-UC-001, precondition: 用户已登录且实名认证存在已完成且未检票的订单, steps: [进入我的12306, 点击已完成订单, 选择车票点击退票, 确认退票], rules: [已检票车票不可退, 距发车不足30分钟需到窗口退] } def build_test_cases(uc): cases [] cases.append({ id: uc[id] _T01, precondition: uc[precondition], steps: uc[steps], expected: 退票成功订单状态变为已退票生成退款单 }) for idx, rule in enumerate(uc[rules], start2): cases.append({ id: f{uc[id]}_T0{idx}, precondition: uc[precondition] f并且{rule}, steps: uc[steps], expected: 系统拦截并提示 rule }) return cases for case in build_test_cases(uc): print(json.dumps(case, ensure_asciiFalse, indent2))代码先构造正常流T01预期结果固定为“退票成功订单状态变为已退票生成退款单”。然后遍历规则列表每条规则生成一条异常流用例预期结果是“系统拦截并提示对应规则文案”。这么做的前提是UC的步骤和规则都是数组否则脚本无法区分“分支”和“主流程”。如果模板里UC的“描述”是一大段文字建议在模板层面拆成基本流程和业务规则两个字段否则脚本无法干净切分。4.4 用提示词模板约束AI输出当UC字段规范到位后可以让AI直接基于UC生成测试用例。常用的做法是给一个结构化的提示词模板请依据以下PRD用例生成测试用例覆盖正常流、异常流、边界值。 用例编号{id} 用例名称{name} 前置条件{precondition} 后置条件{postcondition} 基本流程{steps} 业务规则{rules} 输出要求 1. 每条用例包含用例编号、测试数据、前置条件、操作步骤、预期结果 2. 至少包含一条正常流、一条异常流、一条边界值用例 3. 不允许省略前置条件这里最关键的是把“业务规则”单独拿出来。如果模板里没有规则字段提示词里就没有{rules}AI只能从基本流程里猜猜出来的异常流经常是重复的无效用例。输出要求第三项“不允许省略前置条件”是为了防止AI偷懒把前置条件写成“用户进入页面”这种无法构造的数据。如果想要更高粒度的输出可以在提示词末尾加一句“每个前置条件都要能唯一确定一个用户状态”能显著减少用例之间的数据冲突。团队配合上我一般把上面的提示词模板挂在项目Wiki的“测试设计规范”里产品经理写PRD时就按这个规范填UCAI生成的质量会稳定很多不需要每次调prompt。真正的收益不是一条条检查AI的用例而是通过PRD字段标准化把人工评审范围缩小到规则描述的覆盖度上。评审时只看“已检票车票不可退”这类规则是否遗漏而不是去数有没有一百条用例。5. 文档排坑与自动化校验docx模板在团队协作里的最后一步5.1 别让WPS默认新建docx的配置坑到整条流水线模板交付后首先会遇到打开方式的问题。团队里如果有人用WPS有人用Office双击模板可能打开的是不同软件。常见的问题是WPS在授权不完整情况下会把新建文档默认保存为旧版doc导致后续脚本读取时表格结构发生变化。操作上建议所有人先确认默认文件类型是docx。如果Windows资源管理器预览窗格无法预览docx通常是因为系统没有安装Office文档预览处理程序或者权限被组策略禁用。对“无法预览doc”这种场景与其折腾预览器不如直接跑一次脚本做完整性检查反正最终都要靠脚本校验。5.2 用校验脚本卡住PRD的完整性模板最大的风险是字段填了一半评审没发现。我一般会在PRD提交前跑一个校验脚本自动列出所有UC中缺失的关键字段。脚本作用于之前生成的docx提取所有表格按“编号字段”结构检查from docx import Document REQUIRED_FIELDS (前置条件, 后置条件, 规则描述, 描述) def check_prd(path): doc Document(path) issues [] for table in doc.tables: uc_id None fields {} for row in table.rows: if len(row.cells) 2: continue key row.cells[0].text.strip() value row.cells[1].text.strip() if key 编号: uc_id value fields[key] value if uc_id is None: continue for field in REQUIRED_FIELDS: if not fields.get(field): issues.append(f{uc_id} 缺少字段{field}) return issues issues check_prd(PRD_filled.docx) for issue in issues: print(issue)脚本逻辑是按行读取每张表格把第一列当字段名、第二列当字段值。只有当行内存在“编号”且编号非空时才把它当作UC表。然后检查前置条件、后置条件、规则描述、描述四个字段是否都非空。模板里可能有角色矩阵或功能优先级表那些表格没有“编号”列会被自动跳过所以不会误报。这里有一个边界情况某个UC的后置条件写“查看订单详情即可选择退票”值非空但不可验证。脚本只能抓空字段抓不出“写得不规范”。要再进一步可以在脚本里加关键词白名单检查“后置条件”是否包含“变为”“显示”“生成”这类结果动词不含则提示主观性过强。这个脚本可以挂到Git的pre-commit钩子PRD每次更新提交时自动跑一遍有issue就不允许合入。这样评审前看到的是完整且可执行的UC不是开发拿着半张表去猜需求。本文还有配套的精品资源点击获取