|
| 1 | +# 课堂助手增强策略与实施规划(2026-08) |
| 2 | + |
| 3 | +> 基于竞品差距分析(`classroom-assistant-competitive-analysis.md`)与技术机制调研(`video-content-extraction-market-2026.md`)的落地决策文档。 |
| 4 | +> 状态:已决策(本章节) / 待探讨(批量插入章节) |
| 5 | +> 对应代码热区:`client/src/features/classroom/`、`client/electron/ipc/keyframeStorage.ts`、`server/ai-gateway/` |
| 6 | +
|
| 7 | +--- |
| 8 | + |
| 9 | +## 一、差距项决策速览 |
| 10 | + |
| 11 | +| # | 差距 | 选定方案 | 优先级 | 性质 | |
| 12 | +|---|------|---------|--------|------| |
| 13 | +| 1 | 页切换检测 + 页面级去重 | **方案 C**:独立板书/页面双通道哈希池 | P1 | 增量 → 降成本 | |
| 14 | +| 2 | PPT 页独立摘要 | **方案 A+B**:页标记 + 图编号精确对齐 | P1 | 质量提升 | |
| 15 | +| 3 | 语义章节切分 | **方案 B**:一次性 LLM 章节划分 | P1 | 结构化飞跃 | |
| 16 | +| 4 | 时间轴回放 | **方案 A**:文本级时间轴(零新数据依赖) | P0 | 体验基础 | |
| 17 | +| 5 | RAG 问答 | **方案 A**:课后问答入口(复用 `askSessionQuestion`) | P0 | 核心缺口 | |
| 18 | +| 6 | 转写修正全链路同步 | **方案 A+B**:修正写回 audioText + 原文溯源 | P0 | bugfix | |
| 19 | +| 7 | 多格式导出 | Anki 导出优先,Markdown 次之 | P2 | 跨生态 | |
| 20 | + |
| 21 | +### 各方案详细描述 |
| 22 | + |
| 23 | +#### ① 页切换检测 + 页面级去重 — 方案 C |
| 24 | + |
| 25 | +- 画面帧按 `changeType` 路由到两个独立哈希池:`slidePool`(score ≥ 0.6) + `boardPool`(score < 0.6) |
| 26 | +- 各池独立维护近 50 帧哈希集合,新帧与池中所有帧比较 Hamming 距离 |
| 27 | +- 去重阈值:`slide` 收紧(≤8 算重复,允许非精确翻页匹配),`board` 维持(≤5,渐进板书疏漏少) |
| 28 | +- 在 `SmartSampler` 中新增双池逻辑,`trimOldKeyframeImages` 同步裁剪 |
| 29 | + |
| 30 | +> 预期效果:同页动画/光标不再重复捕获,增量分析帧数砍半,同时板书与 PPT 页不去重互扰。 |
| 31 | +
|
| 32 | +#### ② PPT 页独立摘要 — 方案 A+B |
| 33 | + |
| 34 | +- **A**:`analyzePartial` 拆包时按 `isNewPage`(`changeType === 'slide_change'`)切分,每页独立调 VLM |
| 35 | + 输出 `{ pageNumber, summary }`,增量结果带 `pageNumber` 标记存入 `partialNotesRef` |
| 36 | +- **B**:每个 `pageSummary` 携带 `[图:N]` 精确标记指向具体关键帧,mergeNotes 时精确匹配而非时间就近兜底 |
| 37 | + |
| 38 | +> 效果:摘要粒度从"不确定的 5 帧块"变为"确定的一页笔记"。 |
| 39 | +
|
| 40 | +#### ③ 语义章节切分 — 方案 B |
| 41 | + |
| 42 | +- mergeNotes 成功(或本地 concat 后)→ 调一次 LLM `chapter_segment` prompt |
| 43 | +- Prompt:将整篇笔记划分为章节 + 每章命名 + 一句话概述 + 起止时间 |
| 44 | +- LLM 不可用时降级:按 partial 序号 + 时间区间规则分割 |
| 45 | + |
| 46 | +> 改动最小(纯 prompt 工程 + 一次网关调用),产出质量最高。 |
| 47 | +
|
| 48 | +#### ④ 文本级时间轴 — 方案 A |
| 49 | + |
| 50 | +- 纯 UI:课后笔记详情页 + 采集过程中侧边栏,展示可点击时间线 |
| 51 | +- 现有数据直接消费:`audioSegments[i].timestampStart/End` + `audioText` + `keyframes[].timestamp` + `timeline` 书签 |
| 52 | +- 不新增任何持久化依赖。点击时间点 → 高亮对应转写段落 + 定位关键帧缩略图 |
| 53 | + |
| 54 | +#### ⑤ 课后 RAG 问答 — 方案 A |
| 55 | + |
| 56 | +- 在 `SessionContentView` 的 QA Tab(已有)接入 `askSessionQuestion`(移动端 `mobilePipeline.ts` 已实现的函数) |
| 57 | +- 用户输入问题 → 调网关 `/api/v1/ai/session-qa` → 展示回答 + 引用时间 |
| 58 | +- 改造:当前 QA Tab 的 `qaTranscript` 拼接方式改为传入 `liveTranscripts` + `audioSegments` 中的 `audioText` 完整内容 |
| 59 | + |
| 60 | +#### ⑥ 转写修正全链路同步 — 方案 A+B |
| 61 | + |
| 62 | +- **A**:`handleEditTranscript` 保存时同步更新 `smartBundle` 中对应 `audioSegment.audioText`(不可变更新) |
| 63 | + mergeNotes 从 `audioSegments` 拿修正后文本,修正自动流入笔记 + 闪卡 |
| 64 | +- **B**:保留 `audioTextRaw`(已有字段),UI 增加"原始视图/修正视图"切换 |
| 65 | + |
| 66 | +> 当前修正只改 UI 态不下游同步,这是必须修的 bug(约 10 行)。 |
| 67 | +
|
| 68 | +#### ⑦ 多格式导出 |
| 69 | + |
| 70 | +- **Anki 导出优先**:现有闪卡已存 `front/back/cloze` 结构,导出 `.apkg`(ZIP + CSV/SQLite)即可跨生态 |
| 71 | +- **Markdown 导出**:`note.content` 是 Markdown 转 TipTap 存的,逆向转换后写 `.md` 文件 |
| 72 | + |
| 73 | +--- |
| 74 | + |
| 75 | +## 二、优先级路线图 |
| 76 | + |
| 77 | +### P0 — 立即(1~2 天,独立不阻塞) |
| 78 | + |
| 79 | +``` |
| 80 | +① 转写修正全链路同步 |
| 81 | +② 课后 RAG 问答 UI 接入 |
| 82 | +③ 文本级时间轴(纯 UI) |
| 83 | +``` |
| 84 | + |
| 85 | +### P1 — 近中期(3~5 天,逐项推进) |
| 86 | + |
| 87 | +``` |
| 88 | +④ 页面级去重(双池哈希) |
| 89 | +⑤ 页级摘要拆分 + 精确图对齐 |
| 90 | +⑥ 一次性语义章节切分(LLM) |
| 91 | +``` |
| 92 | + |
| 93 | +### P2 — 后续评估 |
| 94 | + |
| 95 | +``` |
| 96 | +⑦ Anki/Markdown 导出 |
| 97 | +``` |
| 98 | + |
| 99 | +### 不做(至少当前阶段不触及) |
| 100 | + |
| 101 | +``` |
| 102 | +- PPT 页重建导出 |
| 103 | +- 逐词同步高亮 |
| 104 | +- 实时视觉 OCR 流(smart 路径) |
| 105 | +- 下载多平台 URL 视频 |
| 106 | +``` |
| 107 | + |
| 108 | +--- |
| 109 | + |
| 110 | +## 三、待探讨:语音转写文本的批量插入笔记 |
| 111 | + |
| 112 | +### 3.1 问题描述 |
| 113 | + |
| 114 | +当前转写文本(smart 路径 `liveTranscripts` / fine 路径 `segments`)没有进入笔记插入弹窗的路径: |
| 115 | + |
| 116 | +- `liveTranscripts` 在 UnifiedTimeline 中仅展示/编辑,**不可选中、不可批量插入** |
| 117 | +- `segments` 在 SegmentList 中有多选,但落地是**复制到剪贴板**而非插入笔记弹窗 |
| 118 | +- `NoteInsertDialog` 只被 `AnalysisPreview`(AI 分析结果)触发 |
| 119 | + |
| 120 | +用户如果想在 AI 分析完成之前(或替代 AI 分析)直接把转写原文段落塞进笔记,无法操作。 |
| 121 | + |
| 122 | +### 3.2 用户场景 |
| 123 | + |
| 124 | +1. **课中快速摘录**:上课 20 分钟出现重要讨论 → 勾选对应转写段落 → 追加到已有课程笔记 |
| 125 | +2. **课后快速归档**:AI 分析需要等待 2~5 分钟 → 不等了,选中关键原文批量插入 |
| 126 | +3. **原文备份**:AI 整理版之外,保留逐句转写原文作为底稿 |
| 127 | + |
| 128 | +### 3.3 方案探讨 |
| 129 | + |
| 130 | +**方案 A(推荐,轻量)**:UnifiedTimeline 每行转写加勾选框 → 底部"插入笔记"按钮 → 选中文本拼接为 Markdown(带 `[HH:MM:SS]` 时间戳)→ 传入 `NoteInsertDialog`(复用现有弹窗,`content` 参数不限来源) |
| 131 | + |
| 132 | +**方案 B(增强)**:AI 分析弹窗中增加"切换到原始转写版本"开关,用户选择插哪版 |
| 133 | + |
| 134 | +**方案 C(顺手修复)**:`SegmentList` 的"插入选中"改为弹出 `NoteInsertDialog`(而非当前仅 `clipboard.writeText`) |
| 135 | + |
| 136 | +### 3.4 与现有优先级的协同 |
| 137 | + |
| 138 | +推荐纳入 P0: |
| 139 | +- 改动量约 100 行,风险低 |
| 140 | +- 与 P0 时间轴方案共用选中交互,一次 UI 设计覆盖两个需求 |
| 141 | +- 修复了"采集 → 笔记"之间的灰色地带 |
| 142 | + |
| 143 | +--- |
| 144 | + |
| 145 | +## 四、技术注意 |
| 146 | + |
| 147 | +1. **主进程 CPU 评估**:页面级去重(方案 C)的双池哈希在渲染侧离线计算,不涉及主进程推理,性能风险低 |
| 148 | +2. **章节切分的 LLM 降级**:必须保留纯规则降级路径,防止章节切分阻塞笔记生成流程 |
| 149 | +3. **转写修正同步范围**:修正同步至 `audioText` 后,下游消费链为:mergeNotes(读 audioText)→ structureAndSave → 闪卡生成;需验证无数据穿透(修正后的文本不应回流到 ASR 模型) |
| 150 | +4. **NoteInsertDialog 通用化**:目前为止它只被 AnalysisPreview 调用。改为独立路由后,需确认弹窗被同时多次打开时的竞态(用 `showNoteDialog` 布尔锁已足够,无需额外防护) |
0 commit comments