状态:规划定稿(2026-08-23,设计完成待实施) 依据:用户对话 2026-08-23(图文笔记空内容修正需求 · WGC 稳定性评估 · 截屏 UX 对比调研 · DeepSeek 默认化裁决 · 视频 OCR 质量裁决 · 图片精修可选性与 AI 链条开关裁决) 前置:v0.11.7(图文会话)交付后开工
七项改进修正五个断裂:图文会话转笔记空内容的设计债(filter_note 正文源多态重构)、视频采集窗口遮挡的能力债(WGC 窗口级捕获 + 三级降级链)、图文截屏看不全的交互债(系统级覆盖层截图替代 letterbox 框选)、AI 默认链路过时的配置债(默认 Provider 切 DeepSeek + 默认模型 deepseek-v4-flash-vision-exp,旧 key 废除)、视频画面 OCR 质量差的质量债(本地 OCR 下线 + AI 精修图片理解可选增强)+ 全屏采集体验的体验债(浮窗化)。
| # | 项目 | 类型 | 落点 |
|---|---|---|---|
| 1 | 笔记正文源多态(长期重构) | P0 设计债 | detect_body_source 抽象层 + filter_note_from_ocr 精简净化链——图文会话 OCR 文本直接进入笔记 markdown |
| 2 | WGC 窗口级捕获 | P1 能力债 | 新增 capture/wgc_capture.rs,WGC 为主路径,DXGI 为降级 1,GDI 为兜底——三级自愈链 |
| 3 | 系统级覆盖层截图 | P2 交互债 | Tauri 独立全屏透明窗口替代应用内 letterbox 框选,1:1 原始像素显示,全局快捷键触发 |
| 4 | DeepSeek 默认化 | P1 配置债 | 默认 Provider 切 DeepSeek + 默认模型 deepseek-v4-flash-vision-exp;设置页预设/文案/价格表同步;旧 key 环境变量废除 |
| 5 | 视频会话画面要点降级 + vision-exp 视觉提取 | P1 质量债 | 本地 OCR 下线(仅保留字幕/图文采集);关键帧纯图;用户授权后 deepseek-v4-flash-vision-exp 视觉提取进笔记正文;vision 块回补章节/术语/大纲 |
| 6 | 采集浮窗化 | P1 体验债 | 采集中全屏看视频时悬浮小窗(状态/转写/控制),Tauri 子窗口 alwaysOnTop |
| 7 | 文档与治理 | 伴随 | ADR-021(正文源多态)+ ADR-022(WGC 窗口级捕获)+ ADR-023(视频 OCR 下线 + vision 提取)+ 本版本文档 |
问题:filter_note 硬编码 segments(转写段)为唯一正文源,ocr_blocks(OCR 块)始终为辅助画面要点不入 markdown。对视频会话这是正确设计(关键帧信息密度低),但对图文会话(kind=photo)——用户手动框选、OCR 文本即意图——导致笔记 markdown 只有标题,正文空。
根因:数据层的语义抽象不足——(segments, ocr_blocks) 二元组缺乏"哪个是正文"的表达层。
方案:引入 BodySource 枚举(Transcript / OcrDirect / Empty),detect_body_source 纯函数根据输入智能判断,filter_note 内部按来源分叉到不同过滤链:
segments ──┐
├→ detect_body_source ─→ Transcript ─→ 既有口语过滤链(视频,不变)
ocr_blocks ─┘ ─→ OcrDirect ─→ 精简 OCR 过滤链(图文,新增)
─→ Empty ─→ 标题仅
OCR 精简过滤链:排序 → 置信度过滤(0.5) → 符号归一(跳过口语净化——OCR 文本无结巴/口头禅) → 相邻去重 → markdown 组装。利用已有 region=="full" 标记为判断依据(photo_capture 写入的图文会话 OCR 块特征)。
与既有设计的冲突:无。Transcript 路径不做任何改动,OcrDirect 是纯新增分支——零回归风险。
问题:当前 DXGI Desktop Duplication 是显示器级捕获,窗口上方覆盖的 UI(弹窗/任务栏/通知)会入镜。GDI BitBlt 降级更差,遮挡完全无法避免。
方案:新增 WGC (Windows.Graphics.Capture) 后端,构建三级降级自愈链:
WGC(主,窗口级,Win 10 1903+)
↓ AcquireNextFrame 失败 / 安全桌面 / 窗口最小化
DXGI Desktop Duplication(降级 1,屏幕级+窗口裁剪,当前主路径)
↓ 远程桌面 / 锁屏 / 设备丢失
GDI BitBlt(兜底,全场景可用)
WGC 不稳定的场景及处理:
| 场景 | 表现 | 处理 |
|---|---|---|
| 安全桌面(UAC) | API 不可用 | 降级 DXGI |
| 全屏独占 DX 游戏 | 窗口脱离 DWM | 降级 DXGI(与当前行为一致) |
| 窗口最小化 | 丢帧 / 最后一帧 | 降级 DXGI+GDI,回退屏幕级捕获 |
| Win 10 1903 以下 | API 不存在 | 编译期 gate(#[cfg]),回退 DXGI |
| 无 DWM(Server Core) | API 不可用 | 降级 GDI |
ScreenCaptureSampler 扩展为三级链:新增 capture/wgc_capture.rs 模块(WinRT 异步帧回调 → 通道同步化),dxgi_capture.rs 的 ScreenCaptureSampler 增加 WGC 状态机,try_create_dxgi 语义泛化为 try_create_backend(WGC → DXGI → GDI 逐级尝试)。
问题:当前 ScreenSelectOverlay 在应用窗口内用 letterbox 缩略显示全屏截图——4K 屏在 1200px 窗口内缩到 73%,文字细节丢失。且需三步操作(开始采集 → 点击截屏 → 框选),vs 微信截图 Alt+A 一步触发。
市场调研:
| 方案 | 承载层 | 像素比例 | 触发方式 |
|---|---|---|---|
| 当前(ScreenSelectOverlay) | 应用内 letterbox | 缩放 50-80% | 应用内按钮三步 |
| Windows Snipping Tool | 独立全屏窗口 | 1:1 原始 | 全局 Win+Shift+S |
| 微信截图 | 全屏透明 WS_EX_LAYERED 窗口 | 1:1 原始 | 全局 Alt+A |
方案:Tauri 创建独立透明全屏窗口作为覆盖层,1:1 显示捕获帧,用户在原分辨率下框选:
全局快捷键 Ctrl+Shift+Q(或应用内按钮)
→ Tauri 创建全屏透明窗口(decorations:false, transparent:true, fullscreen:true)
→ 窗口内 1:1 像素显示当前帧(不缩略,超大屏幕可滚动手势缩放)
→ 用户拖拽框选(自动边缘检测候选)
→ 框选确认 → 窗口关闭 → PNG 回传主窗口 → 存图+OCR
→ Esc 取消 → 窗口关闭,无副作用
DPI 换算简化为零——覆盖层窗口以物理像素显示,鼠标坐标直接对应图像坐标。交互流从当前三步缩减为一步(快捷键→框选→确认,快捷键→框选→Esc)。
跨窗口通信:主窗口等待覆盖层结果(通道 / event bus);覆盖层不持久,截完即销毁。
问题:当前预设模板首选项为 SiliconFlow(legacy 迁移默认);旧 key 已废除,默认链路应切到 DeepSeek 官方端点 + deepseek-v4-flash-vision-exp(视觉多模态,图文会话精修/OCR 增强的未来主力)。
方案:
preset_templates()将 DeepSeek 提到首位(effective_default_id取第一个 enabled → DeepSeek 生效);DeepSeek 预设 models 添加deepseek-v4-flash-vision-exp,default_model 改为该模型legacy迁移(migrate_from_legacy)目标从 SiliconFlow 改为 DeepSeek(旧 key 废除后迁移到新默认链)ai_cost.rsbuiltin_prices 登记 deepseek-v4-flash-vision-exp 价格(官方 2026-08:输入缓存未命中 1.5-3.0 元/百万,输出 4.5-9.0 元/百万——取保守上界 9.0 登记,注释标注分段价)- 前端
AiProviderSettingsPRESET_OPTIONS 同步(I-3 双源:后端优先,前端兜底) - 文案统一:AiRefineCard/EnrichPanel/NotePreviewView 的 SiliconFlow 硬编码文案 → DeepSeek(或通用 Provider 表述)
- 旧 key 废除:
SILICONFLOW_API_KEY环境变量读取路径移除/改为DEEPSEEK_API_KEY;401 错误文案同步
与既有设计的冲突:无。Provider 机制不变(BYOK 多端点),仅默认指向与预设内容更新。
问题:本地 PaddleOCR 对视频全帧画面要点提取质量差(动态模糊/复杂版面/小字/干扰物)——同一引擎在字幕/图文场景效果好。
决策(用户 2026-08-23 裁决):
- 本地 OCR 只做字幕(视频)+ 图文采集(photo 会话)——视频会话不再做全帧 OCR
- 关键帧纯图(存图不识别);存图触发从「OCR 文本非空」解耦为「grid diff 变化 + 时间间隔」
- vision-exp 图片理解(可选增强,仅视频会话,并入 AI 精修):不做独立提取命令——精修时若
vision_refine_enabled开启,屏卡图随转写文本一并送 vision-exp(content 数组多模态),精修输出直接含画面要点;屏卡缩略图走现有 attach_images - 图文会话 OCR 已足够,不启用 vision(用户决策:仅视频会话使用)
- 图片精修可选性:
vision_refine_enabled开关(默认关)——图片上传最敏感,独立闸门,关闭则精修纯文本(现有行为零变化) - AI 强化链条总开关:复用现有
AiSettings.enabled(全局闸门,默认关)——关闭则采集期领域识别/AI 复核/精修/补充全部拒绝(已有 content_gate 门控) - 图片缩略图走现有机制(attach_images / convertFileSrc,屏卡配图不新建通道)
隐私红线:图片上传默认关(vision_refine_enabled 默认 false + 全局 enabled 默认关);关闭时精修走纯文本(零变化);图片仅随精修切片请求上传,不作独立提取(ADR-010 扩展)。
- 新增
note_body_source.rs:BodySource枚举 +detect_body_source纯函数 + 独立单测 - 新增
note_filter_ocr.rs:filter_note_from_ocr精简净化链(排序 → 置信过滤 → 符号归一 → 相邻去重 → markdown) - 修改
note_filter.rs:filter_note入口增加BodySource分派(use note_body_source+use note_filter_ocr),三路 match - 修改
lib.rs:注册note_body_source+note_filter_ocr模块 - 更新
note_filter_tests.rs:适配filter_note_with_empty_segments测试新语义(OCR 文本进入 markdown,ocr_points 空) - 验收:纯图文会话转笔记 → markdown 含 OCR 识别文字;视频会话转笔记 → 零变化(回归验证)
- 新增
capture/wgc_capture.rs:WgcState(WinRTGraphicsCaptureItem+Direct3D11CaptureFramePool+ 通道发送端)WgcState::create(hwnd)→ 按窗口句柄创建捕获目标 + 帧池 + 捕获会话- 异步帧回调 → 通道同步化(帧到达推入
crossbeam_channel/std::sync::mpsc) capture()→ 从通道取最新帧(non-blocking try_recv)
- 修改
capture/dxgi_capture.rs:ScreenCaptureSampler扩展为三级链- 新增
backend: enum CaptureBackend { Wgc, Dxgi, Gdi } try_create_backend()逐级尝试(WGC → DXGI → GDI)capture()按当前后端路由,失败自动降级下一级
- 新增
DxgiStatetry_create_dxgi旧逻辑保留,作为三级链中段- 验收:窗口被遮挡时捕获内容不受影响;远程桌面/锁屏自动降级;窗口关闭后兜底正常
- 主进程:
Tauri::Builder注册覆盖层窗口工厂(create_overlay_window / close_overlay_window) - 渲染进程(覆盖层窗口):
- 全屏透明窗口显示捕获帧(1:1 像素,超大屏幕加平移/捏合缩放)
- 框选组件(仿微信截图 + 自动边缘检测)
- 确认后通过 IPC 回传裁剪 PNG base64
- 渲染进程(主窗口):
PhotoCapturePanel适配两触发器(应用内按钮 / 全局快捷键)- 等待覆盖层结果 →
save_photo_capture存图+OCR
- 验收:图文采集一步触发框选;4K 屏不再缩略;框选精度提升
ai_provider.rs:preset_templates()DeepSeek 提首位 + models 加 deepseek-v4-flash-vision-exp + default_model 切换;migrate_from_legacy目标改 DeepSeekai_cost.rs:builtin_prices 登记 deepseek-v4-flash-vision-exp(保守上界 9.0,注释标注分段价待实测校准)AiProviderSettings.tsx:PRESET_OPTIONS DeepSeek 行同步- 文案:AiRefineCard/EnrichPanel/NotePreviewView 硬编码 SiliconFlow → DeepSeek;
commands_ai_providers.rsenv 读取 SILICONFLOW_API_KEY → DEEPSEEK_API_KEY - 测试:ai_provider_tests 断言适配(DeepSeek 首位/迁移目标);ai_cost_tests 价格断言
- 验收:新装/迁移用户默认 Provider=DeepSeek、默认模型=deepseek-v4-flash-vision-exp;设置页预设与文案一致;成本估算显示正确单价
live_keyframes.rs:handle_full_frame拆分——存图触发解耦(grid diff + 2s 防抖,不再依赖 OCR 文本);OCR 落库分支退役(视频会话)live_frame_process.rs:全帧分支跳过recognize_image_timeout(保留 is_subtitle 路径不动);screen_tracker.assign_screen输入从 texts 改为 layout_changed + grid diffai_client.rs:新增chat_vision(system, user, images)——OpenAI 兼容 content 数组(text + image_url data URI);现有 chat_text/chat_json 9 处调用零改动ai_note_refine.rs:refine()增加多模态分支——vision_refine_enabled开启时组装屏卡图为 image_url 随切片请求(屏卡图来自 session_images_dir 归档,缩放 ≤1280px 控 token);关闭时纯文本(现有行为零变化)ai_settings.rs:新增vision_refine_enabled: bool(默认关)AiServicePanel.tsx:新增「精修时启用画面理解」复选框(复用现有开关模式)- 触发:仅 AI 精修时生效(不新增独立命令/自动触发)
- 验收:视频会话关键帧纯图默认态;开启图片开关后精修请求含屏卡图、输出含画面要点;关闭开关精修纯文本零变化;图文会话不受影响;
enabled=false时精修命令拒绝
commands_window.rs(新增):open_capture_float()/close_capture_float()——WebviewWindowBuilder 创建 "capture-float" 子窗口(alwaysOnTop/decorations:false/transparent/skipTaskbar/360×240),加载index.html?float=1capabilities/default.json:windows 列表加 "capture-float"CaptureFloatPanel.tsx(新增):顶部状态(录制/暂停/时长/电平)· 中部最近转写 2-3 条 · 底部最近画面缩略图 · 操作按钮(暂停/继续/标记/停止/回主窗)useLiveSessionEvents.ts(新增 hook):从 LiveActivityPanel 抽取事件监听逻辑(partial/final/subtitle/status)——主面板与浮窗共用App.tsx入口:URL 带 ?float=1 → 渲染 CaptureFloatPanel(不渲染主导航壳)ClassroomPage.tsx:采集中按钮组加「🗕 浮窗化」+ 快捷键 Ctrl+Shift+F;停止后自动关闭浮窗- 验收:全屏视频上浮窗置顶可见;暂停/标记/停止可操作;停止后浮窗自动关闭
- ADR-021:笔记正文源多态——
detect_body_source架构决策 - ADR-022:WGC 窗口级捕获——三级降级链决策
- ADR-023:视频会话 OCR 下线 + vision-exp 视觉提取(含隐私授权契约)
- 本版本文档
- 正文源多态是长期重构:不是打补丁——
note_body_source.rs作为独立抽象层,detect_body_source可扩展(未来导入 PDF/网页截图等新正文源只需加变体,不改过滤链核) - OCR 不走口语净化链:OCR 文本是视觉识别产物,无 ASR 的结巴/填充词/重复。引用 photo_capture 已有规则:用户框选即意图,不过 UI 垃圾黑名单
- WGC 异步转同步:WinRT 异步帧回调通道化——采集线程仍保持
capture()同步接口,上层 Worker 零改动(变化检测/双速率调度/OCR 编排全部复用) - 三级链不引入新不确定性:WGC 初版编译期
#[cfg(windows)]gate,Win 10 1903 以下回退 DXGI/GDI——旧系统行为零变化 - 覆盖层窗口不持久:截完即销毁,不常驻内存。跨窗口通信不走 DB/文件,IPC event 直传
- YAGNI:覆盖层不引入截图编辑(标注/马赛克/文字)——仅框选;WGC 最小化场景不回退到 DXGI 后不尝试自动切回——沿用 DXGI 已有 30s 周期重建(TD-033 快速节流同理)
- 版本号策略:七项跨模块不关联——M1 可独立发 patch(
v0.11.8);M4 可独立发(v0.11.9,配置债零风险);M2+M3+M5+M6 合入v0.12.0;M5 依赖 M4(vision-exp 默认链),M6 独立
- M1:纯图文会话(
kind=photo,无 segments)→session_to_note产出 markdown 含 OCR 识别文本,且标注"图文提取"段;视频会话转笔记 → 零变化(回归);cargo test note_filter全通过 - M2:目标窗口被遮挡时捕获内容为窗口实际内容(非遮挡物);远程桌面会话下自动降级 DXGI/GDI 且不 panic;窗口关闭/最小化时捕获按现有 DXGI/GDI 逻辑兜底;
cargo build通过 - M3:图文采集快捷键触发全屏覆盖层 → 1:1 像素显示 → 框选确认 → 截图落库;当前 letterbox 路径保留为降级(覆盖层窗口创建失败时回退)
- M4:新装/迁移用户默认 Provider=DeepSeek、默认模型=deepseek-v4-flash-vision-exp;设置页预设与文案一致;成本估算显示正确单价
- M5:视频会话关键帧纯图(无 OCR 文字);开启图片开关后精修请求含屏卡图、输出含画面要点;关闭开关精修纯文本零变化;图文会话不受影响;
enabled=false时精修命令拒绝 - M6:全屏视频上浮窗置顶可见;暂停/标记/停止可操作;停止后浮窗自动关闭
- 全量回归:
cargo test/cargo clippy --all-targets/tsc/vitest
| 层 | M1 笔记正文源 | M2 WGC 捕获 | M3 覆盖层截图 | M4 DeepSeek | M5 vision 提取 | M6 浮窗 |
|---|---|---|---|---|---|---|
| 纯函数 | detect_body_source 黄金用例(5 场景)、filter_note_from_ocr 过滤链(空/重复/低分) |
D3D11 设备管理可测(mock),变化检测复用现有 frame_diff_tests.rs |
坐标换算复用 photoCrop.test.ts,增加全屏覆盖层场景 |
ai_provider_tests 顺序/迁移断言 | build_chat_payload 多模态分支、vision 开关门控 |
useLiveSessionEvents hook 事件合并 |
| 数据层 | 内存库 create_session(kind=photo) + add_ocr_block + session_to_note 验证 markdown |
不涉及 | 不涉及 | 不涉及 | vision_refine_enabled 持久化 | 不涉及 |
| 集成 | 图文会话全链路(capture → save → finish → to_note) | 暂不 mock DXGI/WGC,真机验收 | 暂不 mock 多窗口 IPC,真机验收 | 不涉及 | 开关开/关两种精修请求形态 | 多窗口创建/关闭真机验收 |
| 前端 | 不涉及(纯 Rust 改动) | 不涉及 | ScreenSelectOverlay.spec.tsx 的 ESC/鼠标事件覆盖新窗口模式 |
AiProviderSettings 预设渲染 | AiServicePanel 新复选框 | CaptureFloatPanel 状态/按钮 |
- 覆盖层截图的标注/编辑/OCR 实时预览功能以用户反馈为门控,不预排
- WGC 全路径达到生产级后,
ScreenCaptureSampler可移除CaptureBackend枚举的 DXGI 前两位保留为仅降级 - 正文源多态为未来"导入 PDF/网页截图直接转笔记"提供架构地基(仅需新增
BodySource::PdfDirect+ 对应过滤链) - PPT 语义提取(通义听悟对标):M5 的 AI 精修图片理解是地基(屏卡图随精修上云),未来可升级为独立多屏卡批量提取 + 图文总结 + PPT 导出——以用户反馈为门控
- 双声源分离(Granola Me/Them):WASAPI 环回 + 麦克风双流融合,speaker 影子列(types.rs)已留桩——需独立 ADR,记 TD
- 转录面板片段操作(复制/删除/搜索,Granola 转录面板对标):依赖 live:asr-final 段 id 回传协议扩展,记需求池
- 问题回顾展示(通义听悟对标):复用修辞问句检测逻辑改为双向输出,记需求池
- 热词建议(Granola Internal Jargon 对标):会话后低置信段+高频专名 → 候选词一键采纳,记需求池
- 自动结束与 Resume:15min 无音频自动停(idle_governor 扩展)+ 已结束会话恢复转录(生命周期语义变更)——需独立 ADR,记 TD
- 设计文档:2026-08-23-v0.12.0-body-source-wgc-overlay-design(待写,未落档)
- 依赖/复用:
capture/frame_diff.rs(变化检测纯函数)·capture/dxgi_capture.rs(降级 1 层)·capture/gdi_capture.rs(兜底层)·photo_capture.rs(OCR 块 region=full 写入)·note_filter.rs(既有 Transcript 路径完全不变)·ai_client.rs(chat_vision 多模态扩展点)·live_keyframes.rs(存图触发解耦) - 市场对标:Granola(转录面板/自动停止/Me-Them 双声源/浮窗指示器)· 通义听悟(PPT 提取/问题回顾/值得关注)· Notion AI(结构化上下文)
- ADR-002(DXGI 窗口裁剪)· ADR-010(AI gap-filling 隐私契约——M5 授权扩展)· ADR-018(FSRS)· ADR-020(图文会话 kind=photo)