关于 write-a-prd
用于产品塑形的技能,可将已充分理解的问题整理为范围明确的 PRD。它引导访谈者设定时间投入、检查代码库与既有研究、梳理用例,并准备可供实现的交接内容。
主要功能
- 01每轮只问一个问题
- 02设定时间投入范围
- 03检查代码库与既有研究
- 04梳理用例和边界情形
- 05识别待解问题与排除项
- 06准备实现交接内容
适用场景
- 01根据用户问题塑造功能提案
- 02按时间投入限定项目范围
- 03结合已有研究与过往方案
- 04为拆解工单准备 PRD
安装
复制下面的命令,在终端中运行。
npx skills add https:/ / github.com/ chrislacey89/ skills --skill write-a-prd安装后在 Claude Code 中输入/write-a-prd确认已加载。
附带文件references/sidecar.shreferences/state-backend.md
详细介绍
编写 PRD
此技能会产出一份经过塑形的提案——PRD 的粗略程度足以留给构建者判断,方案又足够成熟,可以投入发布,并且明确限定了时间投入。请遵循以下步骤,根据工作内容调整深度,但不要跳过用于明确投入意愿、了解当前代码实际情况、掌握组织知识以及确认交接准备情况的检查。
每轮只问一个问题。 在此技能的访谈过程中,一次只问一个问题,并等待用户回答后再问下一个。即使问题很简短,也绝不要在一条消息中提出多个问题。
优先使用单选。 当用户需要选择一个方向、一项优先事项或一个下一步时,使用单选题。
谨慎使用多选。 仅用于可以并存的选项组合,例如目标、限制、非目标和成功标准。如果需要确定优先级,请继续追问用户所选项目中哪一项最重要。
平台提供提问工具时请使用。 在 Claude Code 中,使用
AskUserQuestion;在 Codex 中,使用request_user_input;在 Gemini 中,使用ask_user。否则,在聊天中列出编号选项,并等待用户回复后再继续。
调用位置
这是一个主要流程技能,通常位于 /research 之后、/prd-to-issues 之前。
当问题已经足够清晰,可以制定范围明确的解决方案并将其转化为可实施提案时,使用 /write-a-prd。
如果问题仍然模糊,需要在 /shape 中继续探索;如果尚未在 /research 中核实技术现状;或者用户已有成型的 PRD,只想拆解或执行,那么不要从这里开始。
流程
1. 将问题描述为具体场景
请用户用一个具体场景描述问题,说明现状为何无法满足真实用户的需求。在抽象的功能请求(“我们需要改进 X”)尚未具体到实际阻碍(“用户尝试执行 Y 时,由于……而遇到 Z”)之前,请引导用户进一步说明。
好的问题陈述应是一个场景——一个参与者、一次尝试、一次失败。如果用户先提出解决方案(“我想添加一个 webhook 系统”),请问:“当前发生了什么痛点,严重到值得为此投入开发?”
2. 确定时间预算
在设计任何解决方案之前,先明确时间预算:这个问题值得投入多少时间?
- 小批次:1-2 周的实施时间
- 大批次:最多 6 周的实施时间
时间预算是一项约束,而不是估算。它回答的是“我们愿意投入多少时间?”,而不是“这需要多长时间?”。如果问题超出时间预算,就缩小问题范围,而不是增加预算。
时间预算是一个目标——业务方愿意投入多少时间。它不是估算——对工作可能需要多长时间的分析性预测;也不是承诺——承诺在某个日期前交付。如果当前估算超出时间预算,就调整解决方案,而不是悄然把时间预算变成承诺。
时间预算会影响后续的一切:哪些用户故事是必需项,哪些是锦上添花;可以接受多少次钻牛角尖;以及要多大力度地压缩范围。
大批次工作的容器里程碑。 如果时间预算属于大批次(6 周),询问是否应创建 GitHub 里程碑,用作 PRD 及其后续切分 issue 的组织容器。默认答案是肯定的——大批次工作可受益于 GitHub 中基于里程碑的进度跟踪。
创建新里程碑前,先检查是否已有里程碑:gh api repos/{owner}/{repo}/milestones --jq '.[].title'。如果已存在里程碑(例如之前某个阶段通过 /create-milestone 创建),询问是否应关联到该里程碑,而不是创建新的。
如果用户确认,请记下里程碑名称,供步骤 8 使用。如果用户拒绝,就不使用里程碑继续推进——里程碑只是组织上的便利,并非结构性要求。小批次工作(1-2 周)不需要里程碑。
如果步骤 8 的后端检查结果为 sidecar,那么里程碑只是一个名称。跳过 gh api 查询,也不要在 GitHub 上创建任何内容。记下名称,步骤 8 会将其记录为工作项的一个字段。
3. 探查代码库
探查仓库,以核实用户的说法并了解代码的当前状态。
4. 查阅机构知识
在采访用户之前,检查两个来源:
过往解决方案 — 搜索所有可能存放经验总结的位置:项目的 sidecar 和仓库内路径。使用此技能随附的解析器 references/sidecar.sh,并通过其已安装的绝对路径解析两者;切勿自行计算 sidecar 路径。sidecar.sh solutions-dirs 会打印要搜索的目录,并负责制定相关策略(其文件头中对此有说明)。将要查找的关键字设为 KW:
SC="<this skill's directory>/references/sidecar.sh"
KW="relevant-keyword"
bash "$SC" solutions-dirs | while IFS= read -r DIR; do
[ -d "$DIR" ] && grep -rl -- "$KW" "$DIR"
done
true
列出两个位置的匹配项;两处不会互相遮蔽。若某条匹配项位于 docs/solutions 以外的 in_tree_path 下(如 docs/adr、docs/decisions 等),那就是该仓库自己的惯例:将其作为普通文档阅读,不检查 frontmatter 或过时情况。若你阅读的条目引用了其他路径(Related: 指针、研究条目、档案等),使用 SC="<this skill's directory>/references/sidecar.sh"; bash "$SC" require "<cited path>" --from "<the citing entry's file path>" 检查该路径(新 shell 中没有 SC),并打开它打印出的路径,而不是从引用条目推导出的路径;MISSING: 行要展示给用户,不能跳过。若存在相关解决方案,请阅读并将其中的经验纳入你对问题领域的理解。在采访过程中向用户指出相关陷阱、模式或决策——“我们之前在类似功能中遇到过 X,解决方案是 Y。这里要采用相同模式吗?”
研究文档 — 查找此功能最新的研究产物。根据项目的 research.storage 设置,产物可能位于以下两个位置之一:
-
Spike issue 模式 — 在 GitHub 上搜索已关闭且带有
research标签、与此功能匹配的问题:gh issue list --label research --state closed --search "<feature keywords>" --limit 5如果存在匹配的 spike issue,请阅读其正文——顶部的 YAML frontmatter 包含与归档文件相同的
date和installed_versions_snapshot字段。 -
归档模式(默认)— 使用相同的解析器,列出 Phase 5c 写入的研究目录
/research。如果存在 sidecar,则该目录为其research/;如果出现SIDECAR MISS,则它是 sidecar 之前的归档目录,sidecar.sh archive-dir会为此处和 Phase 5c 指定该目录:SC="<this skill's directory>/references/sidecar.sh" ERR="$(mktemp)" || exit 1 if DIR="$(bash "$SC" path research 2>"$ERR")"; then rm -f "$ERR" ls "$DIR" else cat "$ERR" >&2 # Only a SIDECAR MISS falls back; any other failure is a refusal, not a miss. grep -q 'SIDECAR MISS:' "$ERR" || { rm -f "$ERR"; exit 1; } rm -f "$ERR" DIR="$(bash "$SC" archive-dir)" || exit 1 echo "pre-sidecar archive: $DIR" if [ -d "$DIR" ]; then ls "$DIR"; else echo "(empty: no research entries)"; fi fi选择
featurefrontmatter 字段(或文件名 slug)与此功能匹配的条目,并通过$DIR/<file>引用它。如果出现SIDECAR MISS,请按原样向用户显示该行,不要运行其init命令,因为创建 sidecar 是人工操作。若退出码为 1 但没有 miss 行(即当前目录不是 git 仓库),则不属于 miss:转述解析器打印的内容。scripts/test-sidecar-resolution.sh会针对 Phase 5c 的写入运行此段逻辑,确保两者不会指定不同的目录。
检查两个位置——最近切换过模式的项目可能仍在旧位置保留产物。如果同一功能在两个位置都有产物,优先采用 frontmatter 中 date 较新的那份,并向用户说明存在重复项。在信任任何研究产物之前,检查 frontmatter 中的 date 和 installed_versions_snapshot——如果其中任一项相对于当前情况显得过时,请向用户指出。如果研究产物存在且仍然有效,请彻底阅读。它包含 /research 阶段已研究并推荐的技术方案。方案介绍应以这些建议为基础,而不是重新争论。请在方案介绍中引用规范位置(spike issue URL,或上文所列条目的绝对路径),以便 /execute 和 Ralph 在实施期间读取。
产物优先级: 如果研究产物与 docs/solutions/ 不一致,以研究产物为准——它已根据已安装版本进行验证。存储位置不会影响可信度:spike issue 和归档条目具有同等权威性,因为它们都是同一 /research 技能依据同一 Phase 0/1 验证生成的正文。请在采访过程中向用户指出冲突,不要默默自行选择。
5. 通过塑形纪律开展访谈
访谈用户,了解解决方案,同时贯穿运用 Shape Up 的塑形技巧:
逐一对照解决方案梳理每个用例。 按照逐步成形的设计,逐一走过每次交互。此时会暴露缺口和兔子洞——“如果用户执行了 X,但 Y 还没加载,会发生什么?”发现兔子洞时,给它命名,并在继续之前商定一句话的解决方案。 每个重要用例都需要一个主要成功场景,外加至少两个流程出现转折、失败或需要恢复的扩展场景。如果你说不出这些扩展场景,说明该场景的塑形还不够充分。
将带保留的锚点视为一种特定的未解决兔子洞。诸如 “或者它的 X 表”、“Y 目前使用的同一条加载器路径”、“仿照现有的 Z 测试” 或 “W 的现有模式” 等说法,表明模型提到了一个未经核实是否存在的实体。在同一份 PRD 中,§Rabbit Holes 里的模糊措辞往往会在 §Implementation Decisions 中变成带有定冠词的确定说法,继而传播到 /prd-to-issues 中的切片边界图,并在 /execute 第 0 步之后依然存在——该步骤的 Consumes 验证关卡只会检查已命名的符号,不会检查模糊的名词。要在 §Implementation Decisions 将其敲定之前解决每个带保留的锚点:要么通过在代码库中搜索验证并明确写出精确标识符,要么重写说法,避免假装某个实体确实存在。如果这份 PRD 运行过 /research,其 Phase 0 规范锚点检查本应已发现这些问题;本段则是为跳过或压缩 /research 运行时提供的兜底。
梳理完用例后,反向推演一次。 正向梳理暴露出最初的兔子洞后,转换视角:设想此功能已经发布,却引发了严重问题。问题出在哪里?从失败倒推。将每种失败模式归入 Rabbit Holes(并附上解决方案)或 No-gos。不要把它们当作模糊的“已接受风险”带过——如果某种失败模式既无法解决,也无法排除,说明设计还没有解决到位。
检查结构,而不只是症状。 在敲定塑形方案前,依次提出以下三个问题——一次问一个,听取回答后再问下一个:
- 导致当前问题的根本条件是什么,而不只是表面上的抱怨?
- 是否存在延迟、交接或缺失的反馈环路,让问题更难及早发现?
- 拟议的干预措施是针对该条件的高杠杆改动,还是只是在局部修补症状?
保持精简。目标是改进塑形,而不是把方案变成一篇系统思维论文。
持续划分范围。 随着功能和行为逐渐明确,将它们划分为必需项或锦上添花项(~)。锦上添花项是预先授权的删减项——如果工作量接近上限,就优先砍掉这些内容,无需争论。
保持方案灵活。 将逐渐形成的理解作为可调整的方案呈现——“这是我目前的想法,欢迎随时提出异议”——而不是最终决定。这样能促成及时纠偏,而非让人照单全收。
与现状比较,而不是与理想比较。 评估能否接受缩减范围时,应与用户目前的体验(基线)比较,而不是与完美版本比较。发布优于基线的东西,总比因为追求理想而一无所获要好。
条件性流程行。 如果该功能引入面向用户的多步骤流程、新导航或重大的 UI 状态变化,请在访谈期间梳理其位置(屏幕/对话框)、可操作项(各处的按钮/字段/操作)和关联关系(从何处跳转到何处)——并将每一行关联到它所实现的 Must-have 故事,而不是单独归入一个章节。这样可以及早发现缺失的状态转换和含糊的状态,也能让 /prd-to-issues 第 5 步按可操作项的粒度而非整句话的粒度测试覆盖情况。某一行可以实现多个 Must;没有实现任何 Must 的行(导航栏、加载状态和空状态)应放入模板提供的未归属内容区域——不要强行让每一行都恰好对应一个故事,否则约束过严,会导致这些行被删除而不是妥善归类。对于仅涉及 API、后端或单屏的变更,请跳过此项。
访谈期间,请结合过往解决方案和研究中的相关经验:
- “研究建议使用 Ably 来实现在线状态——我们要采纳这一建议,还是重新评估?”
- “docs/solutions/ 中记录了关于 X 的一个陷阱——设计时应将其考虑在内。”
- “过往解决方案建议此类集成采用模式 Y。这适合这里吗?”
如果用户开始谈论日期、截止时间或信心程度,请在继续之前明确这些表述的含义。逐项提问:
- 这是一个目标(期望的业务成果或截止时间)、估算(当前预测),还是承诺(协商后作出的保证)?
- 还有哪些不确定因素,使得现在作出坚定承诺为时过早?
- 这份提案是否应标注一个范围或信心说明,而不是给出单一日期?
对于 API 类工作,请在结束访谈前明确契约的基本形态。保持精简,但须明确以下事项:
- API 问题陈述和影响陈述
- 使用该契约的开发者
- API 必须支持的操作
- 粗略说明端点或事件的范围
- 对使用方而言重要的必填、可选和有默认值的字段
- 预期的错误格式
- 对现有使用方的兼容性说明
- 一条简短的“其他考虑过的方案”说明,记录已否决的范式或契约方向
这不是完整的实现规范,而是最低限度的契约草案,可避免 /execute 在执行过程中自行臆造 API 行为。
6. 验证:粗略、已解决、范围明确
撰写提案前,请确认梳理好的工作具备以下三个特性:
- 粗略:解决方案有意为构建者留出判断空间。你没有指定像素级的 UI、精确的方法签名或逐步实现流程。如果读起来像线框图或教程,就说明细节太多。
- 已解决:宏观方向已敲定。所有已识别的复杂问题都用一句话给出了解决方案。构建者无需做根本性的架构决策,只需做战术层面的决定。
- 范围明确:已设定投入上限。已声明禁止事项。可选项以 ~ 标记。构建者无需询问,就能知道哪些内容在范围内、哪些不在。
- 坦诚面对不确定性:如果存在时间线或范围压力,方案说明应区分目标投入与当前估算或承诺。在重大未知因素尚未解决时,不应以虚假的精确度给出单一日期。
- 内容完整:动笔前,检查用户故事或复杂问题中未涵盖、但常被遗漏的工作。范围超支的主要原因是遗漏工作,而非低估工作量。AI Agent 会放大这一问题:Ralph 不会加班补上没人提过的错误处理,而是直接在没有错误处理的情况下交付。检查此清单(耗时 30 秒——判断是否相关即可,无需逐项详尽讨论):
- 只提名称、未列明内容的产品语义要素(评分标准、分类方案、评分准则、分类体系、角色/权限矩阵、决策规则)——如果 PRD 提及某个分类方案的名称,却未列出其成员,请在 §Implementation Decisions 中逐项列明,或将其声明为禁止事项。诸如“7 个类别”或“4 个等级”之类的说法是假精确性警示:使用定冠词般的确定语气,但具体内容仍只存在于用户脑中,并未写入 PRD 正文。
- 其他知识传递渠道——如果某项功能需要保证“不重复询问/不重复处理/不再次呈现/只处理一次”,请列明受保护输入可能到达的所有渠道(结构化字段和自由文本;输入的回答和上传的文档;API 参数和内嵌文本)。如果保护机制依赖某个渠道的结构标记(哨兵前缀、消息角色或工具输出部分类型),那它必然无法识别其他渠道。对于开放词汇渠道(自由文本),保护机制必须基于语义——使用由 LLM 决定的提示词,而非确定性键;并在行为/评估边界设置回归保护。区分“已说明”(信息完整提供)和“已提及”(有所涉及但实质上不完整);后者仍应允许继续询问。
- 质量属性(性能、可靠性、安全性、易用性、可维护性)——对于功能所涉及的每项属性,请在 §Implementation Decisions 中写明 SMART 标准(具体、可衡量、可实现、相关、有时间限制),或将其声明为禁止事项。如果无法编写测试,该要求就默认由 Agent 实际实现成什么样决定。将模糊的关注点改写为可测试的标准:“监控后端路径” → “每条后端路径都会输出包含 request_id、latency_ms 和 outcome 的结构化日志事件;通过切片 X 中的日志捕获集成测试验证”;“快速失败,而不是静默传播损坏状态” → “在 X 集成点发生架构验证失败时,写入器会在 50ms 内抛出异常;通过切片 Y 中的错误行强制测试验证”;“功能速度要足够快” → “100 个并发用户下,搜索延迟 p95 低于 200ms;通过切片 X 中的负载测试验证”。如果
docs/solutions/显示此功能涉及的模块曾出现缺陷聚集,那么 SMART 标准应明确提出能捕获既往缺陷的断言或监控。(对于每项可观测性 AC,请注明发出调用的文件或步骤,并确认该文件或步骤可以访问 SDK。如果发出点是客户端组件,却试图调用仅限服务端的 SDK——即读取服务端凭据或要求仅限 Node 的运行时的 SDK——则必须将 AC 移至上游服务端边界,或将客户端→服务端路由纳入范围。如果无法立即确定如何迁移,应将其作为复杂问题,并用一句话给出解决方案。SDK 的类型签名决定了可编译内容的上限;SDK 实际能够发出调用的运行时边界决定了可运行内容的下限。) - 信任边界——只要数据流两端由不同主体控制,就构成边界(浏览器↔服务端、服务端↔第三方 API、Webhook 发送方↔接收方、上传内容↔解析器、LLM 输出↔任何会据此采取行动的对象)。指出该功能新增或变更的每个跨界点,并针对每个跨界点列出一项威胁及其缓解措施(例如“调用方提供 ID → 读取前先检查所有权”)。每项都应在对应切片的 AC 中纳入两项测试——一项利用未缓解的情形,另一项尝试绕过缓解措施——或作为复杂问题并用一句话给出解决方案,或声明为禁止事项。禁止事项不得代表用户接受风险。若没有跨界点,只需写一次“无”。
- 数据库迁移或架构变更
- 加载、空白和部分状态(UI 功能)
- 数据回填或现有记录迁移
- 部署或环境变更(新增环境变量、功能标记)
- 清理将被替换的代码路径
- 此变更可能影响现有功能的边缘情况
- API 契约影响:请求/响应结构变更、增量变更与破坏性变更的风险、身份验证或范围变更、Webhook 验证,以及面向开发者的错误契约 对于适用但被遗漏的类别:将其加入用户故事,将其列为带有解决方案的 Rabbit Hole,或声明为 No-go。不要让它被隐藏。
如果此功能会改变或引入重要的 API 契约,且访谈后契约形式仍不够明确,请在最终确定方案前调用 /api-design-review。
如果缺少任何属性,请回到访谈中补齐。
7. 设计模块
勾勒出完成实现所需构建或修改的主要模块。主动寻找机会,提取可独立测试的深模块。
深模块(相对于浅模块而言)是指封装大量功能,同时提供简单、可测试且很少变化的接口的模块。
对于内部状态复杂的每个模块:找出关键不变量;一旦违反该不变量,就会导致静默损坏,而非立即失败。将其记入“实现决策”部分——实现者应为其添加前置条件或 isValid() 检查。
你在正文中提到的每种机制都必须有归属。 离开此步骤前,逐项检查 §Solution 和 Must-haves 中的流程行,梳理其中提到的每种机制——每种数据结构、预计算输入、后台任务、缓存或预置状态。每种机制都必须且只能归入以下四类之一:此处的 Modules 条目、附有解决方案的 Rabbit Hole、No-go 条目,或独立的 Must-have 故事。
第四类最容易被作者遗漏。前置条件本身可以是一个完整的用户目标,而非其他目标的一部分——Cockburn 举例说,客户想要租借视频,但必须先设置会员资格;他特意将其列出,以免撰写者将其“修正”为错误的层级关系(第 5 章)。当某种机制本身就是用户想要完成的事项时,就应将其提升为故事;这样它才会进入 /prd-to-issues 第 5 步的未映射 Must 中止检查。正文中提到的机制如果没有归入上述四类,下游就会看不到它:第 4 步会读取 §Implementation Decisions 中已锁定的契约形式,因此没有模块的机制会让边界映射推导无从发现。
请与用户确认这些模块是否符合他们的预期。询问用户希望为哪些模块编写测试,以及要在哪一层边界进行测试。
如果用户不确定某个模块的接口,或者存在多个各有实际利弊的可行设计(例如,一个方法完成所有操作,还是三个可组合的方法;回调 API,还是事件发射器),请调用 /design-an-interface,通过并行子 Agent 生成 2–3 个截然不同的选项。向用户展示这些选项及其利弊,并让用户选择。如果接口显而易见,或用户已有明确偏好,则跳过此步骤并继续。
如果不确定之处在于 API 契约本身——范式选择、请求/响应形式、Webhook 模型、身份验证模型或兼容性策略——请调用 /api-design-review,而不是将其当作常规模块接口问题来处理。
8. 撰写提案
在你完整、清晰地理解问题和解决方案后,使用以下模板撰写提案。保存位置取决于项目。
先询问 PRD 存放在哪里。 根据 references/state-backend.md,backend prds 会给出答案:
SC="<this skill's directory>/references/sidecar.sh"
BACKEND="$(bash "$SC" backend prds)" || BACKEND=
case "$BACKEND" in
github) echo "prds backend: github" ;;
sidecar) echo "prds backend: sidecar" ;;
*) echo "prds backend: refused; stop and relay the stderr above" >&2; exit 1 ;;
esac
github:按照以下步骤,将提案作为 GitHub issue 提交。sidecar:将提案保存为 sidecar 工作项,而不是 GitHub issue。运行下方 在 sidecar 上保存 部分的代码块,并将模板正文放在占位行处。不要创建 GitHub issue 或里程碑。模板末尾的 Next session 行不保存到正文中,因为在work create打印出 ID 之前,该 ID 并不存在。将这些行打印给用户,格式为/prd-to-issues W-<n>,绝不要使用#<n>。- 其他情况(退出码非零,因此没有打印任何内容):停止,并转述
backend在 stderr 上打印的内容。不要回退到gh issue create。在访客仓库中,这样会把提案放进客户端的跟踪系统。
在 sidecar 上保存。 下方的每个代码块都是独立的,因为每次工具调用都会启动一个全新的 shell:它会自行设置 SC 和正文文件,不会沿用上方 backend 代码块中的任何内容。将占位行替换为模板正文,并将 MILESTONE 设置为步骤 2 记录的名称,或者留空。代码块会打印新的 ID:W-<n>。
SC="<this skill's directory>/references/sidecar.sh"
MILESTONE=""
f="$(mktemp)"
cat > "$f" <<'PITCH'
<the pitch body, from the template below>
PITCH
set -- --kind prd
if [ -n "$MILESTONE" ]; then set -- "$@" --milestone "$MILESTONE"; fi
bash "$SC" work create "$@" --body-file "$f"
如果输入的是 research-ready 工作项,请就地扩展该工作项,而不是创建第二个工作项。将其 ID 填入 ID:
SC="<this skill's directory>/references/sidecar.sh"
ID="W-<n>"
f="$(mktemp)"
cat > "$f" <<'PITCH'
<the pitch body, from the template below>
PITCH
bash "$SC" work edit "$ID" --body-file "$f" && bash "$SC" work set "$ID" maturity prd
如果步骤 2 要求创建容器里程碑,且后端是 github,请在 PRD issue 之前创建里程碑,以便将 issue 关联到该里程碑:
- 创建里程碑:
gh api repos/{owner}/{repo}/milestones -f title="<Milestone Name>" -f description="<1-2 sentences from the problem story>" - 创建 PRD issue,并使用
--milestone "<Milestone Name>"将其关联到里程碑 - 在提案输出中注明里程碑名称,以便
/prd-to-issues将其传递给切片 issue
问题
讲述一个具体故事,说明现状为何行不通。聚焦一个角色、一次尝试、一次失败。不要抽象地抱怨,而要描绘一个让痛点具体可感的场景。
投入
小批次(1-2 周)或大批次(6 周)。说明为什么这个问题值得投入相应的时间,但不值得投入更多。
明确说明,投入时间是解决这个问题值得花费时间的目标,而不是当前的工期估算,也不是交付承诺。
目标 / 估算 / 承诺
[当存在时间、范围或截止日期压力时填写。没有有意义的时间安排讨论时省略。]
- 目标:[期望的业务成果、活动日期或预算界限]
- 当前估算:[范围或置信度阶梯,不要给出虚假的精确单点数值]
- 承诺态度:[尚未承诺 / 解决 X 后有条件承诺 / 明确承诺]
不确定性 / 置信度
[当时间或范围的置信度会实质性影响提案时填写。低压力的需求塑形工作可省略。]
- 当前置信度:[高 / 中 / 低]
- 主要不确定因素:[在估算收敛前必须了解或决定的事项]
- 如何提高置信度:[原型、研究结论、首个 tracer bullet、合同决策等]
解决方案
经过梳理的概念。保留足够的开放空间,让构建者自行判断;同时解决得足够充分,让整体方向清晰,并填补明显的漏洞。范围受上文的意愿约束。
描述从用户视角来看会有哪些变化。在有帮助的地方,可以从架构层面描述方案,但不要规定应由构建者决定的实现细节。
如果问题有明确的结构性诱因,请在此简要说明——只需足以解释为什么该方案针对的是造成痛点的根本条件,而非最近的表象。
如果解决方案依赖库提供的回调(Agent 钩子、中间件、生命周期方法、工具处理器)进行设计,请按文件:行号引用 research.md(第 1.25 阶段)中的库回调契约快照。除非 X 和 Y 原样出现在已接受的返回形状中,否则不要将机制描述为“通过 X 注入”或“传入 Y”。库的 .d.ts 中不存在的臆想机制,正是 /research 第 1.25 阶段要防止的偏差。
[图示建议:离开“解决方案”部分之前,考虑上文内容是否用图示表达会更清晰——例如流程图、时序图、架构草图、状态机、决策树或前后对比图。列表和正文仍是权威内容;图示只是辅助阅读,便于 /prd-to-issues 拆解任务和 /execute 冷启动。如果合适,请调用 /mermaid。如果图示就是读者会快速浏览的整个方案要点,而非其中的一张图,/visual-recap 会将 PRD 呈现为一个临时 HTML 文件,其中包含展示本方案承诺的决策卡片、展示尚未定案选项的对比图,以及这张图示。这是可选功能,绝不会自动调用,也不是 PRD 的要求;无论如何,问题正文始终是真实依据。如果解决方案足够简短、线性,正文已经是最清晰的表达方式,就跳过此步骤——判断标准是:不熟悉代码库的读者看图后是否比不看图更快理清思路。此提示放在“解决方案”部分末尾(而不是嵌套在条件流程行中),因此无论解决方案采用 UI 流程、架构、重构/替换还是状态机形式,都会触发此提示——将之前由流程草图触发的提示,以及 chrislacey89/skills#90 中提出的重构/替换触发条件,合并为一个与形式无关的提示。]
潜在陷阱
明确列出的风险,并为每项预先确定一句话解决方案。如果不加审视,这些未知因素可能导致一个原本为期 6 周的项目拖到 18 周。提前列出并给出解决方案,构建者就不必在截止日期压力下做出这些决定。
- [风险名称]:[一句话解决方案]
不包含的内容
明确列出排除项。不提及就意味着“包含在范围内”,因此凡是构建者可能合理地认为包含、但实际上不包含的内容,都必须在此列出。这些不是“以后再说”的事项,而是有意设定的边界。
- [明确排除的事项]
用户故事
必须具备
- 作为[角色],我希望[功能],以便[收益]
- [位置名称]:[交互方式 1]、[交互方式 2] -> 连接到[其他位置]
- [其他位置]:[交互方式 3] -> 连接到……
[缩进行是流程行,仅在功能涉及多步骤的面向用户流程、新导航或显著的 UI 状态变化时才添加。对于仅涉及 API、后端或单屏的变更,请省略。对每个实现该需求的 Must,都重复添加相应行;没有实现任何 Must 的行则放在下方的共享交互方式中。]
可有可无(~)
- ~作为[角色],我希望[功能],以便[收益]
通用界面元素(未归属)
[仅当存在流程行且某些行不服务于任何单一 Must 时才包含——导航界面、加载和空状态、全局错误界面。这些不是承诺;/prd-to-issues 不会将它们视为未映射的 Must。若每一行都找到了归属项,则完全省略此标题。]
用户故事受投入周期的限制。Must-have 定义了最低限度的可发布版本——也就是让产品比用户当前基线更好的部分。Nice-to-have 是预先授权的删减项:如果投入周期所剩无几,就直接砍掉这些范围,无需讨论。prd-to-issues 会将每个垂直切片映射回这些故事;若某个 Must 包含流程行,则会按界面元素粒度进行映射。
API 契约草案
[仅当该功能引入或更改 API 契约时才包含。保持简洁并以使用者为中心,不要深入实现细节。]
- 问题陈述: [此 API 要解决的开发者问题]
- 影响陈述: [此 API 可带来的结果]
- 使用者: [谁会集成此 API]
- 操作: [此 API 必须允许使用者执行的操作]
- 接口草图: [高层次的端点/事件]
- 重要字段: [对使用者而言重要的必填/可选字段及默认值]
- 错误格式: [机器可读的代码 + 人类可读的消息]
- 兼容性: [新增兼容/可能存在破坏性变更/存在破坏性变更]
- 其他考虑过的方案: [被否决的范式或契约方向]
实现决策
已做出的实现决策列表。可包括:
- 将要构建/修改的模块
- 将要修改的模块接口
- 开发者提供的技术澄清
- 架构决策
- 架构变更
- API 契约
- 特定交互
不要包含实现代码片段——循环体、错误处理、辅助函数内部逻辑、配置字符串字面量。这些内容会在构建者做出判断后立刻过时。
[读者会快速浏览本节,因为项目符号列表中没有任何标记能指出哪些决策会排除其他可能性。若某项决策会排除其他可能性——例如线格式、公共 ID、所有权边界、数据模型形态——/visual-recap 可以将其整理为决策卡片:已决定、排除项、何时反转、来源,并且每个字段都引用正文,或明确标记为已断言。此功能为可选且临时,不会取代在此处记录决策。]
当 PRD 的决策存在于接口层面时,确实要用代码形式呈现已锁定的契约形态:例如 Schema 字段列表(Drizzle、Prisma、SQL DDL)、导出的类型别名或接口、导出的函数签名、结构化输入/输出 Schema(Zod、JSON Schema)。判断标准是实际用途:如果下游流水线步骤(/prd-to-issues Boundary Map、/execute Consumes 验证、/pre-merge 契约边界审查)会查找此标识符或形态,那么它就是契约形态,应以代码形式呈现。如果没有下游步骤会原样继承它,那它就是实现细节,应以文字描述或省略。契约形态代码会随着 PRD 的重新协商路径以相同速度发生变化——编辑 PRD 正文并重新生成 Coverage Matrix,与更改任何其他 PRD 内容的流程相同。
Research Reference
[仅在存在匹配的研究产物时包含。使用与项目的 research.storage 模式相匹配的格式。若为归档模式,请填写 § 4 打印的清单中的绝对路径。]
Spike issue 模式(存在时优先使用):
此功能的技术研究记录在 spike issue Refs # 中(创建时即关闭的快照,标签为 research)。关键建议:
- [研究中建议的方案]
- [研究中的关键约束或权衡]
实现人员应在开始工作前阅读该 spike issue(任何机器上均可运行 gh issue view <spike-issue-number>)。
归档模式(不存在 spike issue 时的备用方案):
此功能的技术研究记录在 <absolute path to the research entry>(仓库之外)。关键建议:
- [研究中建议的方案]
- [研究中的关键约束或权衡]
实现人员应在开始工作前阅读研究文档。所引用的路径位于仓库之外(/research Phase 5c 说明了具体位置),因此除发起用户外,其他读者都无法打开该文件。对于跨机器、多人协作或面向公众的 PRD,请将项目切换为 spike issue 模式(参见 /research Phase 5a)。
过往方案的经验
[仅在找到相关的 docs/solutions/ 文件时包含]
以下已记录的方案为此提案提供了参考:
docs/solutions/<path>— [所应用的经验]
下一会话: /prd-to-issues # 输入: PRD issue 正文
不要直接对此 issue 调用 /execute —— 这是一个经过梳理的提案,而非一个切片。请明确打印 issue 编号,以便下一会话可通过复制粘贴开启,而不必费力查找。
交接
- 预期输入: 已明确的用户问题、经
/research验证的技术背景,以及与该功能相关的过往方案指导 - 产出: 经过梳理的 PRD issue(大型批次工作时可选择附加到容器里程碑),其中包含工作量、方案、潜在岔路、明确不做的事项,以及在相关情况下的契约草案。使用 sidecar 后端时,则改为产出
W-<n>sidecar 工作项,并将里程碑记录为一个字段。 - 可能调用: 当模块接口仍未确定时调用
/design-an-interface;当 API 契约仍存在不确定性时调用/api-design-review - 默认后续步骤:
/prd-to-issues