AstroResearch/docs/architecture.md
Asfmq cd6af4f995 feat: 重构 PDF/文献检索同步机制、升级引力图交互与控制台 UI 样式
- [后端/PDF解析] 重构 MinerU PDF 解析流程:引入预签名两阶段直传机制,解决大文件 API 传输限制问题;支持轮询机制与本地 images 备用目录存储。
- [后端/同步与下载] 新增经典 ADS SCAN 扫描件 PDF 和 ADS_PDF 直接通道的下载逻辑;新增常用同步检索配置的持久化存储与去重管理 API。
- [后端/日志] 重构日志系统,支持控制台 pretty 输出与每日滚动文件日志(使用上海 +08:00 时区),引入 HTTP 路由请求链路追踪。
- [前端/引力图] 升级引用星系图 canvas 交互:支持平移拖拽与滚轮缩放,添加引力圈轨道装饰及未导入文献的半透明视觉区分。
- [前端/控制台] 统一重构为扁平高对比度浅色纯中文控制台样式;重新设计文献详情弹窗与状态进度条。
- [数据库] 新增 papers 表的 doctype 字段及 sync_queries 检索配置表。
2026-06-10 17:29:07 +08:00

13 KiB
Raw Blame History

AstroResearch Architecture / 架构设计

AstroResearch 是一个集成了天文学文献检索、双通道下载、结构化解析、中英学术对比翻译以及引文星系图谱的天文科研辅助系统。

1. 整体架构 (Overall Architecture)

AstroResearch 采用 C/S (Client-Server) 架构,由前端 React 单页应用和后端 Axum HTTP 服务构成,核心流程及层级如下:

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]
        Logging[日志记录器 services/logging.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)

本流程实现了文献的双通道流式下载,支持多级回退以及安全反爬防线绕过,其详细步骤与交互如下:

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。其详细步骤与交互如下

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. 获取批量预签名上传 URL (POST /file-urls/batch/)
        M-->>P: 7b. 返回预签名上传 URL 与 Batch ID
        P->>M: 7c. 上传 PDF 二进制字节流 (PUT 至预签名 URL)
        loop 轮询任务状态 (每 10s 一次,最多 45 次)
            P->>M: 7d. 查询提取进度与结果 (GET /extract-results/batch/{id})
            M-->>P: 7e. 返回处理状态 ("done"/"error"等)
        end
        P->>P: 7f. 下载解析结果的 ZIP 压缩包并解压提取
        loop 遍历每一个提取的插图
            P->>Q: 7g. 上传插图文件并获取七牛云 CDN 域名外链
        end
        P->>P: 7h. 在 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 进行布局分析与公式提取。为避免在上传大型 PDF 时触发 API 网关的 413 Payload Too Large 错误,系统弃用了传统的 Multipart 表单直接 POST 请求,转而采用两阶段直传机制:先请求预签名上传 URL随后使用 HTTP PUT 直接流式传输二进制数据至存储服务,最后通过后台任务轮询 extract-results 获取转换完毕的 ZIP 并自动托管插图至七牛云。

2.3 智能对照翻译流程 (Translation Flow)

本流程实现了基于天文学专属词汇表的 LLM 专业对比翻译,其详细步骤与交互如下:

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:
    • 处理 Axum API 路由分发与业务逻辑,包括统一检索、笔记管理、划词高亮及翻译。
  • src/services/batch_sync.rs:
    • 核心后台大批量文献元数据采集 (MetaSync) 与文献物理资源批量处理 (AssetSync) 的业务同步引擎。
  • src/services/download.rs:
    • 包含浏览器头伪装与请求延迟控制。
    • 处理 ADS Link Gateway 路由重定向追踪与 validate.perfdrive.com 防护解码绕过。
    • 实现官方 arxiv.org/html 优先及 ar5iv 兜底,自动去除版本号后缀。
  • src/services/parser.rs:
    • 实现 HTML 语法树向 GFM Markdown 的逆向转换,使用占位符保护机制防止 MathJax/LaTeX 公式被误解析。
    • 统一相对图表链接,并集成 MinerU PDF 解析。
  • src/services/translation.rs:
    • 利用本地千万字级别的天文学双语词典对原文进行分词匹配,注入系统提示词让 LLM 实现学术级精细翻译。
  • src/services/logging.rs:
    • 全局日志记录系统,基于 tracing-subscriber 实现了控制台美化日志输出与基于时间的每日滚动日志文件写出,使用上海时区 (+08:00) 格式化时间。
  • dashboard/src/components/CitationGalaxyCanvas.tsx:
    • 基于原生 HTML5 Canvas 开发的轻量级、高性能力导向图星系物理引擎,用于文献引文网络拓扑结构的可视化渲染。