Files
Story-extractor/docs/Story-Extractor-产品设计文档.md
2026-04-24 16:02:16 +08:00

411 lines
14 KiB
Markdown
Raw Permalink Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# Story Extractor — 产品设计文档
> 版本v1.1 · 2026-04-21
---
## 一、产品概述
### 1.1 产品定位
Story Extractor 是一个 **局域网部署的 Web 工具**,用于从直播回放文字稿中自动提取学员个人故事,与讲述者个人信息匹配后,为每位讲述者生成独立的 DOCX 文档。
### 1.2 核心价值
- **自动化**AI 自动从上万行口语化文字稿中提取学员故事,替代人工阅读筛选
- **结构化**:将散乱的直播内容转化为结构化的"人物 + 故事"文档
- **可复用**工具化交付支持后续扩展LLM 升级、搜索引擎等)
### 1.3 使用场景
| 维度 | 描述 |
|------|------|
| **部署环境** | 局域网,多人可访问 |
| **数据规模** | 20+ 份文字稿每份上万行8+ 位讲述者 |
| **用户角色** | 内容运营人员 |
---
## 二、文字稿特征分析
### 2.1 格式特征
每段格式为:**`发言者(时间戳): 内容`**,例如:
```
卢慧老师(00:05:38): 这个我们在我们的启蒙课里面...
14班+HCM(02:39:31): 就是要要打要骂,呵呵...
```
- 有明确的**说话人标记**(老师 / 学员昵称)
- 有**时间戳**,可用于判断发言时长
- 主讲老师占 60-70% 内容,学员发言散落其中
### 2.2 内容构成
| 内容类型 | 占比 | 说明 |
|----------|------|------|
| **课程讲授** | ~55% | 老师讲理论、概念、方法论 |
| **课堂管理** | ~10% | 改昵称、纪律提醒、进组讨论等技术性内容 |
| **疗愈练习** | ~15% | "我愿意看见且释放..." 引导式重复 |
| **学员故事** | ~15% | 学员讲述个人经历,老师追问 |
| **学员短回应** | ~5% | "好的""收到"等 |
### 2.3 故事的实际形态
故事**不是一段完整的自述**,而是**对话式展开**的:
- 老师提问/引导 → 学员回答 → 老师追问 → 学员深入讲述 → 可能穿插疗愈练习
- 一个故事可能跨 **20-30 段对话**,持续 15-30 分钟
- 故事之间没有明显分界,可能上一段还在讲理论,下一段就切入学员故事
### 2.4 典型故事示例
| 讲述者 | 故事概要 |
|--------|----------|
| **14班+HCM** | 从小被妈妈体罚(跪凳子),长大后用同样方式对待女儿,女儿出现躯体化症状 |
| **13-阿纳** | 姥姥因特殊年代藏首饰恐惧自杀,形成"不能有钱"的家族限制性信念 |
| **06班Rena** | 妈妈在怀自己前打掉一个男孩,爸爸重男轻女,自己被当男孩养,对亲密关系有破坏倾向 |
| **11班四维** | 女儿出柜说喜欢同性,追溯到自己出生时妈妈因生女孩而悲伤的家族重男轻女 |
---
## 三、用户流程
### 3.1 流程总览
```
欢迎页 → 上传文件 → 提取故事 → 匹配确认 → 预览导出
```
采用 **线性向导式** 交互,用户依次完成四个步骤。
### 3.2 步骤指示器
- 顶部居中展示 4 个步骤节点(上传文件 → 提取故事 → 匹配确认 → 预览导出)
- 当前步骤高亮(紫色),已完成步骤显示绿色 ✓
- 步骤之间用连线表示进度
- 欢迎页不显示步骤指示器
- 步骤节点可点击跳转(已完成的步骤)
### 3.3 底部导航栏
- 固定在页面底部
- 左侧:上一步按钮(第一步时隐藏)
- 中间:当前步骤提示文案
- 右侧:下一步按钮(最后一步变为"全部导出"
- 欢迎页不显示底部导航栏
---
## 四、页面详细设计
### 4.0 欢迎页
**目的**:产品介绍 + 引导用户开始
**布局**:页面垂直居中
**内容**
- 产品 Logo紫色渐变圆角方块 + 书本图标)
- 产品名称 "Story Extractor"
- 一句话介绍:"从直播回放文字稿中AI 自动提取个人故事,与讲述者信息匹配,一键生成精美文档。"
- 四步流程预览(图标 + 标题 + 副标题):
- 📤 上传文件 — 文字稿 + 个人信息
- 🪄 提取故事 — AI 智能识别
- 🔗 匹配确认 — 人工核对
- 📄 预览导出 — 生成 DOCX
- 大号 CTA 按钮:"开始使用"
**交互**
- 点击"开始使用"进入第一步(上传文件)
- 不显示步骤指示器和底部导航栏
---
### 4.1 第一步:上传文件
**目的**:上传直播文字稿和讲述者个人信息
**布局**:左右两栏
**左栏 — 直播文字稿**
- 标题:直播文字稿(蓝色图标)+ 右侧标注 "DOCX 格式"
- 上传区域(虚线边框拖拽区):
- 图标 + "拖拽文件到此处,或点击上传"
- 提示:支持批量上传 · 仅限 .docx 格式
- 已上传文件列表:
- 每个文件显示:文件图标(蓝色 DOCX+ 文件名 + 元信息(行数、大小)
- 右侧删除按钮
**右栏 — 讲述者信息**
- 标题:讲述者信息(粉色图标)+ 右侧标注 "一人一个 DOCX"
- 上传区域(虚线边框拖拽区):
- 图标 + "拖拽文件到此处,或点击上传"
- 提示:每个讲述者一个 DOCX · 包含个人信息和照片
- 已上传文件列表:
- 每个文件显示:文件图标(粉色)+ 文件名 + 元信息(含几张照片)
- 右侧预览按钮 + 删除按钮
**交互**
- 底部导航提示:"上传文字稿和讲述者信息文件后进入下一步"
- 点击"下一步"进入第二步
---
### 4.2 第二步:提取故事
**目的**AI 自动从所有文字稿中提取学员个人故事
**进入方式**:从第一步点击"下一步"后自动进入,**自动开始提取**,无需手动触发
#### 阶段 A提取进度自动展示
**布局**:单卡片
**内容**
- 标题:"AI 正在工作中" + 右侧百分比(大号加粗)
- 进度条(粗圆角,紫色渐变填充)
- 当前处理状态:
- 运行状态指示灯(紫色脉冲动画)
- 当前文件名:"正在读取xxx.docx"
- 当前动作:
- "预处理:过滤课堂管理内容..."
- "预处理:过滤疗愈练习..."
- "智能分段:识别话题边界..."
- "故事识别:检测学员发言..."
- "故事提取:整理故事内容..."
- 三列状态卡片:
- 文件读取:`X / 23`(已读文件数 / 总文件数)
- 话题分段:`XX 段`(已分段数量)
- 故事发现:`X 个`(已发现故事数量,发现后变绿色)
**进度阶段**
1. 0-15%:读取文件,预处理(过滤课堂管理、短回应)
2. 15-40%:智能话题分段
3. 40-70%:识别学员故事片段
4. 70-95%:提取故事内容,生成标题和摘要
5. 95-100%:汇总结果
**完成时**
- 进度条变绿色
- 状态灯变绿色
- 显示"全部处理完成!共处理 X 份文字稿,发现 X 个故事"
- 1.2 秒后自动切换到故事列表
#### 阶段 B故事列表提取完成后展示
**布局**:单卡片
**内容**
- 标题:"已提取的故事" + 右侧 "共 X 个故事"
- 故事卡片列表,每个卡片包含:
- 故事标题(加粗)
- 讲述者昵称(从文字稿提取,如"14班+HCM"
- 故事摘要2-3 句话)
- 来源信息(文件名 + 行号范围 + 时长)
- 置信度标签(高/中/低)
- 操作按钮:查看原文、编辑、删除
**交互**
- 底部导航提示:"AI 已提取故事,下一步将故事与讲述者匹配"
- 点击"下一步"进入第三步(**无需全部匹配,可直接进入**
---
### 4.3 第三步:匹配确认
**目的**:将提取的故事与讲述者一一对应(可选操作)
**布局**:三栏(故事列表 | 匹配操作 | 讲述者列表)
**左栏 — 故事列表**
- 标题:"故事列表" + 右侧 "X 个故事"
- Tab 切换:全部 / 已匹配 / 未匹配
- 故事卡片列表:
- 故事标题
- 讲述者昵称(文字稿中的昵称,如"14班+HCM"
- 故事摘要(简短版)
- 匹配状态标签(已匹配显示讲述者姓名,未匹配显示"待匹配"
- 点击选中(高亮为橙色背景)
- 操作:删除(不满意的故事可直接删除)
**中间 — 匹配操作**
- 紫色圆形箭头按钮
- 提示文字:"选中故事和讲述者后点击匹配"
**右栏 — 讲述者列表**
- 标题:"讲述者" + 右侧 "共 X 人"
- 讲述者卡片列表:
- 头像(姓氏首字,紫色渐变背景)
- 姓名
- 文字稿昵称映射(如:张小花 → 14班+HCM
- 匹配状态(已匹配 X 个故事 / 未匹配)
- 点击选中(紫色边框高亮)
**交互**
- 选中左侧故事 + 选中右侧讲述者 → 点击中间箭头确认匹配
- 匹配完成后故事状态变为"已匹配"
- **可删除不满意的故事**AI 可能提取出无效故事)
- **无需全部匹配即可进入下一步**(未匹配的故事不会导出)
- 底部导航提示:"将需要的故事与讲述者匹配,未匹配的故事不会导出"
---
### 4.4 第四步:预览导出
**目的**:预览最终文档效果并导出
**布局**:左右两栏
**左栏 — 导出列表**
- 标题:"导出列表" + 右侧 "仅显示已匹配的讲述者"
- 导出项列表,每项包含:
- 状态图标(绿色 ✓ = 已匹配可导出)
- 文件名:"张小花 - 故事集.docx"
- 元信息:"X 个故事 · 含个人信息和照片"
- 预览按钮、下载按钮
- 未匹配的故事不会出现在导出列表中
**右栏 — 文档预览**
- 标题:"文档预览" + 上一个/下一个切换按钮
- 文档预览卡片(模拟 DOCX 效果):
- 顶部:紫色渐变头部
- 圆形头像占位
- 讲述者姓名
- 个人信息(性别 · 年龄 · 城市 · 职业)
- 正文区域:
- "她的故事" 标题(紫色下划线)
- 故事正文(多段落,如有多个故事依次排列)
**交互**
- 点击"上一个/下一个"切换预览不同讲述者的文档
- 点击单个下载按钮导出单个 DOCX
- 底部"全部导出"按钮(绿色)批量导出所有已匹配讲述者的文档
---
### 4.5 系统设置(弹窗)
**触发**:右上角齿轮图标
**布局**:居中弹窗 Modal
**内容**
**LLM 配置**
- API 提供商下拉选择OpenAI (GPT-4) / DeepSeek / 通义千问 / 本地 Ollama / 自定义兼容 API
- 模型名称(文本输入)
- API Base URL文本输入
- API Key密码输入
**提取参数**
- 话题分段最大长度(行数)
- 故事最小长度(行数)
- 置信度阈值(低于此值的故事标记为"低置信度"
- 并发请求数
- Temperature
**操作按钮**
- 取消、测试连接、保存
---
## 五、数据模型
### 5.1 文字稿Transcript
| 字段 | 类型 | 说明 |
|------|------|------|
| id | string | 唯一标识 |
| filename | string | 原始文件名 |
| file_path | string | 服务器存储路径 |
| line_count | int | 总行数 |
| file_size | int | 文件大小(字节) |
| status | enum | pending / processing / done / error |
| uploaded_at | datetime | 上传时间 |
### 5.2 讲述者Person
| 字段 | 类型 | 说明 |
|------|------|------|
| id | string | 唯一标识 |
| name | string | 真实姓名 |
| nickname | string | 文字稿中的昵称(如"14班+HCM" |
| filename | string | 原始 DOCX 文件名 |
| file_path | string | 服务器存储路径 |
| photo_path | string | 提取的照片路径 |
| info | json | 从 DOCX 提取的个人信息(年龄、性别、城市、职业等) |
| uploaded_at | datetime | 上传时间 |
### 5.3 故事Story
| 字段 | 类型 | 说明 |
|------|------|------|
| id | string | 唯一标识 |
| title | string | AI 生成的故事标题 |
| summary | string | AI 生成的故事摘要 |
| content | text | 完整故事内容(仅学员讲述部分,已过滤老师对话) |
| speaker_nickname | string | 文字稿中的讲述者昵称(如"14班+HCM" |
| source_transcript_id | string | 来源文字稿 ID |
| source_lines | json | 在原文中的行号范围 [{start, end}] |
| duration_minutes | float | 预估时长(分钟) |
| confidence | float | 置信度0.0-1.0 |
| person_id | string | 匹配的讲述者 ID可为空 |
| match_status | enum | pending / matched / deleted |
| created_at | datetime | 提取时间 |
### 5.4 系统配置Config
| 字段 | 类型 | 说明 |
|------|------|------|
| llm_provider | string | API 提供商 |
| llm_model | string | 模型名称 |
| llm_base_url | string | API Base URL |
| llm_api_key | string | API Key加密存储 |
| segment_max_lines | int | 话题分段最大行数 |
| story_min_lines | int | 故事最小行数 |
| confidence_threshold | float | 置信度阈值 |
| concurrency | int | 并发请求数 |
| temperature | float | Temperature |
---
## 六、输出文档模板
每个讲述者生成一份 DOCX结构如下
```
┌─────────────────────────────────┐
│ [照片] │
│ 姓名:张小花 │
│ 性别:女 年龄35岁 │
│ 城市:北京 职业:全职妈妈 │
├─────────────────────────────────┤
│ │
│ 她的故事 │
│ ───── │
│ 故事正文第一段... │
│ │
│ 故事正文第二段... │
│ │
│ (如有多个故事,依次排列) │
│ │
└─────────────────────────────────┘
```
- 简洁模板,不花哨
- 个人信息在顶部,照片居中
- 故事正文在下方(仅学员讲述内容,已过滤老师对话)
- 一位讲述者可能有多个故事,依次排列
---
## 七、非功能性需求
| 需求 | 说明 |
|------|------|
| **局域网访问** | 部署在局域网内,多人可通过浏览器访问 |
| **扩展性** | LLM 可替换,后续可扩展文章搜索引擎 |
| **数据安全** | API Key 加密存储,文件仅在服务器本地处理 |
| **并发处理** | 支持多文件并发提取,避免前端长时间等待 |
| **容错性** | 单个文件处理失败不影响其他文件 |