feat: polish generation demo workflow
This commit is contained in:
@@ -21,6 +21,12 @@
|
||||
- `planning/demo-checklist.md`
|
||||
求职演示检查清单。用于演示前确认 Docker 环境、核心链路、话术和风险预案。
|
||||
|
||||
- `planning/demo-validation-log.md`
|
||||
本地 Docker 演示验证记录。用于说明最近一次构建、smoke 和手动检查结果。
|
||||
|
||||
- `planning/interview-pitch.md`
|
||||
3 分钟项目讲解稿。用于面试中说明产品定位、生成工作流、Provider 分层和取舍。
|
||||
|
||||
- `planning/week-1-sprint-review.md`
|
||||
Week 1 复盘总结。用于沉淀已完成成果、剩余缺口和下一阶段建议。
|
||||
|
||||
@@ -29,6 +35,12 @@
|
||||
- `technical/memory-system-dev.md`
|
||||
记忆系统技术说明。用于后续继续做孩子档案、故事宇宙和个性化生成。
|
||||
|
||||
- `technical/api-compatibility.md`
|
||||
旧生成 API 兼容层策略。用于说明历史接口如何迁移到统一 generation 入口。
|
||||
|
||||
- `technical/generation-job-state.md`
|
||||
Generation Job 状态落库决策。用于说明当前为什么先复用 story 状态,何时再拆 job/event 表。
|
||||
|
||||
- `technical/provider-routing.md`
|
||||
Provider Routing 技术说明。用于解释 Capability / Provider / Adapter / Routing Policy 的职责边界。
|
||||
|
||||
|
||||
@@ -57,6 +57,7 @@ SMOKE_AUDIO=1 ./scripts/demo_smoke.sh
|
||||
- [ ] 绘本图片 retry 后 `image_status=ready`
|
||||
- [ ] `/admin/providers/capabilities` 返回 `text/image/tts/storybook`
|
||||
- [ ] 如果启用 `SMOKE_AUDIO=1`,音频 retry 后 `audio_status=ready`
|
||||
- [ ] 验证结果已记录到 `docs/planning/demo-validation-log.md`
|
||||
|
||||
---
|
||||
|
||||
@@ -100,6 +101,8 @@ SMOKE_AUDIO=1 ./scripts/demo_smoke.sh
|
||||
|
||||
## 4. 3 分钟讲解结构
|
||||
|
||||
详细稿见 `docs/planning/interview-pitch.md`。现场建议背结构,不逐字背。
|
||||
|
||||
### 0:00 - 0:40 产品定位
|
||||
|
||||
DreamWeaver 是面向 3-8 岁亲子场景的个性化 AI 绘本与陪伴式讲述产品。它不是只生成一次性故事,而是围绕孩子档案、成长主题和故事宇宙,生成可回看、可补全、可聆听的故事体验。
|
||||
|
||||
54
docs/planning/demo-validation-log.md
Normal file
54
docs/planning/demo-validation-log.md
Normal file
@@ -0,0 +1,54 @@
|
||||
# Demo 验证记录
|
||||
|
||||
这份记录用于演示前快速说明“当前本地 Docker 环境已经验证到什么程度”。新的验证记录按时间倒序追加。
|
||||
|
||||
## 2026-04-18
|
||||
|
||||
验证范围:
|
||||
|
||||
- 用户前端 Docker 生产构建
|
||||
- 管理前端 Docker 生产构建
|
||||
- 后端 Docker 镜像构建与服务重启
|
||||
- 后端 lint 与测试
|
||||
- 后端统一生成接口
|
||||
- 故事封面资产补全
|
||||
- 故事音频资产补全
|
||||
- 绘本文字生成
|
||||
- 绘本封面和分页插图补全
|
||||
- 故事列表读取
|
||||
- Provider capability policy
|
||||
|
||||
执行命令:
|
||||
|
||||
```bash
|
||||
docker compose build frontend
|
||||
docker compose build frontend frontend-admin
|
||||
docker compose build backend backend-admin worker celery-beat
|
||||
docker compose up -d backend backend-admin worker celery-beat frontend frontend-admin
|
||||
cd backend && .venv/bin/python -m ruff check app tests
|
||||
cd backend && .venv/bin/python -m pytest -q
|
||||
SMOKE_AUDIO=1 ./scripts/demo_smoke.sh
|
||||
```
|
||||
|
||||
结果:
|
||||
|
||||
- `vue-tsc` 通过。
|
||||
- 用户端与管理端 `vite build` 通过。
|
||||
- Docker 前端镜像 `dreamweaver-frontend:dev` 构建通过。
|
||||
- Docker 管理前端镜像 `dreamweaver-admin-frontend:dev` 构建通过。
|
||||
- Docker 后端镜像 `dreamweaver-backend:dev` 构建通过。
|
||||
- `ruff check app tests` 通过。
|
||||
- `pytest -q` 通过,71 个测试通过。
|
||||
- `SMOKE_AUDIO=1 ./scripts/demo_smoke.sh` 通过。
|
||||
- 本地用户端可通过 `http://localhost:52080` 访问。
|
||||
|
||||
已确认的演示能力:
|
||||
|
||||
- 普通故事可以先生成可读正文。
|
||||
- 封面和音频可以作为资产单独重试。
|
||||
- 绘本可以生成 6 页文本并补全全部插图。
|
||||
- 故事列表能看到最新生成结果。
|
||||
|
||||
限制:
|
||||
|
||||
- 本机浏览器自动化脚本默认寻找标准版 Chrome;当前电脑安装的是 Google Chrome Beta,所以本轮没有生成 CDP 截图。
|
||||
83
docs/planning/interview-pitch.md
Normal file
83
docs/planning/interview-pitch.md
Normal file
@@ -0,0 +1,83 @@
|
||||
# DreamWeaver 3 分钟项目讲解稿
|
||||
|
||||
这份讲解稿用于 AI 产品经理面试中的项目介绍。建议先背结构,不要逐字背稿;现场根据面试官背景调整技术深度。
|
||||
|
||||
---
|
||||
|
||||
## 0:00 - 0:30 一句话定位
|
||||
|
||||
DreamWeaver 是一款面向 3-8 岁亲子场景的个性化 AI 绘本与陪伴式讲述产品。它不是简单生成一段故事,而是围绕孩子档案、成长主题和故事宇宙,生成可以保存、回看、补全封面和播放语音的亲子阅读体验。
|
||||
|
||||
---
|
||||
|
||||
## 0:30 - 1:05 为什么要重启这个项目
|
||||
|
||||
这个项目早期功能很多:故事生成、绘本、语音、Provider 管理、孩子档案、记忆系统都做过,但主线不够聚焦。求职版重启时,我把目标从“功能越多越好”改成“能否讲清楚一个 AI 产品闭环”。
|
||||
|
||||
我保留的核心闭环是:
|
||||
|
||||
`选择孩子档案 -> 输入主题/教育目标 -> 生成故事或绘本 -> 补全封面/插图/语音 -> 保存到故事库 -> 可再次打开`
|
||||
|
||||
这样面试官能快速理解用户价值,也能看到我对范围收敛的判断。
|
||||
|
||||
---
|
||||
|
||||
## 1:05 - 1:55 统一生成工作流
|
||||
|
||||
AI 生成产品最大的问题不是“能不能调模型”,而是结果不确定时,用户体验怎么保持稳定。所以我把普通故事、完整故事和绘本生成收敛成统一 Generation Workflow。
|
||||
|
||||
现在系统先保存主结果,让故事或绘本文字尽快可读;封面、绘本插图和语音作为可补全资产处理。即使图片或音频失败,主故事不会丢,用户可以继续阅读,也可以稍后重试。
|
||||
|
||||
后端通过统一状态字段表达结果:
|
||||
|
||||
- `generation_status`
|
||||
- `image_status`
|
||||
- `audio_status`
|
||||
- `last_error`
|
||||
|
||||
服务层也抽出了 `AssetCompletionResult`,用来表达资产补全类型、状态、结果值、错误信息和是否阻塞主结果。
|
||||
|
||||
---
|
||||
|
||||
## 1:55 - 2:35 Provider 分层
|
||||
|
||||
另一个重点是 Provider 体系。早期 Provider Router 同时承担默认配置、Key 映射、路由策略、熔断、成本统计和执行入口,解释起来很乱。
|
||||
|
||||
我把它拆成四个概念:
|
||||
|
||||
- Capability:产品需要的 AI 能力,例如文本、图片、语音、绘本结构
|
||||
- Provider:某个能力下的供应商配置,例如 Gemini、OpenAI、CQTAI、MiniMax
|
||||
- Adapter:具体 API 调用实现
|
||||
- Routing Policy:如何按优先级、成本、延迟或轮询选择 Provider
|
||||
|
||||
这样用户看到的是稳定的产品能力,系统内部再决定具体调用哪个模型或供应商。
|
||||
|
||||
---
|
||||
|
||||
## 2:35 - 3:00 当前成果和下一步
|
||||
|
||||
目前本地 Docker 可以跑通完整链路,并且有 smoke 脚本验证健康检查、登录、生成、资产重试、故事列表和 Provider 能力分层。
|
||||
|
||||
下一步我会继续打磨前端状态体验,让生成中、部分完成、失败重试这些 AI 产品特有状态更清楚;同时明确旧 API 兼容层和 generation job 是否需要落库。
|
||||
|
||||
我希望通过这个项目展示的是:我不只是会接 AI API,而是能把不确定的模型能力收敛成稳定、可解释、可恢复的产品体验。
|
||||
|
||||
---
|
||||
|
||||
## 面试官追问时的简短回答
|
||||
|
||||
### 为什么不是继续加更多功能?
|
||||
|
||||
因为求职版的核心目标是展示产品判断和系统设计能力。功能越多不一定越好,闭环稳定、边界清楚、能解释取舍更重要。
|
||||
|
||||
### 为什么资产失败不直接让生成失败?
|
||||
|
||||
儿童故事的主价值是可阅读内容。封面、插图、语音是增强资产,失败时应该降级而不是摧毁主结果。这是 AI 产品常见的不确定性处理。
|
||||
|
||||
### Provider 分层有什么产品价值?
|
||||
|
||||
它让用户不需要理解模型供应链,只感知稳定能力;同时让产品拥有者能控制成本、失败降级和供应商切换。
|
||||
|
||||
### 这个项目下一步怎么上线?
|
||||
|
||||
我会先完成演示级前端状态体验和旧 API 兼容策略,再决定 generation job 是否落库。生产上线前还需要补真实用户鉴权配置、密钥管理、监控告警和部署策略。
|
||||
@@ -76,13 +76,13 @@ Week 2 的目标不是做“完整商业产品”,而是做出一个面试时
|
||||
| W2-01 | Demo | 固化本地 Docker smoke 脚本 | `scripts/demo_smoke.sh` | P0 | 0.5d | Done |
|
||||
| W2-02 | Demo | 形成求职演示 checklist | `docs/planning/demo-checklist.md` | P0 | 0.5d | Done |
|
||||
| W2-03 | Planning | 输出 Week 2 执行 backlog | 当前文档 | P0 | 0.5d | Done |
|
||||
| W2-04 | Product | 写 3 分钟项目讲解稿 | 面试口径:产品、工作流、Provider、取舍 | P0 | 0.5d | Pending |
|
||||
| W2-05 | Frontend | 打磨创建弹窗的状态文案 | 用户知道正在生成故事/绘本/资产 | P0 | 0.5d | Pending |
|
||||
| W2-06 | Frontend | 强化故事详情页资产状态与重试 CTA | 图片/音频失败时可理解、可操作 | P0 | 1.0d | Pending |
|
||||
| W2-07 | Frontend | 强化绘本阅读器降级态 | 缺图、失败、加载中不出现空白体验 | P0 | 1.0d | Pending |
|
||||
| W2-08 | Backend | 梳理旧生成 API 兼容层策略 | 保留/标记 deprecated/迁移计划 | P1 | 0.5d | Pending |
|
||||
| W2-09 | Backend | 判断 generation job 是否需要落库 | ADR 或技术说明 | P1 | 0.5d | Pending |
|
||||
| W2-10 | QA | 补前端关键路径构建与 smoke 验证记录 | Docker build + smoke 输出 | P1 | 0.5d | Pending |
|
||||
| W2-04 | Product | 写 3 分钟项目讲解稿 | 面试口径:产品、工作流、Provider、取舍 | P0 | 0.5d | Done |
|
||||
| W2-05 | Frontend | 打磨创建弹窗的状态文案 | 用户知道正在生成故事/绘本/资产 | P0 | 0.5d | Done |
|
||||
| W2-06 | Frontend | 强化故事详情页资产状态与重试 CTA | 图片/音频失败时可理解、可操作 | P0 | 1.0d | Done |
|
||||
| W2-07 | Frontend | 强化绘本阅读器降级态 | 缺图、失败、加载中不出现空白体验 | P0 | 1.0d | Done |
|
||||
| W2-08 | Backend | 梳理旧生成 API 兼容层策略 | 保留/标记 deprecated/迁移计划 | P1 | 0.5d | Done |
|
||||
| W2-09 | Backend | 判断 generation job 是否需要落库 | ADR 或技术说明 | P1 | 0.5d | Done |
|
||||
| W2-10 | QA | 补前端关键路径构建与 smoke 验证记录 | Docker build + smoke 输出 | P1 | 0.5d | Done |
|
||||
| W2-11 | Docs | 输出 Week 1 Sprint Review | `docs/planning/week-1-sprint-review.md` | P1 | 0.5d | Done |
|
||||
| W2-12 | Docs | 更新 README 的演示前检查流程 | README 本地演示说明 | P1 | 0.5d | Done |
|
||||
|
||||
|
||||
48
docs/technical/api-compatibility.md
Normal file
48
docs/technical/api-compatibility.md
Normal file
@@ -0,0 +1,48 @@
|
||||
# API 兼容层策略
|
||||
|
||||
这份文档用于说明 DreamWeaver 求职版如何处理旧生成接口。目标不是立刻删除所有旧 API,而是把主线收敛到统一生成工作流,并让历史入口变成可迁移、可监控、可解释的兼容层。
|
||||
|
||||
## 背景
|
||||
|
||||
项目早期分别提供过普通故事、完整故事、绘本、封面生成和资产重试接口:
|
||||
|
||||
- `POST /api/stories/generate`
|
||||
- `POST /api/stories/generate/full`
|
||||
- `POST /api/storybook/generate`
|
||||
- `POST /api/image/generate/{story_id}`
|
||||
- `POST /api/stories/{story_id}/assets/retry`
|
||||
|
||||
这些接口都能工作,但对前端和面试讲解不够友好:故事、绘本和资产补全看起来像多条产品链路,容易掩盖真正的核心能力。
|
||||
|
||||
## 目标入口
|
||||
|
||||
求职版主入口统一为:
|
||||
|
||||
- `POST /api/generations`
|
||||
- `GET /api/generations/{story_id}`
|
||||
- `POST /api/generations/{story_id}/retry-assets`
|
||||
|
||||
前端创建弹窗、绘本阅读器、故事详情页的资产重试应优先使用这些入口。
|
||||
|
||||
## 当前策略
|
||||
|
||||
1. 保留旧接口,避免破坏已有测试和潜在调用方。
|
||||
2. 旧接口内部继续复用同一套 service workflow,不复制业务逻辑。
|
||||
3. 旧接口响应增加迁移提示 header:
|
||||
- `Deprecation: true`
|
||||
- `X-DreamWeaver-Successor-Endpoint: <target>`
|
||||
- `Link: <target>; rel="successor-version"`
|
||||
4. 新前端不再新增对旧生成接口的依赖。
|
||||
|
||||
## 删除条件
|
||||
|
||||
旧接口可以在同时满足以下条件后删除:
|
||||
|
||||
- 用户端和管理端都已切到 `/api/generations`。
|
||||
- smoke 脚本只依赖统一入口。
|
||||
- 后端测试覆盖统一入口的故事、绘本、资产重试和失败降级。
|
||||
- 至少一个迭代周期没有发现旧接口新增调用。
|
||||
|
||||
## 面试表达
|
||||
|
||||
我不会为了“代码看起来干净”直接删掉旧接口,因为这会引入不可见风险。更稳妥的做法是先定义目标 API,再把旧入口降级为带迁移信号的兼容层,最后通过测试和调用方收敛来决定删除时机。
|
||||
43
docs/technical/generation-job-state.md
Normal file
43
docs/technical/generation-job-state.md
Normal file
@@ -0,0 +1,43 @@
|
||||
# Generation Job 状态落库决策
|
||||
|
||||
这份文档用于回答一个关键技术债问题:DreamWeaver 是否需要为每次 AI 生成单独建立 `generation_jobs` 表。
|
||||
|
||||
## 当前结论
|
||||
|
||||
短期不新增 `generation_jobs` 表,继续把求职版状态落在 `stories` 主记录上。
|
||||
|
||||
原因是当前 MVP 的生成方式仍然以同步请求为主:后端在一次请求中完成主内容保存,再补全封面、绘本插图或语音。用户最关心的是“这个故事现在能不能读、哪些资产可补全”,而不是一个独立 job 的生命周期。
|
||||
|
||||
## 现有状态模型
|
||||
|
||||
当前 `stories` 表已承载演示所需状态:
|
||||
|
||||
- `generation_status`: 主流程状态,例如 `narrative_ready`、`assets_generating`、`completed`、`degraded_completed`、`failed`
|
||||
- `image_status`: 封面或绘本插图状态
|
||||
- `audio_status`: 语音状态
|
||||
- `last_error`: 最近一次资产失败原因
|
||||
|
||||
这些字段足够支撑前端展示、smoke 检查、失败降级和资产重试。
|
||||
|
||||
## 什么时候需要落库 job
|
||||
|
||||
如果后续进入真实生产化,需要重新评估 `generation_jobs`:
|
||||
|
||||
- 生成流程改成真正异步,前端需要轮询 job 进度。
|
||||
- 单个故事会产生多次生成尝试,需要审计每次 provider 调用。
|
||||
- 需要展示更细颗粒度步骤,例如 prompt 构建、文本生成、封面生成、每页插图、TTS。
|
||||
- 需要按 provider、成本、延迟和失败原因做运营分析。
|
||||
- 需要断点续跑,避免 Worker 重启后丢失中间状态。
|
||||
|
||||
## 推荐未来结构
|
||||
|
||||
未来可以新增两层记录:
|
||||
|
||||
- `generation_jobs`: 一次用户发起的生成任务,记录输入、状态、耗时、错误和关联 story。
|
||||
- `generation_job_events`: 任务事件流,记录每一步开始、成功、失败、provider、耗时和错误摘要。
|
||||
|
||||
这会把“用户可见结果”和“系统执行过程”分开,但目前还不是求职版的最高优先级。
|
||||
|
||||
## 面试表达
|
||||
|
||||
我现在没有急着加 job 表,是因为 MVP 首要目标是让故事结果稳定可读,并让资产失败可恢复。等生成链路变成真正异步、需要审计和运营指标时,再把执行过程拆到 job/event 表,会比现在提前设计复杂表结构更稳。
|
||||
Reference in New Issue
Block a user