名称: prd-generator 描述: 使用假设驱动方法和实施阶段跟踪生成结构化的产品需求文档。 版本: 1.0 模型: sonnet 调用者: agent 用户可调用: false 工具: [Read, Write, AskUserQuestion] 分配代理: [pm] 最佳实践:
- 问题优先于解决方案
- 证据支持的假设
- 使用MoSCoW进行优先级排序
- 实施阶段表格用于可追溯性 错误处理: standard 流式处理: supported 已验证: false 最后验证时间: 2026-02-19T05:29:09.098Z
PRD生成器技能
概述
生成结构化的产品需求文档(PRD),使用问题优先、假设驱动的方法。确保清晰的问题陈述、证据支持的决策和可追踪的实施阶段。
核心原则:在“如何”之前验证“为什么”。问题 → 证据 → 假设 → 解决方案。
何时使用
始终使用:
- 需要产品定义的新功能
- 需要利益相关者对齐的产品变更
- 高复杂度或史诗级功能的需求收集
- 需要结构化分析的功能请求
特定使用:
- 需求不明确的功能(渐进式披露)
- 需要跟踪的多阶段实施
- 需要决策文档的功能
- 需要成功指标的产品计划
不要使用:
- 简单的错误修复(不需要PRD)
- 琐碎的配置更改
- 无产品影响的仅代码重构
目的
- 问题优先:在提出解决方案前,用证据定义问题
- 假设驱动:陈述可测量的假设以进行验证
- MoSCoW优先级排序:使用必须/应该/可以/不会来防止范围蔓延
- 实施阶段:通过阶段表格跟踪进度(状态、依赖项、计划链接)
- 决策日志:记录“为什么选择X而不是Y”以供未来参考
- 可追溯性:PRD → 规划者 → 开发者,具有完整上下文
工作流程
步骤1:收集需求
交互模式(当需求不明确时):
// 使用AskUserQuestion进行结构化收集
const problem = await AskUserQuestion({
question: '解决什么问题?(具体描述用户痛点)',
});
const evidence = await AskUserQuestion({
question: '有什么证据表明这个问题存在?(数据、反馈、指标)',
});
const hypothesis = await AskUserQuestion({
question: '什么可测量的结果能证明这个功能解决了问题?',
});
提示模式(当需求已提供时):
从用户提示或任务描述中提取需求
渐进式披露(用于模糊功能):
如果需求不明确,使用8阶段提问工作流程:
- 启动:澄清功能目标和范围
- 基础:理解问题上下文
- 接地(市场):研究类似解决方案
- 深度探讨:探索能力和用户流程
- 接地(技术):评估可行性
- 决策:文档选择和权衡
- 生成:从收集的上下文创建PRD
何时使用渐进式披露:
- 高复杂度或史诗级功能
- 模糊的用户请求(如“让它更好”)
- 无现有模式的新产品领域
- 需要利益相关者对齐的功能
何时跳过:
- 提供了清晰的需求
- 已构建类似功能
- 小范围更改
步骤2:加载模板
// 读取PRD模板
const template = Read({ file_path: '.claude/templates/prd-template.md' });
模板包括以下部分(必需):
- 问题陈述
- 证据
- 关键假设
- 我们不构建什么(范围排除)
- 成功指标表格
- 核心能力(MoSCoW)
- 用户与上下文
- 解决方案详情(MVP范围、用户流程)
- 技术方法
- 实施阶段表格
- 决策日志表格
- 研究摘要
- 风险表格
- 开放问题
步骤3:填充模板部分
问题陈述(证据支持):
## 问题陈述
[具体问题描述,包括用户影响]
## 证据
- 用户反馈:[引用或摘要]
- 数据:[显示问题规模的指标]
- 业务影响:[为什么现在很重要]
关键假设:
## 关键假设
我们相信[能力]将为[用户]解决[问题]。
当我们看到[可测量的结果]时,就知道我们是对的。
示例:
我们相信添加JWT刷新令牌将减少移动用户的重新认证摩擦。
当我们看到会话超时投诉减少50%且移动日活跃用户增加10%时,就知道我们是对的。
成功指标:
| 指标 | 目标 | 如何测量 |
|---|---|---|
| 会话超时投诉 | -50% | 支持工单分析 |
| 移动日活跃用户 | +10% | 分析仪表板 |
| 令牌刷新成功率 | >95% | 后端日志 |
核心能力(MoSCoW):
| 优先级 | 能力 | 理由 |
|---|---|---|
| 必须 | JWT刷新令牌端点 | 需要用于MVP - 启用会话扩展 |
| 必须 | 刷新时的令牌轮换 | 安全最佳实践 |
| 应该 | 刷新令牌撤销 | 允许用户从所有设备注销 |
| 可以 | 令牌使用分析 | 用于监控,不错的功能 |
| 不会 | 生物识别认证集成 | 超出范围 - 未来考虑 |
MoSCoW定义:
- 必须:MVP阻塞器 - 没有这个,功能失败
- 应该:高价值,时间允许时包括
- 可以:不错的功能,需要时可推迟
- 不会:明确从当前范围排除
用户与上下文:
## 用户与上下文
**主要用户**:移动应用用户(iOS/Android),在工作流中经历会话过期
**当前行为**:用户登录 → 会话在1小时后过期 → 强制重新登录 → 丢失上下文
**触发**:活跃使用期间的会话过期
**成功状态**:用户无缝保持登录,仅在真正需要时重新认证
**待完成工作**:当我的会话过期时,我希望在不重新输入凭证的情况下继续工作,以维持工作流动量。
实施阶段表格:
| # | 阶段 | 描述 | 状态 | 并行 | 依赖 | 计划链接 |
|---|---|---|---|---|---|---|
| 1 | 设计 | 具有刷新令牌流的认证架构设计 | pending | No | - | - |
| 2 | 后端API | 实现带令牌轮换的/refresh端点 | pending | No | 1 | - |
| 3 | 移动客户端 | 向移动SDK添加刷新逻辑 | pending | No | 2 | - |
| 4 | 测试 | 刷新流程的端到端测试 | pending | Yes | 2,3 | - |
| 5 | 监控 | 向仪表板添加刷新指标 | pending | Yes | 2 | - |
阶段列解释:
- #:阶段编号
- 阶段:短阶段名称
- 描述:此阶段构建的内容
- 状态:pending | in_progress | completed | blocked
- 并行:是否可以与其他阶段并行运行?
- 依赖:哪些阶段必须先完成?(逗号分隔的数字)
- 计划链接:链接到规划者的实施计划(.claude/context/plans/impl-{phase}-{date}.md)
决策日志:
| 决策 | 选择 | 替代方案 | 理由 |
|---|---|---|---|
| 令牌存储 | 安全存储(Keychain/KeyStore) | 本地存储、会话存储 | 安全要求 - 令牌是敏感的 |
| 刷新策略 | 在401上自动 | 手动用户操作 | 更好的用户体验 - 对用户透明 |
| 令牌生命周期 | 访问:1小时,刷新:30天 | 访问:5分钟,刷新:90天 | 平衡安全和用户体验 |
研究摘要:
## 研究摘要
**市场上下文**:
- Auth0、Firebase使用类似的刷新令牌模式
- 行业标准:短寿命访问 + 长寿命刷新
- OWASP推荐在刷新时轮换令牌
**技术上下文**:
- 现有JWT库支持刷新
- 移动SDK具有安全存储
- 后端已有会话管理
风险:
| 风险 | 可能性 | 缓解措施 |
|---|---|---|
| 令牌盗窃 | 中 | 使用安全存储,刷新时轮换 |
| 刷新循环(无效令牌) | 低 | 添加指数退避,最大重试限制 |
| 时钟偏差问题 | 低 | 使用5分钟宽限期进行过期验证 |
开放问题:
## 开放问题
- [ ] 密码更改时活跃刷新令牌会发生什么?
- [ ] 在网络中断期间如何处理令牌刷新?
- [ ] 刷新令牌过期时是否应通知用户?
步骤4:验证完整性
必需部分检查清单:
const requiredSections = [
'问题陈述',
'证据',
'关键假设',
'成功指标',
'核心能力',
'实施阶段',
'决策日志',
];
// 验证所有存在
const missingRequiredSections = requiredSections.filter(section => !prdContent.includes(section));
if (missingRequiredSections.length > 0) {
throw new Error(`缺少必需部分:${missingRequiredSections.join(', ')}`);
}
质量检查:
- [ ] 问题陈述具体(不模糊)
- [ ] 证据包括数据或用户反馈
- [ ] 假设可测量(包括指标)
- [ ] MoSCoW有至少1个“必须”和1个“不会”
- [ ] 实施阶段有依赖映射
- [ ] 决策日志解释“为什么不选择X”用于替代方案
步骤5:写入PRD
// 生成文件名
const featureName = 'auth-refresh-tokens'; // 从问题陈述中获取
const date = new Date().toISOString().split('T')[0]; // YYYY-MM-DD
const filename = `${featureName}-prd-${date}.md`;
// 写入规范目录
Write({
file_path: `.claude/context/artifacts/specs/${filename}`,
content: prdContent,
});
输出位置:.claude/context/artifacts/specs/{feature-name}-prd-{YYYY-MM-DD}.md
出处标头:
<!-- 代理: pm | 任务: #{task-id} | 会话: {date} -->
# PRD: {功能名称}
**版本**: 1.0
**作者**: PM代理
**日期**: {YYYY-MM-DD}
**状态**: 草案
集成点
PRD → 规划者 → 开发者流程
PM创建PRD:
## 实施阶段
| # | 阶段 | 描述 | 状态 | 并行 | 依赖 | 计划链接 |
| --- | ------- | ----------------- | ------- | -------- | ------- | --------- |
| 1 | 设计 | 认证架构 | pending | No | - | - |
| 2 | 后端 | /refresh端点 | pending | No | 1 | - |
规划者读取PRD:
- TaskGet({ taskId: ‘X’ }) → 获取PRD位置
- 读取PRD → 理解问题、决策、阶段
- 选择下一个待处理阶段(依赖满足)
- 创建实施计划
- 更新PRD计划链接:
| 1 | 设计 | 认证架构 | completed | No | - | [计划](.claude/context/plans/impl-phase1-2026-02-09.md) |
开发者读取计划:
- 规划者的计划链接回PRD
- 开发者具有完整上下文:问题、决策、理由
- 实现时理解“为什么”
结果:
- 单一真实来源:检查PRD阶段表格获取状态
- 可追溯性:PRD → 计划 → 实施
- 上下文保存:新开发者可以读取PRD以理解功能
必需部分检查清单
写入PRD前,验证:
- [ ] 问题陈述(具体,不模糊)
- [ ] 证据(数据、反馈、指标)
- [ ] 关键假设(可测量的结果)
- [ ] 成功指标表格(指标 | 目标 | 如何测量)
- [ ] 核心能力(MoSCoW,带必须/应该/可以/不会)
- [ ] 实施阶段表格(# | 阶段 | 状态 | 依赖 | 计划链接)
- [ ] 决策日志(决策 | 选择 | 替代方案 | 理由)
- [ ] 用户与上下文(主要用户、待完成工作)
- [ ] 技术方法(可行性、依赖项)
- [ ] 风险表格(风险 | 可能性 | 缓解措施)
- [ ] 开放问题(未解决项)
常见模式
模式1:功能请求 → PRD
用户: “向应用添加深色模式”
PM:
1. 问题: 用户报告在低光条件下眼睛疲劳
2. 证据: 200+支持工单,应用评分从4.2降至3.8提到“太亮”
3. 假设: 深色模式将减少眼睛疲劳投诉60%
4. MoSCoW:
- 必须: 系统默认主题检测
- 必须: 设置中的手动切换
- 应该: 每屏主题覆盖
- 不会: 基于日落的自动切换(未来)
5. 阶段:
- 阶段1: 设计系统颜色令牌
- 阶段2: 实现主题提供者
- 阶段3: 更新所有屏幕
6. 写入PRD → specs/dark-mode-prd-2026-02-09.md
模式2:模糊请求 → 渐进式披露
用户: “让应用更快”
PM:
1. [渐进式披露: 8阶段提问]
- 什么具体缓慢?(应用启动?导航?数据加载?)
- 证据在哪里?(指标显示应用启动5秒 vs 竞争对手2秒)
- 什么结果?(启动时间<2秒,第95百分位)
2. [收集上下文后]
- 问题: 应用启动时间5秒 vs 行业2秒
- 假设: 延迟加载模块将减少启动至<2秒
3. 写入PRD → specs/app-launch-performance-prd-2026-02-09.md
模式3:实施期间的PRD更新
规划者完成阶段1设计:
更新PRD:
| 1 | 设计 | 认证架构 | completed | No | - | [计划](.claude/context/plans/impl-phase1-2026-02-09.md) |
| 2 | 后端 | /refresh端点 | in_progress | No | 1 | [计划](.claude/context/plans/impl-phase2-2026-02-09.md) |
添加决策到日志:
| 令牌算法 | RS256 | HS256 | RS256用于密钥轮换支持 |
最佳实践
做:
- 从问题开始,而不是解决方案
- 包括证据(数据、引用、指标)
- 使假设可测量
- 明确记录“不会”(防止范围蔓延)
- 清晰映射阶段依赖项
- 记录考虑过的替代方案的决策
- 链接阶段到实施计划
- 随着阶段完成更新PRD
不做:
- 没有问题陈述就跳到解决方案
- 跳过证据收集
- 使用模糊的成功指标(如“让它更好”)
- 忘记优先级排序(一切都是“必须”)
- 创建没有依赖映射的阶段
- 跳过决策理由
- 让PRD过时(随着进展更新)
- 为琐碎更改写PRD
铁律
没有问题定义之前不要提出解决方案
如果您不理解问题,就无法创建有效的PRD。对于不明确的需求,使用渐进式披露。
示例:完整PRD
<!-- 代理: pm | 任务: #42 | 会话: 2026-02-09 -->
# PRD: JWT刷新令牌实现
**版本**: 1.0
**作者**: PM代理
**日期**: 2026-02-09
**状态**: 草案
---
## 问题陈述
移动应用用户在活跃使用期间经历会话过期(1小时超时),强制重新认证并丢失工作流上下文。这造成摩擦和挫折,特别是执行多步骤任务的用户。
## 证据
- **支持工单**: 过去2个月200+关于“强制注销”的投诉
- **分析**: 35%的移动会话以强制重新认证结束(vs 5%桌面)
- **用户反馈**: 应用商店评论提到“烦人的登录提示”(评分从4.2降至3.8)
- **业务影响**: 15%的购物车放弃率与会话超时相关
## 关键假设
我们相信添加JWT刷新令牌将减少移动用户的重新认证摩擦。
当我们看到会话超时投诉减少50%且移动日活跃用户增加10%时,就知道我们是对的。
## 我们不构建什么
- 生物识别认证集成(未来阶段2)
- 社交登录提供者(单独计划)
- 多设备会话管理(v2.0)
## 成功指标
| 指标 | 目标 | 如何测量 |
| -------------------------- | ------ | ----------------------- |
| 会话超时投诉 | -50% | 支持工单分析 |
| 移动日活跃用户 | +10% | 分析仪表板 |
| 令牌刷新成功率 | >95% | 后端日志 |
| 强制重新认证率 | <10% | 分析事件 |
## 核心能力(MoSCoW)
| 优先级 | 能力 | 理由 |
| -------- | ---------------------------------------- | -------------------------------------------- |
| 必须 | JWT刷新令牌端点 | 需要用于MVP - 启用会话扩展 |
| 必须 | 刷新时的令牌轮换 | 安全最佳实践(OWASP) |
| 必须 | 安全令牌存储(Keychain/KeyStore) | 防止令牌盗窃 |
| 应该 | 刷新令牌撤销 | 允许用户从所有设备注销 |
| 应该 | 令牌使用分析 | 监控和调试 |
| 可以 | 可配置令牌生命周期 | 管理员灵活性 |
| 不会 | 生物识别认证集成 | 超出范围 - 未来考虑 |
| 不会 | 令牌过期时的推送通知 | 不错的功能,推迟到v2 |
## 用户与上下文
**主要用户**: 移动应用用户(iOS/Android),在活跃使用期间(购物、填写表单、浏览)经历会话过期
**当前行为**: 用户登录 → 执行任务 → 会话在1小时后过期 → 强制重新登录 → 丢失表单数据/购物车上下文
**触发**: 活跃使用期间的会话过期或应用在>1小时后从后台返回
**成功状态**: 用户无缝保持登录长达30天(刷新令牌寿命),仅在真正需要时重新认证
**待完成工作**: 当我的会话过期时,我希望在不重新输入凭证的情况下继续工作,以维持工作流动量并完成任务。
## 解决方案详情
### MVP范围
**阶段1**: 设计具有刷新令牌流的认证架构
**阶段2**: 实现带令牌轮换的后端/refresh端点
**阶段3**: 向移动SDK(iOS/Android)添加刷新逻辑
**阶段4**: 刷新流程的端到端测试
**阶段5**: 向监控仪表板添加刷新指标
### 用户流程
1. 用户登录 → 接收访问令牌(1小时)+ 刷新令牌(30天)
2. 用户进行API调用 → 服务器验证访问令牌
3. 访问令牌过期 → 下一个API调用返回401
4. 移动SDK检测到401 → 使用刷新令牌调用/refresh
5. 服务器验证刷新令牌 → 颁发新的访问 + 刷新令牌
6. SDK使用新访问令牌重试原始API调用
7. 用户无缝继续(无需重新登录)
### 边缘情况
- 刷新期间网络故障 → 使用指数退避重试
- 刷新令牌过期 → 强制重新登录,显示“会话过期”消息
- 刷新令牌撤销(密码更改) → 强制重新登录
- 刷新期间的并发API调用 → 队列并在刷新完成后重试
## 技术方法
**可行性**: 高
**依赖项**:
- 现有JWT库(jsonwebtoken)支持刷新
- 移动SDK具有安全存储(Keychain/KeyStore)
- 后端具有会话管理基础设施
**集成点**:
- 移动SDK(iOS/Android)需要刷新拦截器
- 后端需要/refresh端点
- 数据库需要刷新令牌存储(带过期)
**架构说明**:
- 访问令牌: 1小时寿命,无状态(JWT)
- 刷新令牌: 30天寿命,有状态(存储在数据库中)
- 令牌轮换: 每次刷新使旧令牌无效,颁发新令牌
- 安全存储: Keychain(iOS)、KeyStore(Android)
## 实施阶段
| # | 阶段 | 描述 | 状态 | 并行 | 依赖 | 计划链接 |
| --- | ----------- | ------------------------------------------------ | ------- | -------- | ------- | --------- |
| 1 | 设计 | 具有刷新令牌流的认证架构设计 | pending | No | - | - |
| 2 | 后端API | 实现带令牌轮换的/refresh端点 | pending | No | 1 | - |
| 3 | 移动SDK | 向iOS/Android SDK添加刷新逻辑 | pending | No | 2 | - |
| 4 | 测试 | 刷新流程的端到端测试 | pending | Yes | 2,3 | - |
| 5 | 监控 | 向仪表板添加刷新指标 | pending | Yes | 2 | - |
## 决策日志
| 决策 | 选择 | 替代方案 | 理由 |
| ---------------- | ---------------------------------- | -------------------------------------- | ------------------------------------------------------- |
| 令牌存储 | 安全存储(Keychain/KeyStore) | 本地存储、会话存储 | 安全要求 - 令牌是敏感凭证 |
| 刷新策略 | 在401上自动 | 手动用户操作、主动刷新 | 更好的用户体验 - 对用户透明,无额外UI |
| 令牌生命周期 | 访问: 1小时, 刷新: 30天 | 访问: 5分钟/90分钟, 刷新: 7/90天 | 平衡安全(短访问)和用户体验(长刷新) |
| 令牌算法 | RS256(非对称) | HS256(对称) | 启用密钥轮换,更适合分布式系统 |
| 刷新轮换 | 总是轮换 | 在可疑活动时轮换 | OWASP最佳实践,防止令牌重放 |
| 存储位置 | 数据库 | Redis、内存中 | 需要持久存储,数据库已可用 |
## 研究摘要
**市场上下文**:
- Auth0、Firebase、Okta都使用刷新令牌模式
- 行业标准: 短寿命访问 + 长寿命刷新
- OWASP推荐每次刷新时轮换令牌
- JWT RFC 7519和OAuth 2.0 RFC 6749定义模式
**技术上下文**:
- 现有后端使用jsonwebtoken库(支持刷新)
- 移动SDK具有安全存储能力
- 后端具有会话管理和令牌存储数据库
- 平均API延迟: 100毫秒(刷新不会显著影响用户体验)
**可行性评估**: 高
- 所有依赖项可用
- 无需新基础设施
- 清晰的实施路径
- 范围蔓延风险低
## 风险
| 风险 | 可能性 | 缓解措施 |
| ------------------------------ | ---------- | --------------------------------------------------------- |
| 令牌盗窃(XSS/MITM) | 中 | 使用安全存储,仅HTTPS,刷新时轮换 |
| 刷新循环(无效令牌) | 低 | 添加指数退避,最大3次重试,回退到登录 |
| 时钟偏差问题 | 低 | 使用5分钟宽限期进行过期验证 |
| 数据库性能(令牌查找) | 低 | 索引刷新令牌,实现令牌清理作业 |
| 并发刷新尝试 | 低 | 刷新期间使用互斥/锁,队列待处理请求 |
## 开放问题
- [ ] 密码更改时活跃刷新令牌会发生什么?(决策: 撤销所有)
- [ ] 在网络中断期间如何处理令牌刷新?(决策: 使用退避重试)
- [ ] 刷新令牌过期时是否应通知用户?(决策: 是,显示“会话过期”消息)
- [ ] 是否需要每设备刷新令牌?(决策: 是,用于“从所有设备注销”功能)
---
_生成: 2026-02-09_
_状态: 草案_
相关技能
progressive-disclosure- 用于不明确需求的8阶段提问task-breakdown- 将PRD阶段分解为实施任务research-synthesis- 为问题陈述收集证据
分配代理
此技能由以下调用:
pm(产品经理) - 此技能的主要用户
内存协议(强制)
开始前:
读取.claude/context/memory/learnings.md
检查:
- 先前创建的PRD
- 此代码库中的功能模式
- 常见决策和理由
完成后:
- 新PRD模式 →
.claude/context/memory/learnings.md - 重复决策 →
.claude/context/memory/decisions.md - PRD创建阻塞器 →
.claude/context/memory/issues.md
假设中断: 如果不在内存中,则未发生。