Skip to content

Repository files navigation

figexplain

论文图表驱动的逻辑结构与要点总结工具。

从一篇论文的 PDF 出发:提取每张图(图像 + caption + 子图 panel)与正文引用句 → 用多模态 LLM 解读每个子图、归纳图表逻辑结构 → 与摘要/引言做对比、定位正文里的差异与遗漏 → 综合图表信息和正文总结关键要点 → 把结果写成一条 Zotero 笔记。

灵感来自 zotero-figure(PDF 图表提取思路)与一个本地 fig_explain 产物包(manifest schema + 自包含 HTML 模板),但本项目是独立的 Python 脚本工具,不依赖 Zotero 插件运行环境。

功能流程

PDF (Zotero 附件)
  │
  ├─ pdf_extract.py ── 每图图像 + caption + 子图分割 + 正文 Fig 引用句 + 摘要/引言
  │
  ├─ llm_explain.py ── 阶段1:每图 panel 中文注释 + 图核心结论 + 逻辑角色 (vision)
  │                   阶段2:图表逻辑结构 vs 摘要/引言 → 差异/遗漏 → 正文定位 → 要点总结
  │
  └─ note_writer.py ── 自包含 HTML 笔记 (图+panel表+结构+差异表+要点) → 写入 Zotero

依赖

pip install -r requirements.txt

需要:Python 3.10+,PyMuPDF、Pillow、requests。

用法

  1. 启动 Zotero(本地 HTTP 服务 127.0.0.1:23119 随之运行)。
  2. 在 Zotero 里点开目标文献所在的分类。
  3. 运行:
python run.py            # 列出当前分类的文献,输入序号选择
python run.py <itemKey>  # 直接按 Zotero item key 处理
  1. 首次运行会交互输入 OpenAI 兼容 base_url / api_key / 模型名 / Zotero storage 目录,存到 ~/.figexplain/config.json(之后每次运行可回车保留或覆盖)。模型需支持 vision(如 gpt-4oqwen-vl-max)。
  2. 跑完后,Zotero 当前分类下会出现一条顶层笔记(标题 图表解读:<原文献名>,标签 fig-explain / fig-explain-<key>),同时生成一份本地 HTML 副本 figexplain_<key>.html

网页模式(推荐入口)

工具主要作为网页应用使用。直接访问 http://127.0.0.1:8788/ 显示「无法访问」或空白,不是代码 bug,而是服务没有在运行——该地址由本地 API 进程提供,必须先把服务起起来。

最省事的方式:双击桌面入口 启动 figexplain 网页.bat(位于桌面,不在本仓库内)。它会:

  1. 检测 127.0.0.1:8788 是否已有服务在跑;有则直接打开浏览器,不重复启动。
  2. 没有则启动 API,轮询 /health 真正就绪后再自动打开浏览器。
  3. 关闭该窗口(或 Ctrl+C)即停止自己启动的服务,避免残留进程。

项目内也提供了等价脚本,可手动运行:

python start_web.py          # 默认 127.0.0.1:8788,就绪后自动开浏览器

网页界面只保留三块:模型配置PDF 拖拽/点击上传Zotero 导入;任务状态与结果三者共用同一个列表与轮询逻辑。拖入 PDF 后立即自动上传并轮询结果,完成后给出结果 HTML 链接;Zotero 文献点击「导入解析」后走同一套任务状态/结果展示。网页端 PDF 单文件上限 100MB。

网页内配置模型

页面顶部「模型配置」表单覆盖:

  • 视觉模型(逐图解读) explain_base_url / explain_model / explain_api_key
  • 综合模型(结构分析) synthesize_base_url / synthesize_model / synthesize_api_key
  • 默认/兜底(openai_*) 上面两组留空时回退到此

保存即写入 ~/.figexplain/config.jsonAPI Key 不会回显到浏览器:加载时只显示「已保存/未保存」,提交时空着的 Key 字段表示保留原值、不修改。也可在网页里直接改 Zotero storage 目录。

网页内从 Zotero 导入

「Zotero 导入」区在页面加载时自动探测连接状态,并列出 Zotero 当前选中分类下的 journalArticle 文献:

  1. 必须先在 Zotero 里点开目标分类(Zotero 本地 API 没有「读取当前选中条目」端点,只能读「当前选中分类」再列其条目)。
  2. Zotero 需运行且本地 HTTP 服务可用(默认 127.0.0.1:23119)。未运行时区域显示「未连接」并提示启动 Zotero 后点「刷新当前分类」。
  3. 点「刷新当前分类」重新读取当前分类文献;每行「导入解析」即对该文献发起解读任务,复用与 PDF 上传相同的任务状态轮询与结果展示,完成后给出可打开的结果 HTML 链接(/result/<job_id>)。
  4. 若自动列表不可用,可用底部的「手动输入 item key」兜底(如 4IX5ZWDT)。

同一 item_key 若已有任务在进行中(queued/running),再次提交会被服务端去重、复用同一任务,不会重复消耗 LLM。

底层接口(仍可用,供脚本/CLI 调用):

GET  /config                 返回非敏感配置 + key 是否已保存(不回显明文)
POST /config                 保存配置(空 key 字段保留原值)
POST /upload                 原始 PDF 请求体,X-Filename 传文件名
POST /explain               {"item_key": "4IX5ZWDT"} 启动 Zotero 文献解读(同 item_key 进行中去重)
GET  /jobs/<job_id>          查询任务状态(不含整段 HTML / 本机路径)
GET  /result/<job_id>        查看结果 HTML(Zotero 与 PDF 任务通用)
GET  /zotero/status          只读:Zotero 是否运行 + 当前分类名/id(未运行返回 503 + 中文错误)
GET  /zotero/articles        只读:当前分类下文献 key/title/authors/date(不含 API key/敏感路径)
GET  /health                 健康检查

默认只监听本机 127.0.0.1;若需让 Docker 或局域网客户端访问,可设置 FIGEXPLAIN_HOST=0.0.0.0 后再启动。PowerShell 写法:$env:FIGEXPLAIN_HOST="0.0.0.0"; python start_web.py

已知约束(Zotero 本地 API 实测)

  • 本地 HTTP API 不能创建"挂到父文献下的子笔记"(saveItems 忽略 parentItem),也没有"读取当前选中条目"的端点。因此笔记以顶层 note写入当前分类,内容里嵌原文献标题/作者/DOI/key 做关联。网页端「Zotero 导入」同样受此限制:点击导入后,结果会写成顶层笔记 + 一份 figexplain-out/figexplain_<key>.html 本地副本,但无法自动挂到对应文献下,需在 Zotero 里手动拖入。
  • 网页端 Zotero 列表只读「当前选中分类」,所以导入前请在 Zotero 中先点开目标分类;切换分类后点「刷新当前分类」重新读取。
  • DELETE/PATCH/PUT 一律返回 501,不可用。

项目结构

run.py                     # 入口
figexplain/
  config.py                # ~/.figexplain/config.json,交互式配置
  zotero_local.py          # Zotero 本地 HTTP API 客户端
  pdf_extract.py           # 图表 / caption / panel / refs / 摘要 / 引言 提取
  llm_explain.py           # 多模态 LLM 解释(每图 + 综合)
  note_writer.py           # 笔记 HTML 组装 + 写回
requirements.txt

隐私说明

  • API key 只存在本机 ~/.figexplain/config.json不进仓库(见 .gitignore)。
  • 不向任何第三方服务发送数据,除你配置的 LLM 端点(图图像 + 文本)和本机 Zotero 外。
  • 笔记本地副本 figexplain_*.html 已加入 .gitignore

安全提醒

  • 服务默认只监听 127.0.0.1(本机)。不要把 FIGEXPLAIN_HOST 设为 0.0.0.0 并暴露到公网——那样任何能访问该端口的人都能上传文件、读取你的配置与解读结果,且 API Key 仅以明文存于本机配置文件。
  • 桌面入口与 start_web.py 仅在本机使用;关闭启动窗口即停止服务。
  • 上传的 PDF 仅作为任务输入,结果生成后服务端会自动删除上传副本(结果 HTML 落在 figexplain-out/)。

License

MIT

About

Paper figure-driven logical structure and key-point summarizer (PDF -> multimodal LLM -> Zotero note)

Resources

Stars

0 stars

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages