511 lines
15 KiB
Markdown
511 lines
15 KiB
Markdown
# Product Requirements Document: 统一生成工作流
|
||
|
||
**Version**: 1.0
|
||
**Date**: 2026-04-17
|
||
**Author**: Sarah (Product Owner)
|
||
**Quality Score**: 93/100
|
||
|
||
---
|
||
|
||
## Executive Summary
|
||
|
||
DreamWeaver 当前同时支持普通故事生成、完整故事生成和绘本生成,但这三类能力在系统中以不同接口、不同服务路径和不同前端消费方式存在,已经开始阻碍产品迭代。当前实现能工作,但不利于功能演化,也不利于在求职场景中讲清楚产品系统逻辑。
|
||
|
||
统一生成工作流的目标,是将“文本生成、封面生成、语音生成、绘本页生成、后处理(记忆/成就)”纳入一套统一的产品与系统模型中。对于用户,统一工作流意味着结果更稳定、失败更可解释、页面状态更清晰;对于产品和工程,统一工作流意味着需求不会在多个分叉路径中重复实现。
|
||
|
||
本 PRD 面向 DreamWeaver 求职版 MVP,重点定义统一生成工作流的目标用户、状态模型、功能边界、数据结构演进方向、前后端行为以及发布优先级。
|
||
|
||
## Implementation Snapshot
|
||
|
||
**Updated**: 2026-04-17 evening
|
||
|
||
当前代码已经从“纯目标态设计”进入“部分落地”阶段,主要进展如下:
|
||
|
||
### Already Landed
|
||
|
||
- `Story` 主记录已持久化以下统一状态相关字段:
|
||
- `generation_status`
|
||
- `image_status`
|
||
- `audio_status`
|
||
- `last_error`
|
||
- `audio_path`
|
||
- Storybook 阅读器已支持按 ID 恢复,不再只依赖 Pinia 内存态
|
||
- 故事列表页、故事详情页、绘本阅读页已接入统一状态展示
|
||
- 故事音频已支持首次生成后缓存复用
|
||
- `degraded_completed` 已在服务层和前端语义中落地
|
||
|
||
### Still Missing
|
||
|
||
- 统一的 `POST /api/generations` 风格入口尚未建立
|
||
- 普通故事、完整生成、绘本生成仍通过多条 service 路径实现
|
||
- “统一资产重试入口”尚未落地
|
||
- `partial_ready`、`retryable_assets` 等更细粒度状态仍停留在目标态
|
||
|
||
### What This Means
|
||
|
||
这份 PRD 仍然是目标态文档,但它对应的主干方向已经不是纸面方案。当前最适合的继续方式,不是重写文档,而是继续把 service workflow 和资产补全过程收拢成统一实现。
|
||
|
||
---
|
||
|
||
## Problem Statement
|
||
|
||
**Current Situation**
|
||
|
||
DreamWeaver 当前存在以下工作流层面问题:
|
||
|
||
1. **生成入口不统一**
|
||
普通故事走 `/api/stories/generate`,完整故事走 `/api/stories/generate/full`,绘本走 `/api/storybook/generate`,前端对结果的处理也不同。
|
||
|
||
2. **保存与资产补全过程不统一**
|
||
有的流程先存文本再补图,有的流程只返回绘本对象并依赖前端 store,有的流程不考虑音频状态。
|
||
|
||
3. **状态表达不统一**
|
||
系统缺少标准的“生成中、部分完成、已完成、失败、可重试”等状态定义,导致前端难以做出成熟体验。
|
||
|
||
4. **失败处理策略不统一**
|
||
图片、音频、绘本页生成失败时,系统没有统一的降级定义,用户体验和技术行为都不够稳定。
|
||
|
||
5. **恢复能力不足**
|
||
尤其是绘本路径,依赖前端内存态,页面刷新或重进后无法恢复。
|
||
|
||
**Proposed Solution**
|
||
|
||
引入统一的 Generation Workflow,将不同内容模式视为同一工作流下的不同配置,而不是完全不同的产品流程。系统将围绕一个统一对象进行组织:
|
||
|
||
- 请求输入
|
||
- 上下文准备
|
||
- 文本或绘本结构生成
|
||
- 主记录保存
|
||
- 资产异步补全
|
||
- 状态回写
|
||
- 后处理任务
|
||
|
||
**Business Impact**
|
||
|
||
统一生成工作流将带来以下影响:
|
||
|
||
- 用户更容易理解生成过程与失败反馈
|
||
- 前端可构建成熟状态体验
|
||
- 后续扩展语音缓存、绘本恢复、记忆提取等能力更顺畅
|
||
- 面试场景中可清楚展示 AI 产品的工作流设计能力
|
||
|
||
---
|
||
|
||
## Success Metrics
|
||
|
||
**Primary KPIs**
|
||
|
||
- **工作流覆盖率**:普通故事、完整故事、绘本生成全部迁移到统一工作流 >= 100%
|
||
- **部分完成可用率**:当图片或音频失败时,文本仍能可读的比例 >= 95%
|
||
- **可恢复率**:绘本和故事结果按 ID 重新打开成功率 >= 100%
|
||
- **前端状态完整度**:关键生成状态在前端均有可见反馈 >= 100%
|
||
- **新增需求复用率**:新生成能力接入时复用统一工作流步骤的比例 >= 80%
|
||
|
||
**Validation**
|
||
|
||
- 技术验证:端到端测试与手动演示
|
||
- 产品验证:能否用一张流程图清楚说明 DreamWeaver 的生成机制
|
||
|
||
---
|
||
|
||
## User Personas
|
||
|
||
### Primary Persona: 家长 / 监护人
|
||
|
||
- **Role**: 使用 DreamWeaver 为孩子生成故事内容的人
|
||
- **Goals**:
|
||
- 快速得到稳定的故事或绘本结果
|
||
- 看到清晰的生成状态
|
||
- 即使部分资产失败,仍能继续阅读
|
||
- **Pain Points**:
|
||
- 不知道系统是否仍在生成中
|
||
- 结果部分丢失后体验中断
|
||
- 页面刷新后无法找回内容
|
||
- **Technical Level**: 初中级
|
||
|
||
### Secondary Persona: 产品负责人 / 开发者
|
||
|
||
- **Role**: 维护 DreamWeaver 的产品与系统设计者
|
||
- **Goals**:
|
||
- 降低流程分裂造成的重复实现
|
||
- 统一失败处理与状态管理
|
||
- 能向他人清楚解释系统设计
|
||
- **Pain Points**:
|
||
- 同一需求在多个生成路径里改动
|
||
- 状态定义不清,难以推进前端体验
|
||
- 架构复杂度高,影响项目表达
|
||
- **Technical Level**: 中高级
|
||
|
||
---
|
||
|
||
## User Stories & Acceptance Criteria
|
||
|
||
### Story 1: 统一发起生成
|
||
|
||
**As a** 家长
|
||
**I want to** 从一个统一的创建入口发起普通故事或绘本生成
|
||
**So that** 我不需要理解系统内部差异
|
||
|
||
**Acceptance Criteria**
|
||
|
||
- [ ] 创建入口支持选择输出类型:普通故事或绘本
|
||
- [ ] 系统能根据输入类型走统一流程,而不是完全独立逻辑
|
||
- [ ] 用户提交后立即看到生成状态
|
||
|
||
### Story 2: 获得可用结果
|
||
|
||
**As a** 家长
|
||
**I want to** 在生成过程中尽快看到第一个可用结果
|
||
**So that** 我不会因等待过久而中断使用
|
||
|
||
**Acceptance Criteria**
|
||
|
||
- [ ] 文本生成完成后,主记录应被保存
|
||
- [ ] 图片、音频、绘本页可后续补全
|
||
- [ ] 即使部分资产失败,用户仍可查看文本结果
|
||
|
||
### Story 3: 恢复历史结果
|
||
|
||
**As a** 家长
|
||
**I want to** 通过故事或绘本 ID 再次打开内容
|
||
**So that** 我可以回看、继续阅读或重新播放
|
||
|
||
**Acceptance Criteria**
|
||
|
||
- [ ] 故事详情页支持按 ID 加载
|
||
- [ ] 绘本阅读器支持按 ID 加载
|
||
- [ ] 刷新页面不会导致内容丢失
|
||
|
||
### Story 4: 理解系统状态
|
||
|
||
**As a** 家长
|
||
**I want to** 知道系统目前是在生成文本、生成图片还是失败可重试
|
||
**So that** 我不会困惑或误以为系统卡住
|
||
|
||
**Acceptance Criteria**
|
||
|
||
- [ ] 前端展示统一状态模型
|
||
- [ ] 失败原因对用户可解释
|
||
- [ ] 可补全资产应有独立重试入口
|
||
|
||
### Story 5: 以统一方式扩展能力
|
||
|
||
**As a** 产品负责人
|
||
**I want to** 未来新增音频缓存、更多绘本模式或新资产时复用统一工作流
|
||
**So that** 系统能持续扩展而不继续分叉
|
||
|
||
**Acceptance Criteria**
|
||
|
||
- [ ] 工作流步骤具备清晰边界
|
||
- [x] 新能力接入时能挂入现有状态模型
|
||
- [ ] 不需要再新增完全平行的一套生成接口
|
||
|
||
---
|
||
|
||
## Functional Requirements
|
||
|
||
### Feature 1: 统一工作流模型
|
||
|
||
**Description**
|
||
所有内容生成行为必须映射到同一套工作流中,不再按“故事模式/绘本模式”分别设计完全独立的业务流程。
|
||
|
||
**Standard Workflow Steps**
|
||
|
||
1. Request Accepted
|
||
2. Context Prepared
|
||
3. Narrative Generated
|
||
4. Story Saved
|
||
5. Assets Generating
|
||
6. Partial Ready / Completed
|
||
7. Post-processing Completed
|
||
|
||
**Requirements**
|
||
|
||
- 系统需定义统一工作流状态
|
||
- 故事与绘本共享前四步
|
||
- 资产生成与后处理作为后续步骤处理
|
||
|
||
### Feature 2: 状态模型
|
||
|
||
**Description**
|
||
系统必须拥有统一且可面向前端呈现的状态模型。
|
||
|
||
**Proposed Status Set**
|
||
|
||
- `pending`
|
||
- `context_ready`
|
||
- `narrative_ready`
|
||
- `assets_generating`
|
||
- `partial_ready`
|
||
- `completed`
|
||
- `failed`
|
||
- `degraded_completed`
|
||
|
||
**Requirements**
|
||
|
||
- 每个状态必须有明确进入条件
|
||
- 前端可根据状态做 UI 展示
|
||
- `degraded_completed` 必须代表“主结果可用,部分资产失败”
|
||
|
||
### Feature 3: 统一主记录保存
|
||
|
||
**Description**
|
||
不论输出为普通故事还是绘本,系统都应有统一的主记录保存策略。
|
||
|
||
**Requirements**
|
||
|
||
- 文本或绘本结构生成完成后,应立即保存主记录
|
||
- 主记录至少保存:
|
||
- 用户 ID
|
||
- 档案 ID
|
||
- 宇宙 ID
|
||
- 标题
|
||
- 模式
|
||
- 文本或分页结构
|
||
- 封面 prompt
|
||
- 资产状态
|
||
- 保存后即可供前端按 ID 加载
|
||
|
||
### Feature 4: 资产异步补全
|
||
|
||
**Description**
|
||
图片、音频等资产不应阻塞主结果可用性。
|
||
|
||
**Requirements**
|
||
|
||
- 封面、绘本页插图、音频均支持异步补全
|
||
- 各资产需独立记录状态
|
||
- 资产失败不应导致主故事记录失效
|
||
- 用户应可单独重试未完成资产
|
||
|
||
### Feature 5: 恢复与回看能力
|
||
|
||
**Description**
|
||
结果页与绘本页应按持久化数据恢复,而不是仅依赖 Pinia 内存状态。
|
||
|
||
**Requirements**
|
||
|
||
- 故事详情页支持按 ID 读取主记录
|
||
- 绘本阅读器支持按 ID 读取 `pages`
|
||
- 前端 store 可以作为缓存层,但不是唯一数据来源
|
||
|
||
### Feature 6: 统一后处理钩子
|
||
|
||
**Description**
|
||
成就提取、记忆提取、阅读时间线更新等能力应挂在统一后处理节点中。
|
||
|
||
**Requirements**
|
||
|
||
- 后处理任务应在主记录保存后触发
|
||
- 后处理失败不应影响主内容可读
|
||
- 后处理可被日志和状态观测
|
||
|
||
### Out of Scope
|
||
|
||
- 引入复杂工作流引擎
|
||
- 设计多租户任务编排
|
||
- 在本轮中彻底重做数据库结构
|
||
- 把所有历史接口一次性废弃
|
||
|
||
---
|
||
|
||
## UX Requirements
|
||
|
||
### Core UX Principles
|
||
|
||
- 用户始终知道当前生成到哪一步
|
||
- 用户始终能在部分成功时继续阅读
|
||
- 用户始终能在失败后看到下一步动作
|
||
|
||
### Required UI States
|
||
|
||
- 提交中
|
||
- 正在分析输入
|
||
- 正在生成文本
|
||
- 文本已完成,图片/音频处理中
|
||
- 部分完成
|
||
- 全部完成
|
||
- 失败
|
||
- 可重试
|
||
|
||
### Recovery UX
|
||
|
||
- 刷新页面后,故事结果应直接恢复
|
||
- 绘本页刷新后,应恢复到默认首页或上次阅读位置
|
||
- 若某资产失败,应明确显示“稍后重试”而非空白区域
|
||
|
||
---
|
||
|
||
## Technical Constraints
|
||
|
||
### Backend Constraints
|
||
|
||
- 现有后端基于 FastAPI + SQLAlchemy Async + Celery
|
||
- 应优先在当前架构内重组服务边界,而非大规模重写
|
||
- 现有 `Story` 表已支持 `story_text`、`pages`、`image_url` 等字段,可作为统一主记录基础
|
||
|
||
### Frontend Constraints
|
||
|
||
- 当前前端使用 Vue 3 + Pinia
|
||
- 已有创建弹窗、故事详情页、绘本阅读页
|
||
- 需尽量在现有组件结构内推进,不做过度重写
|
||
|
||
### Integration Constraints
|
||
|
||
- 文本、图片、语音能力由 Provider Router 提供
|
||
- 工作流应与 Provider 路由解耦,避免把模型策略写进业务流程
|
||
|
||
---
|
||
|
||
## Proposed Data Model Evolution
|
||
|
||
### Existing Base
|
||
|
||
当前 `Story` 模型已经可承载:
|
||
|
||
- `story_text`
|
||
- `pages`
|
||
- `cover_prompt`
|
||
- `image_url`
|
||
- `mode`
|
||
|
||
### Recommended Additions
|
||
|
||
建议新增以下字段或概念层(可为数据库字段,也可先为服务层状态):
|
||
|
||
- `generation_status`
|
||
- `text_status`
|
||
- `image_status`
|
||
- `audio_status`
|
||
- `last_error`
|
||
- `retryable_assets`
|
||
|
||
### Why This Matters
|
||
|
||
这些字段可以帮助:
|
||
|
||
- 前端显示精确状态
|
||
- 后端区分主结果和资产结果
|
||
- 支持“部分完成”和“可重试”能力
|
||
|
||
---
|
||
|
||
## API Impact
|
||
|
||
### Current APIs
|
||
|
||
- `POST /api/stories/generate`
|
||
- `POST /api/stories/generate/full`
|
||
- `POST /api/storybook/generate`
|
||
- `GET /api/stories/{id}`
|
||
- `GET /api/audio/{id}`
|
||
|
||
### Recommended Direction
|
||
|
||
第一阶段不必强行一次性废弃旧接口,但建议向统一入口演进。
|
||
|
||
**Recommended Target**
|
||
|
||
- `POST /api/generations`
|
||
- `GET /api/generations/{id}`
|
||
- `POST /api/generations/{id}/retry-assets`
|
||
|
||
如果短期不改 API 命名,也至少应做到:
|
||
|
||
- 内部统一走同一个 service workflow
|
||
- 外部不同接口只是兼容层
|
||
|
||
---
|
||
|
||
## MVP Scope & Phasing
|
||
|
||
### Phase 1: MVP
|
||
|
||
- 统一 service 层生成流程
|
||
- 支持统一状态模型
|
||
- 支持故事和绘本按 ID 恢复
|
||
- 支持部分完成与失败降级
|
||
- 支持图片和音频独立重试入口
|
||
|
||
### Phase 2: Enhancements
|
||
|
||
- 更进一步的音频缓存策略(如过期、清理与复用治理)
|
||
- 更细粒度资产状态
|
||
- 阅读位置恢复
|
||
- 工作流相关日志与监控
|
||
|
||
### Future Considerations
|
||
|
||
- 长任务通知
|
||
- 流式生成 UI
|
||
- 多阶段生成策略
|
||
- 高级 narrative plan
|
||
|
||
---
|
||
|
||
## Risk Assessment
|
||
|
||
| Risk | Probability | Impact | Mitigation Strategy |
|
||
|------|------------|--------|---------------------|
|
||
| 工作流抽象过度 | Medium | High | 先围绕现有故事/绘本/音频场景做最小抽象 |
|
||
| 历史接口兼容性问题 | Medium | Medium | 保留兼容入口,内部统一服务实现 |
|
||
| 前后端状态模型理解不一致 | High | High | 先写清统一状态表,再进入实现 |
|
||
| Storybook 恢复实现不彻底 | Medium | High | 把“按 ID 加载”作为硬性验收项 |
|
||
| 资产状态字段新增引发迁移成本 | Medium | Medium | 允许先在服务层实现,再视需要落库 |
|
||
|
||
---
|
||
|
||
## Dependencies & Blockers
|
||
|
||
**Dependencies**
|
||
|
||
- 现有 `Story` 数据模型
|
||
- 现有 `story_service.py` 能力
|
||
- 现有前端创建入口与详情页
|
||
- Provider Router 可继续提供文本、图片、音频能力
|
||
|
||
**Known Blockers**
|
||
|
||
- 统一入口尚未建立
|
||
- 多条生成链路重复实现
|
||
|
||
---
|
||
|
||
## Appendix
|
||
|
||
### Recommended State Definition Table
|
||
|
||
| State | Meaning | User-facing Message |
|
||
|------|------|------|
|
||
| `pending` | 请求已提交 | 正在准备生成 |
|
||
| `context_ready` | 上下文已完成 | 正在分析孩子档案和主题 |
|
||
| `narrative_ready` | 文本或绘本结构已生成 | 故事已生成,正在补充插图/语音 |
|
||
| `assets_generating` | 资产处理中 | 正在绘制封面或生成语音 |
|
||
| `partial_ready` | 主结果可用,资产未全部完成 | 可以先阅读,稍后补全更多内容 |
|
||
| `completed` | 全部核心资产完成 | 故事已准备完成 |
|
||
| `failed` | 主流程失败 | 生成失败,请重试 |
|
||
| `degraded_completed` | 主流程成功但部分资产失败 | 故事已可阅读,部分内容稍后重试 |
|
||
|
||
### How to Learn from This PRD
|
||
|
||
如果你想模仿写功能级 PRD,可以重点学习这几个动作:
|
||
|
||
1. 不要直接写功能,要先写“为什么当前方式有问题”。
|
||
2. 一定要把“当前实现”和“目标实现”分开写。
|
||
3. 用状态模型、边界和恢复能力来体现你对 AI 产品的不确定性理解。
|
||
4. 用户故事不要只写 happy path,要覆盖失败、降级和恢复。
|
||
5. 对系统型需求,要写清 API 影响和数据模型影响。
|
||
|
||
### References
|
||
|
||
- `backend/app/services/story_service.py`
|
||
- `backend/app/api/stories.py`
|
||
- `backend/app/schemas/story_schemas.py`
|
||
- `backend/app/db/models.py`
|
||
- `frontend/src/components/CreateStoryModal.vue`
|
||
- `frontend/src/views/StorybookViewer.vue`
|
||
|
||
---
|
||
|
||
*This PRD defines the target-state product and system behavior for unifying DreamWeaver's content generation workflow.*
|