# ChatPapers 双模式集成架构设计 | 字段 | 内容 | |------|------| | 产品名称 | ChatPapers for Zotero | | 文档名称 | 双模式集成架构(方案 A) | | 文档版本 | v0.1 | | 状态 | 草案 | | 目标平台 | Zotero 9(macOS / Windows) | | 关联文档 | [双模式 PRD](./DUAL_MODE_PRD.md)、[开发文档](../development.md)、[BanDu 架构参考](./ARCHITECTURE.md) | > **本文档定位**:描述 ChatPapers 插件在保留**文字对话**能力的基础上,扩展**语音伴读**(备课 → 听课 → 语音问答)的架构设计。 > 产品统一品牌为 **ChatPapers**;两种模式是同一条「与论文对话」产品线的不同交互形态——文字即时聊 vs 语音系统讲。 --- ## 1. 架构概述 ### 1.1 架构演进 ``` v0.2(当前) v1.0(目标) ───────────────── ───────────────────────────────── ChatPapers 插件 ChatPapers 插件(单一 .xpi) └── 文字对话 pane ├── 文字对话 pane(已有) PDFWorker 纯文本 │ 即时问答 / 总结 / JSON 会话 LLM 流式 │ sessions/*.json └── 语音伴读 pane(新增) MinerU 段落树 Lecture 备课 + TTS + 播放器 SQLite + mp3 缓存 共享:LLM · PDF 附件 · 笔记 · BibTeX ``` ### 1.2 架构风格 **Local-first 双模式插件架构**:核心计算与缓存均在用户机器完成;仅将段落文本与用户问题发送至用户配置的 LLM / TTS 服务。无自建后端。 ### 1.3 设计原则 | 原则 | 说明 | |------|------| | 单一插件、两种对话形态 | 文字对话与语音伴读并存,共享 LLM 与 Zotero 集成 | | 模块隔离 | 语音模块不侵入文字对话代码路径 | | 备课一次、缓存复用 | Lecture 持久化;attachment ID + 文件哈希为缓存键 | | 增量交付 | 摘要 → beats → 逐段 → TTS 分阶段就绪 | | UI / 领域 / 集成 分离 | 降低 Zotero API 变动影响 | | Grounding 优先 | 生成内容必须可追溯到段落 ID | | 优雅降级 | refs 无效、无 timestamps、无 BBT 均有 fallback | ### 1.4 系统上下文 ``` ┌─────────────────┐ │ 用户 │ └────────┬────────┘ │ ┌──────────────▼──────────────┐ │ Zotero 9(宿主) │ │ ┌────────────────────────┐ │ │ │ ChatPapers 插件 │ │ │ │ ┌──────────┬─────────┐ │ │ │ │ │文字对话 │语音伴读 │ │ │ │ │ │ ChatView │LectureUI│ │ │ │ │ └────┬─────┴────┬────┘ │ │ │ │ │ Shared │ │ │ │ │ └─────┬─────┘ │ │ │ └────────────┼────────────┘ │ └───────────────┼──────────────┘ │ ┌─────────────────────────┼─────────────────────────┐ │ │ │ ▼ ▼ ▼ ┌─────────────┐ ┌─────────────┐ ┌─────────────┐ │ Zotero │ │ LLM API │ │ TTS API │ │ PDFWorker │ │ / Ollama │ │ 火山/Azure等 │ │ MinerU │ │ (共享) │ │(语音模式) │ └─────────────┘ └─────────────┘ └─────────────┘ │ ▼ ┌─────────────────────────────────────┐ │ {Profile}/chatpapers/ │ │ sessions/*.json ← 文字对话 │ │ lecture/lecture.db ← 语音伴读 │ │ lecture/audio/ │ └─────────────────────────────────────┘ ``` ### 1.5 两种对话形态对比 | 维度 | 文字对话(已有) | 语音伴读(新增) | |------|------------------|------------------| | 用户意图 | 「我现在想问什么」 | 「请 AI 先读完再给我讲」 | | 交互 | 打字 → 文字流式回复 | 听课 → 打字提问 → 文字 + 语音回复 | | PDF 输入 | PDFWorker 整篇纯文本 | MinerU 结构化段落树 | | LLM 用法 | 每轮即时组装 context | 一次性备课 + 按需问答 | | 持久化 | `sessions/{itemKey}.json` | `lecture/lecture.db` + mp3 | | TTS | 无 | 讲解 + 问答回答均支持 | | 笔记 | `ChatPapers:` 前缀 | `ChatPapers 伴读报告:` 前缀 | --- ## 2. 整体分层架构 ``` ┌──────────────────────────────────────────────────────────────────┐ │ Presentation Layer(表现层) │ │ 【文字】chatView.ts · multiChatView.ts · readerPane (Chat sec) │ │ 【语音】lecturePane.ts · player/ · libraryWindow.ts(P1) │ │ 【共享】prefs.ts · preferences.xhtml │ └───────────────────────────────┬──────────────────────────────────┘ │ ┌───────────────────────────────▼──────────────────────────────────┐ │ Application Layer(应用层 / 用例) │ │ 【文字】buildChatMessages · buildMultiChatMessages(已有) │ │ 【语音】PrepareLectureUseCase · PlayUseCase │ │ AskQuestionUseCase · GenerateReportUseCase │ └───────────────────────────────┬──────────────────────────────────┘ │ ┌───────────────────────────────▼──────────────────────────────────┐ │ Domain Layer(领域层) │ │ 【文字】ChatMessage · ExtractResult(已有) │ │ 【语音】PaperCache · Paragraph · Chapter · Lecture · Beat │ │ ParagraphExplanation · QARecord · Progress · Highlight │ │ LecturePreparationState · PlayerState │ └───────────────────────────────┬──────────────────────────────────┘ │ ┌───────────────────────────────▼──────────────────────────────────┐ │ Infrastructure Layer(基础设施层) │ │ ┌─ 共享 ─────────────────────────────────────────────────────┐ │ │ │ llm/client · llm/providers · zotero/notes · zotero/citeExport│ │ │ │ pdf/extractor (附件定位) · pdf/selection · utils/* │ │ │ └────────────────────────────────────────────────────────────┘ │ │ ┌─ 文字专属 ─────────────────────────────────────────────────┐ │ │ │ pdf/context · pdf/multiContext · storage/sessions │ │ │ └────────────────────────────────────────────────────────────┘ │ │ ┌─ 语音专属 ─────────────────────────────────────────────────┐ │ │ │ lecture/infrastructure/pdf (MinerU) · tts/ · storage/sqlite │ │ │ │ lecture/infrastructure/rag · audioStorage · promptRegistry │ │ │ └────────────────────────────────────────────────────────────┘ │ └──────────────────────────────────────────────────────────────────┘ ``` --- ## 3. 现有代码映射 ### 3.1 共享层(已实现,语音模式直接复用) | 模块路径 | 职责 | 文字对话 | 语音伴读 | |----------|------|:--------:|:--------:| | `src/hooks.ts` | 生命周期、注册入口 | ✓ | 扩展注册 | | `src/modules/ui/readerPane.ts` | Item pane section 注册 | ✓ | 扩展第二 section | | `src/modules/llm/client.ts` | LLM 流式请求 | ✓ | ✓ 备课 + 问答 | | `src/modules/llm/providers.ts` | Provider 预设 | ✓ | ✓ 只读共享 prefs | | `src/modules/llm/types.ts` | ChatMessage 等类型 | ✓ | 问答层可复用类型 | | `src/modules/pdf/extractor.ts` | PDF 附件定位 | ✓ | ✓ 路径 + 扩展 hash | | `src/modules/pdf/selection.ts` | Reader 选区 | ✓ | ✓ 「解释这句」 | | `src/modules/zotero/notes.ts` | 子笔记创建 | ✓ | ✓ 伴读报告 | | `src/modules/zotero/citeExport.ts` | BibTeX 导出 | ✓ | ✓ 参考文献卡片 | | `src/utils/markdown.ts` | Markdown 渲染 | ✓ | ✓ 报告预览 | | `src/utils/prefs.ts` | Preference 读写 | ✓ | ✓ 扩展 TTS prefs | | `src/utils/abort.ts` | 请求取消 | ✓ | ✓ | ### 3.2 文字对话专属(已实现,语音模式不得引用) | 模块路径 | 职责 | |----------|------| | `src/modules/ui/chatView.ts` | 文字对话 UI | | `src/modules/ui/multiChatView.ts` | 多 PDF 联合对话 | | `src/modules/pdf/context.ts` | 单篇 context 组装 | | `src/modules/pdf/multiContext.ts` | 多篇 context 组装 | | `src/modules/llm/prompts.ts` | 文字对话 system / summary prompt | | `src/modules/llm/history.ts` | 论文材料持久化到消息历史 | | `src/modules/storage/sessions.ts` | JSON 会话文件 | ### 3.3 语音伴读新建(`src/modules/lecture/`) | 模块 | 职责 | |------|------| | `lecture/ui/lecturePane.ts` | Item pane「语音伴读」section | | `lecture/ui/playerController.ts` | 播放状态机 + `