AstroResearch/docs/architecture.md
Asfmq e13fa2ad40 refactor!: 模块化拆分 src 结构,新增批量同步服务、查询解析器及前端分页/高级检索功能
- src/ 按 clients/services/api 分层,Config 提升至 crate 根
- 新增 batch_sync.rs(双源并行收割)、query_parser.rs(多平台检索式转换)
- build.rs 自动触发前端 npm install & build
- SearchPanel 支持分页/排序/每页条数/高级检索构建器,前端加入搜索缓存
- 新增 SyncPanel 替换 SettingsPanel;新增 live_search 集成测试
2026-06-09 10:29:24 +08:00

239 lines
12 KiB
Markdown
Raw Permalink 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.

# AstroResearch Architecture / 架构设计
AstroResearch 是一个集成了天文学文献检索、双通道下载、结构化解析、中英学术对比翻译以及引文星系图谱的天文科研辅助系统。
## 1. 整体架构 (Overall Architecture)
AstroResearch 采用 **C/S (Client-Server)** 架构,由前端 React 单页应用和后端 Axum HTTP 服务构成,核心流程及层级如下:
```mermaid
graph TD
subgraph Frontend ["React 前端 (Port 5173 / 8000)"]
UI[仪表盘 UI / ReaderPanel]
Canvas[引文 Canvas 拓扑图]
API_Client[Axum API 客户端]
end
subgraph Backend ["Rust Axum 后端 (Port 8000)"]
Router[Axum 路由与中间件]
Handlers[业务处理器 api/handlers.rs]
Sync[同步器 services/batch_sync.rs]
Parser[解析器 services/parser.rs]
Downloader[下载器 services/download.rs]
Translator[翻译器 services/translation.rs]
Qiniu[七牛云客户端 clients/qiniu.rs]
DB[("SQLite / astro_research.db")]
end
subgraph External [外部第三方服务]
ADS[NASA ADS API]
arXiv[arXiv Atom XML API]
MinerU[MinerU PDF 解析服务]
QiniuCDN[七牛云对象存储 CDN]
LLM[LLM API]
end
UI -->|用户操作| API_Client
API_Client -->|RESTful APIs| Router
Router --> Handlers
Handlers -->|查询/保存元数据| DB
Handlers -->|文献下载/解析/翻译| Handlers
Handlers -->|批量操作| Sync
Sync -->|元数据同步| ADS
Sync -->|元数据同步| arXiv
Sync -->|批量文件下载| Downloader
Sync -->|批量正文解析| Parser
Sync -->|写库记录| DB
Downloader -->|代理请求| ADS
Downloader -->|直连或 ar5iv| arXiv
Parser -->|图文降级解析| MinerU
Parser -->|托管插图| Qiniu
Qiniu -->|上传图片| QiniuCDN
Translator -->|天文术语翻译| LLM
Canvas -->|引文网络请求| Handlers
```
---
## 2. 核心工作流 (Core Workflows)
### 2.1 文献下载流程 (Download Flow)
本流程实现了文献的双通道流式下载,支持多级回退以及安全反爬防线绕过,其详细步骤与交互如下:
```mermaid
sequenceDiagram
participant U as 用户 (React 前端)
participant H as 处理器 (handlers.rs)
participant D as 下载器 (download.rs)
participant DB as 本地数据库 (SQLite)
U->>H: 1. 发起下载请求 (POST /api/download, 含 bibcode, force)
H->>DB: 2. 查询文献元数据 (获取 arxiv_id, doi 等)
alt force == true
H->>DB: 3. 重置本地下载路径字段为 NULL
end
H->>D: 4. 调度下载器执行物理拉取
alt 文献含有 arxiv_id (通道 AarXiv 直连优先)
D->>D: 5a. 去除版本号 (strip_arxiv_version, v2 -> 无版本)
D->>D: 5b. 随机延时 (maybe_delay: 500-2000ms) 并伪装 UA
D->>D: 5c. 下载 PDF 并校验文件头 (%PDF + %%EOF)
D->>D: 5d. 优先请求官方 HTML (arxiv.org/html/)
note over D: 若官方 HTML 返回 404/错误
D->>D: 5e. 自动降级回退请求 ar5iv HTML (ar5iv.labs.arxiv.org)
D->>D: 5f. 校验 HTML 内容 (detect_anti_bot 检测反爬)
else 无 arxiv_id (通道 BADS 路由回退)
D->>D: 6a. 跟踪 ADS Link Gateway 重定向路由
note over D: 若遇到 validate.perfdrive.com 拦截
D->>D: 6b. 自动解析并解码 ssc 参数提取直链
note over D: 若指向 IOPscience / Springer
D->>D: 6c. IOP 专属策略:预热主页写入 Cookie带 Referer 下载 PDF
D->>D: 6d. Springer 专属策略:使用 Chrome 头下载 HTML 页
note over D: 若网关均失败且存在 DOI
D->>D: 6e. CrossRef 兜底:请求 CrossRef API 获取 PDF URL 并直连下载
end
D-->>H: 7. 返回下载好的本地物理 PDF & HTML 路径
H->>DB: 8. 更新 pdf_path & html_path 记录
H-->>U: 9. 返回最新文献状态 (is_downloaded: true)
```
#### 详细下载说明:
1. **指令接收与校验**:后端 `download_paper` 接口在 `force` 参数为 `true` 时,会强行擦除数据库中已下载的文件路径,启动无缓存的物理文件重新拉取。
2. **下载反爬伪装**:下载器 `Downloader` 请求时采用动态生成的 Firefox/Chrome 轮换 User-Agent并在每次 HTTP 访问前强制加入随机休眠机制500ms - 2000ms模拟人类自然阅读行为。
3. **内容完整性校验**
- 对 PDF 严格校验前四个字节(必须是 `%PDF`)以及尾部检索(必须包含 `%%EOF` 终止符),排查登录墙、错误页伪装成 PDF 导致下载坏文件的问题。
- 对 HTML 文本利用 `detect_anti_bot` 流水线过滤 "cloudflare"、"captcha"、"robot check" 等拦截特征。
---
### 2.2 文献解析流程 (Parse Flow)
本流程负责将本地下载的 HTML 或 PDF 转换为高保真的 Markdown。其详细步骤与交互如下
```mermaid
sequenceDiagram
participant U as 用户 (React 前端)
participant H as 处理器 (handlers.rs)
participant P as 解析器 (parser.rs)
participant M as MinerU (PDF解析服务)
participant Q as 七牛云 (对象存储)
participant DB as 本地数据库 (SQLite)
U->>H: 1. 发起解析请求 (POST /api/parse, 含 bibcode, force)
H->>DB: 2. 查询文献物理路径 (pdf_path, html_path, markdown_path)
alt force == false 且本地已存在 Markdown 物理缓存
H->>H: 3. 读取本地 Markdown 物理文件
H-->>U: 4. 直接返回缓存 Markdown流程结束
end
H->>P: 5. 触发结构化文献解析
alt 本地存在 HTML 文件
P->>P: 6a. 剥离广告/导航栏与尾页页脚噪声
P->>P: 6b. 公式保护:利用占位符隔离 MathJax/LaTeX 公式段
P->>P: 6c. 标签规范:还原 LaTeXML 特定 span 为标准 table/tr/td修正上下标
P->>P: 6d. 插图处理:把相对图像路径替换为绝对 CDN 外链地址
P->>P: 6e. 转换 GFM Markdown 并恢复 LaTeX 公式
P->>P: 6f. 后处理:清除冗余的 margin 空白与前导缩进
else 仅有 PDF 文件 (PDF 降级解析)
P->>M: 7a. Multipart 格式上传 PDF 至 MinerU 服务
M-->>P: 7b. 返回大模型解析出的 Markdown 文本及插图包
loop 遍历每一个提取的插图
P->>Q: 7c. 上传插图文件并获取七牛云 CDN 域名外链
end
P->>P: 7d. 在 Markdown 中重写插图链接为七牛云 CDN 绝对路径
end
P-->>H: 8. 返回清洗转换出的标准英文 Markdown 文本
H->>P: 9. 写入本地物理缓存 Markdown/ 目录
H->>DB: 10. 更新数据库 markdown_path 记录
H-->>U: 11. 返回标准 Markdown 内容渲染展示
```
#### 详细解析说明:
1. **HTML 转换为 Markdown 保护公式**:由于 MathJax/LaTeX 在 Markdown 转换中极易被当成普通字符进行转义(例如 `_` 倾斜或 `\` 换行失效),解析器在 HTML 解析前,通过正则将 `$` / `$$``\(` / `\[` 中的内容全部替换为特定的 UUID 占位符,转换为标准 Markdown 之后,再反向替换恢复公式,确保 LaTeX 渲染无损。
2. **PDF 复杂排版降级**:遇到无法直接提取 HTML 的老文献时,调用 MinerU 进行布局分析与公式提取,配合七牛云对象存储实现插图的自动提取、自动图床托管与正文自动替换回写。
---
### 2.3 智能对照翻译流程 (Translation Flow)
本流程实现了基于天文学专属词汇表的 LLM 专业对比翻译,其详细步骤与交互如下:
```mermaid
sequenceDiagram
participant U as 用户 (React 前端)
participant H as 处理器 (handlers.rs)
participant T as 翻译器 (translation.rs)
participant D as 天文词典 (dictionary.rs)
participant L as 大模型 (LLM API)
participant DB as 本地数据库 (SQLite)
U->>H: 1. 请求文献对比翻译 (POST /api/translate, 含 bibcode, force)
H->>DB: 2. 查询文献路径及状态
alt force == false 且本地已存在翻译缓存文件
H->>H: 3. 读取本地 Translation/{bibcode}_zh.md 物理文件
H-->>U: 4. 直接返回缓存译文,流程结束
end
H->>H: 5. 读取对应的英文解析 Markdown 物理文件
H->>T: 6. 调度翻译器执行翻译工作流
T->>D: 7. 加载本地 dictionary.txt 并初始化 Trie 树结构
T->>D: 8. 执行英文 Markdown 文本分词匹配
D->>D: 9a. 进行前缀匹配检索
D->>D: 9b. 遵循“最长匹配优先”原则,过滤子词去重
D-->>T: 10. 返回该篇文献提取出的天文学名词对照 (Glossary)
loop 针对英文 Markdown 进行段落分块 (Token 长度控制)
T->>L: 11. 携带 Glossary + 英文原文段落发送 Prompt 请求
note over L: LLM 遵循系统 Prompt 约束:<br>1. 专业词汇严格对应 Glossary 译出<br>2. 严禁改变 LaTeX 公式及 Markdown 标签<br>3. 保持中英段落高度对齐
L-->>T: 12. 返回学术级双语对照翻译段落
end
T->>T: 13. 拼接所有段落,生成完整的对照 Markdown
T->>H: 14. 写入本地物理缓存 Translation/ 目录
H->>DB: 15. 更新数据库中的 translation_path 字段
H-->>U: 16. 返回翻译后 Markdown 渲染展示
```
#### 详细步骤说明:
1. **分级翻译缓存机制**
- 第一级缓存:若未开启 `force` 且本地物理磁盘已存在对应翻译文件,直接读取并返回,避免不必要的 LLM API 调用消耗。
- 第二级缓存:必须先完成英文 Markdown 的结构化解析,否则接口返回 `400` 错误,引导用户先进行正文解析。
2. **基于 Trie 树的天文学名词提取**
- 字典类 `Dictionary` 会加载包含数十万词条的本地天文词表 `dictionary.txt`
- 为防止短词覆盖长词(如 `Hertzsprung` 覆盖 `Hertzsprung-Russell diagram`),分词匹配采用 Trie 树的最长前缀匹配。若匹配到长词,自动忽略其包含的子词。
- 最终只保留文献中真实出现的名词并去重,以 JSON 的形式构建为专有提示词Glossary注入 LLM 提示中。
3. **LLM 强约束 Prompt 设计**
- 在向大模型发送请求时,利用 System Prompt 声明其“天文学专业翻译家”的角色。
- 强制约定格式要求:所有的 LaTeX 公式(`$` / `$$`必须原封不动保留Markdown 的标题(`#`)、列表(`-`)、加粗(`**`)等语法严禁破坏,使前端可以无缝解析双语结构并左右对齐渲染。
---
## 3. 核心模块说明
- **[src/api/handlers.rs](../src/api/handlers.rs)**:
- 处理 Axum API 路由分发与业务逻辑,包括统一检索、笔记管理、划词高亮及翻译。
- **[src/services/batch_sync.rs](../src/services/batch_sync.rs)**:
- 核心后台大批量文献元数据采集 (`MetaSync`) 与文献物理资源批量处理 (`AssetSync`) 的业务同步引擎。
- **[src/services/download.rs](../src/services/download.rs)**:
- 包含浏览器头伪装与请求延迟控制。
- 处理 ADS Link Gateway 路由重定向追踪与 `validate.perfdrive.com` 防护解码绕过。
- 实现官方 `arxiv.org/html` 优先及 `ar5iv` 兜底,自动去除版本号后缀。
- **[src/services/parser.rs](../src/services/parser.rs)**:
- 实现 HTML 语法树向 GFM Markdown 的逆向转换,使用占位符保护机制防止 MathJax/LaTeX 公式被误解析。
- 统一相对图表链接,并集成 MinerU PDF 解析。
- **[src/services/translation.rs](../src/services/translation.rs)**:
- 利用本地千万字级别的天文学双语词典对原文进行分词匹配,注入系统提示词让 LLM 实现学术级精细翻译。
- **[dashboard/src/components/CitationGalaxyCanvas.tsx](../dashboard/src/components/CitationGalaxyCanvas.tsx)**:
- 基于原生 HTML5 Canvas 开发的轻量级、高性能力导向图星系物理引擎,用于文献引文网络拓扑结构的可视化渲染。