Files
ReadViewSDK/Doc/RDAIReaderView/RDAIReaderView-ARCHITECTURE.md
T
2026-07-27 21:43:13 +08:00

432 lines
13 KiB
Markdown
Raw 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.
# RDAIReaderView 架构设计
**文档状态:** Draft 0.1
**最后更新:** 2026-07-25
**目标版本:** RDAIReaderView 1.0
## 1. 架构目标
RDAIReaderView 必须满足四个架构目标:
1. 不改变 RDPDFReaderView、RDEpubReaderView 和 RDSpeechReaderView 的核心职责。
2. iOS 15 用户继续获得稳定阅读、基础 NLP 和 TTSFoundation Models 仅作为可选增强。
3. 所有生成结果都能追溯到稳定原文位置。
4. AI Provider、索引实现和 UI 可替换,公共数据模型保持稳定。
## 2. 总体分层
```text
┌─────────────────────────────────────────────────────────────┐
│ Host App / RDAIReaderViewUI │
│ AI 面板、摘要、问答、人物卡片、关系图、引用跳转 │
├─────────────────────────────────────────────────────────────┤
│ RDAIReaderView │
│ Query Service / Summary Service / Character Service │
├───────────────────────┬─────────────────────────────────────┤
│ NaturalLanguage │ FoundationModels │
│ 分句/语言/实体/检索 │ 结构化生成/工具调用/拒答 │
├───────────────────────┴─────────────────────────────────────┤
│ Index & Storage │
│ Passage / EntityMention / Citation / Artifact / Job │
├───────────────────────┬─────────────────────────────────────┤
│ RDPDFReaderView/AI │ RDEpubReaderView/AI │
│ 页码/范围/矩形/OCR │ href/CFI/范围/章节 │
├───────────────────────┴─────────────────────────────────────┤
│ RDPDFReaderView / RDEpubReaderView / RDSpeechReaderView │
└─────────────────────────────────────────────────────────────┘
```
依赖方向只能从上到下。阅读器核心不能反向依赖 RDAIReaderView。
## 3. CocoaPods 模块设计
建议新增:
```ruby
pod 'RDAIReaderView/Core'
pod 'RDAIReaderView/NaturalLanguage'
pod 'RDAIReaderView/FoundationModels'
pod 'RDAIReaderView/UI'
pod 'RDPDFReaderView/AI'
pod 'RDEpubReaderView/AI'
```
### 3.1 Core
- 最低 iOS 15。
- 只依赖 Foundation、SQLite3/CryptoKit 等系统能力。
- 包含公共协议、数据模型、索引调度、存储和查询编排。
- 不导入 UIKit、PDFKit、DTCoreText 或 FoundationModels。
### 3.2 NaturalLanguage
- 最低 iOS 15。
- 依赖 Core 和 NaturalLanguage。
- 提供语言识别、分句、实体候选、关键词和语义评分。
- iOS 17+ 可选使用 `NLContextualEmbedding`;资源不可用时降级。
### 3.3 FoundationModels
- 源码使用 `@available(iOS 26.0, *)` 隔离。
- 依赖 Core 和系统 FoundationModels。
- 需要支持 Foundation Models 的 Xcode 工具链。
- 不被基础 Pod 默认引入,避免旧工具链客户无法编译。
### 3.4 UI
- 最低 iOS 15。
- 依赖 Core,可选识别 FoundationModels 可用性。
- UI 不直接构造 Prompt,也不直接访问数据库。
### 3.5 Reader Adapters
- `RDPDFReaderView/AI` 依赖 RDAIReaderView/Core。
- `RDEpubReaderView/AI` 依赖 RDAIReaderView/Core。
- Adapter 只负责内容快照、定位转换、跳转和高亮。
## 4. 建议目录
```text
Sources/RDAIReaderView/
├── RDAIReaderView.podspec
├── Core/
│ ├── Contracts/
│ ├── Models/
│ ├── Indexing/
│ ├── Retrieval/
│ ├── Storage/
│ └── Services/
├── NaturalLanguage/
│ ├── Analysis/
│ ├── Embeddings/
│ └── Retrieval/
├── FoundationModels/
│ ├── Availability/
│ ├── Generation/
│ ├── Prompts/
│ ├── Schemas/
│ └── Tools/
├── UI/
│ ├── Assistant/
│ ├── Citations/
│ └── Characters/
└── Tests/
Sources/RDPDFReaderView/AI/
Sources/RDEpubReaderView/AI/
```
## 5. 核心数据流
### 5.1 建立索引
```text
ContentProvider
↓ 读取资源快照
Text Snapshot + Stable Locator
Language Detection
Paragraph/Sentence Chunking
Entity Mentions + Keywords + Embeddings
Transactional Storage
Index Checkpoint
```
每次数据库事务只提交一个资源或一组有界片段。应用退出时,最多重做当前事务,不重做整本书。
### 5.2 问答
```text
User Question
Language / Intent / Spoiler Scope
Hybrid Retrieval
Access + Read-Progress Filter
Context Budget Builder
Foundation Models Structured Generation
Citation Validator
Answer or Evidence-Insufficient Refusal
```
检索由代码执行。首版不让模型自由遍历整本数据库,只有需要多轮查找时才使用受限 Tool Calling。
### 5.3 人物关系
```text
Entity Mentions
Alias Candidate Grouping
Chunk-level Structured Extraction
Evidence Validation
Relationship Merge
confirmed / possible / conflicting
```
代码只能自动合并完全相同的标准化名称和明确别名。代词消解、同名人物合并和隐含关系必须保持低置信度,等待更多证据或用户确认。
## 6. 稳定定位模型
### 6.1 通用定位
`RDAILocator` 包含:
- `documentIdentifier`
- `resourceIdentifier`
- `utf16Range`
- `sourceHash`
- 格式专属 Anchor
文本范围统一使用 UTF-16,与现有 RDSpeechReaderView、NSString 和 EPUB 搜索范围保持一致。
### 6.2 PDF Anchor
```text
pageIndex
normalizedRects
textSource: native / ocr
readingOrder
```
PDF Adapter 从现有 `RDPDFReaderTextRun` 构建连续页文本和 UTF-16 范围。每个 Passage 必须保留与 run 的映射,不能在 AI 层重新拼接后丢失矩形。
扫描 PDF 使用现有 `speechTextRuns(at:)`/OCR 能力,但商用实现应增加独立的 AI OCR 调度入口,避免页面导航取消请求时同时取消后台索引。
### 6.3 EPUB Anchor
```text
normalizedHref
cfi
rangeCFI
rangeAnchor
progressionFallback
```
优先级:
1. `rangeCFI`
2. `cfi + UTF-16 range`
3. `rangeAnchor`
4. `href + progression`
屏幕页码只用于展示,不能作为持久化引用主键。
## 7. 文本快照与分块
### 7.1 不修改原文
索引保存两份文本信息:
- `sourceText`:原始文本,用于引用与范围映射。
- `searchText`:规范化副本,用于检索。
禁止使用规范化文本范围直接驱动阅读器高亮。
### 7.2 分块策略
- 先按资源和章节边界划分。
- 再按段落划分。
- 超长段落使用 `NLTokenizer(unit: .sentence)`
- 中文目标 600-900 字;英文目标 300-600 词。
- 片段之间保留 1-2 句重叠。
- 表格、代码、脚注和标题保留语义类型,避免与正文无差别拼接。
### 7.3 内容哈希
建议使用 SHA-256
```text
documentHash = hash(ordered resource identifiers + resource hashes)
resourceHash = hash(source text + format-specific stable metadata)
passageHash = hash(resource hash + UTF-16 range + source text)
```
书籍更新时按资源哈希增量失效。
## 8. 检索架构
首版采用 Hybrid Retrieval
```text
finalScore =
0.45 * lexicalScore +
0.40 * semanticScore +
0.10 * proximityScore +
0.05 * headingBoost
```
权重是初始值,必须通过评测集调优,不作为永久常量。
检索步骤:
1. 规范化查询并识别语言。
2. 关键词倒排召回 Top 30。
3. 语义相似度重排。
4. 合并高度重叠 Passage。
5. 按已读范围、文档授权和最大上下文过滤。
6. 返回 Top 3-4,并保留评分解释。
若语义模型资源不可用,使用纯词法检索,不阻塞问答入口;UI 可提示结果质量可能降低。
## 9. Foundation Models 编排
### 9.1 Provider 抽象
Core 只依赖 `RDAIGenerativeProvider`。Apple 实现位于 FoundationModels 子模块,未来可增加 Core ML、MLX 或经用户授权的云端实现。
### 9.2 会话策略
- 摘要、问答、人物关系使用不同 instructions 和独立会话。
- 同一会话只处理一个并发请求。
- 用户切换书籍、变更阅读范围或取消时终止任务。
- 达到上下文阈值前主动新建会话,不等待系统抛错。
- 记录 Prompt 版本、模型可用性分类、耗时和 token 数,不记录原文。
### 9.3 上下文预算
默认预算建议:
| 项目 | Token 预算 |
|------|------------|
| Instructions + Schema | 500 |
| 用户问题 | 200 |
| 检索上下文 | 2400 |
| 模型输出 | 700 |
| 安全余量 | 296 |
实际使用 `contextSize``tokenCount(for:)` 动态计算,不写死为 4096。
### 9.4 引用验证
生成后执行确定性校验:
1. Citation ID 必须存在于本次上下文。
2. Citation 必须属于当前文档和允许阅读范围。
3. 引用文本必须能在 Passage 原文中匹配。
4. 每个事实项至少有一个有效引用。
5. 删除无效项后答案为空,则返回 evidence insufficient。
## 10. 存储设计
建议使用 SQLiteSchema 初稿:
```text
documents
resources
passages
passage_fts
embeddings
entity_mentions
entities
entity_aliases
relationships
relationship_evidence
artifacts
index_jobs
schema_metadata
```
关键原则:
- FTS 和关系表通过 Passage ID 关联原文。
- 向量数据按模型标识符、revision 和语言分区。
- 生成结果不覆盖人工编辑内容。
- 每个 Artifact 保存 Prompt/模型/输入哈希。
- 索引表支持按文档级联删除。
## 11. 并发与生命周期
建议采用 Swift Concurrency
- `RDAIIndexCoordinator`actor,管理索引队列和 checkpoint。
- `RDAIStore`actor,串行化数据库写入。
- `RDAIRetriever`:Sendable 服务,可并发读取快照。
- Reader Adapter`@MainActor`,仅提取 UI/阅读器状态和执行跳转。
- Foundation Models Session:由单请求 actor 或服务隔离。
优先级:
1. 用户当前问答所需 Passage。
2. 当前章节。
3. 相邻章节。
4. 已读范围。
5. 其余获准内容。
发生内存警告时:
- 取消低优先级 embedding 任务。
- 卸载 contextual embedding。
- 清理内存 Passage/向量缓存。
- 保留已提交数据库和当前用户请求。
## 12. 可用性与降级
```text
Foundation Models available
├─ 是 → 完整生成能力
└─ 否
├─ Natural Language available → 索引、实体、基础检索
└─ 语言/资源不支持 → 关键词检索与基础分段
```
降级状态是公共 API 的一部分,UI 不根据 Error 字符串猜测原因。
## 13. 安全与隐私
- 默认 Provider 为设备端 Provider。
- Core 不包含网络代码。
- 云端 Provider 若未来增加,必须是单独 Pod,并要求宿主显式配置。
- 日志只记录文档匿名哈希、阶段、耗时、错误类别和计数。
- 禁止记录 Prompt、Passage、用户问题和模型回答全文。
- 导出诊断包前再次脱敏。
- 删除书籍时由宿主调用 `removeDocument`,同时删除索引、关系和生成缓存。
## 14. 可观测性
本地指标:
- 索引耗时、资源数、片段数、失败类别。
- 检索 P50/P95、召回数量和降级模式。
- 生成耗时、取消率、错误类别和引用校验失败率。
- Foundation Models availability 分布。
- 缓存命中率和数据库大小。
商用版本默认只汇总数值。任何远程遥测必须由宿主决定,并遵守其隐私政策。
## 15. 架构决策记录
实施时至少补充以下 ADR
- ADR-001:独立 RDAIReaderView 而非嵌入阅读器核心。
- ADR-002UTF-16 作为跨模块文本范围。
- ADR-003:本地 SQLite 和增量资源哈希。
- ADR-004:检索先行、生成后置、引用强校验。
- ADR-005Foundation Models 可选依赖和运行时降级。
- ADR-006:已读范围作为默认安全边界。
## 16. 已知技术风险
| 风险 | 影响 | 缓解 |
|------|------|------|
| 中文小说实体识别不足 | 人物漏识别或误合并 | 规则候选 + 结构化模型提取 + 证据与置信度 |
| OCR 阅读顺序错误 | 摘要和引用错误 | 保留 readingOrder、双栏测试、允许宿主提供文本 |
| PDF OCR 请求被页面导航取消 | 后台索引不完整 | AI 使用独立调度队列与缓存 |
| EPUB 重排后范围变化 | 引用跳转漂移 | CFI/rangeCFI 优先,文本哈希校验 |
| 系统模型更新 | Prompt 质量回归 | Prompt 版本化、模型版本分层评测 |
| 上下文不足 | 回答遗漏 | 检索压缩、分层摘要、新会话 |
| 同名人物 | 错误关系合并 | 不自动合并低置信候选,保留冲突 |