411 lines
14 KiB
Markdown
411 lines
14 KiB
Markdown
# 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 加密存储,文件仅在服务器本地处理 |
|
||
| **并发处理** | 支持多文件并发提取,避免前端长时间等待 |
|
||
| **容错性** | 单个文件处理失败不影响其他文件 |
|