ThesisAgents 使用手册

以关键词驱动的论文搜索助手。从 arXiv(以及可插拔的其他来源)抓取结果, 规范化为统一的 record,并把去重、排序后的结果集导出为 PowerPoint 幻灯片、 Markdown 摘要、BibTeX 文件、与 JSON 原始数据 —— 一次 CLI 调用或一次 MCP 工具调用即可完成。


给驱动本项目的 AI agent 看

如果你是 LLM(Claude Code、Cursor、Aider、Codex CLI …)正在读这份 指南想搞清楚要做什么 —— 从这节开始。 同一套规则也钉在 repo 根目录 的 AGENTS.md(跨 agent 镜像)与 CLAUDE.md(权威来源), 做非小改动前请先读。

交付物是每篇一份论文答辩级的富版 PPT,不是 CLI 默认出的只有摘要的 轻量版。 轻量 emit 是中间产物 —— 你的工作就是把它升级。

决策树

  1. 环境有 ANTHROPIC_API_KEY 吗? → 直接跑 CLI,它会自动 enrich。

  2. 没 key,但你(LLM)正在驱动 → 你自己手写 rich summary。每篇 PDF 自己读,手写 PaperSummary 含 rich-tier 字段,放 scripts/regen_<query>.py,跑它。不要叫用户去设 API key —— 你就是那个会写 summary 的 LLM。

  3. 没 LLM(CI / cron / 无人值守)→ 轻量版可以接受。

MCP 6 步流程

1. (可选) list_sources()                              # 看哪些 plugin 已启用
2. search(keywords, sources, top_tier_only=true, ...)
3. (可选) download_pdfs(papers, out_dir="./exports/...")
4. fetch_pdf_text(pdf_url=paper.pdf_url)              # 每篇都要
5. (你逐篇读 PDF,自己产 structured summary dict)
6. export(papers=[{..., "summary": {...}}], language="zh-cn", ...)

共 12 个 MCP 工具,完整参考见 MCP server

必做:交付前验证 URL / DOI

出版商的 URL 路径 不能猜。AAAI 用数字 ID(v40i5.37389), IEEE 用 opaque arnumber,ACM 用 opaque DOI。手写 Paper 时, url / doi / arxiv_id 必须逐字从同一次搜索产生的 xlsx 抄 —— 不能凭印象,也不能从标题自己拼。

xlsx 写在 exports/<run>/<slug>-<timestamp>.xlsx,第 7 列是 DOI、 第 8 列是 URL。Regen 跑完做这个 audit:

from openpyxl import load_workbook
from scripts.regen_<run> import ALL_PAPERS
real = {sh.cell(row=r, column=2).value: sh.cell(row=r, column=8).value
        for sh in [load_workbook("exports/<run>/<slug>-<ts>.xlsx")["Papers"]]
        for r in range(2, sh.max_row + 1)}
for p in ALL_PAPERS:
    actual = next((u for t, u in real.items() if p.title[:30] in (t or "")), None)
    if actual and not (p.url == actual
                       or p.url.split("v")[0] == actual.split("v")[0]):
        print(f"! {p.bibtex_key()} authored {p.url} vs real {actual}")

禁忌

  • 不要告诉用户「设 ANTHROPIC_API_KEY 才能拿到富版」—— 你就是那个 LLM。

  • 不要把轻量 .pptx 当交付物。

  • 不要看到 download_pdfs 报告「N 份 PDF 已存」就停。

  • 不要编造论文里没有的数字、RQ、贡献、限制。

  • 不要编造 URL / DOI / arXiv ID。

  • 不要把不相关下载留在 run 目录里。关键词搜索会带到无关论文 (例如「Claude code」抓到 Viterbi 解码器论文)。把无关论文的 pdfs/<key>.pdf 与轻量 <key>.pptx 删掉,aggregate xlsx / bib 保留作为「诚实记录」。完整流程见 CLAUDE.md 的「Pruning irrelevant downloads」。

  • 不要在 commit message、PR description、代码注释或文档提到 「Claude」、「Claude Code」、「AI-generated」、「GPT」、「Copilot」 或任何 AI 工具 / 模型名称。

示例:scripts/regen_llm_security_batch.py(en)与 scripts/regen_llm_security_batch_zh_tw.py(zh-tw)里有 8 篇照 这套流程手写的 rich summary,当 template 用。


安装

ThesisAgents 锁定 Python 3.12+(以 3.14 开发),支持 Windows、 macOS、Linux。建议使用项目内的 virtualenv:

git clone <repo-url>
cd ThesisAgents
python -m venv .venv
.venv\Scripts\Activate.ps1            # Windows PowerShell
# source .venv/bin/activate           # Linux / macOS

pip install -e .[dev]

devextra 会拉进 pytestpytest-asynciopytest-httpxruffbanditmcpSDK。如果只需要 MCP server,可以装更轻的 [mcp]

可选依赖组

Extra

解锁什么

[mcp]

只装 mcpSDK。用于 production 安装 —— 想要 thesisagents-mcp但不想要测试工具链时。

[intelligence]

pypdf+ anthropic。Python --enrich路径用 (抓 PDF + 打 Anthropic API)。MCP 上的 LLM-as-agent 流程 不需要这个 —— LLM 自己就是 agent。

[web]

fastapi+ uvicorn+ streamlit—— 预留给后续的网页 UI。 CLI 与 MCP server 不需要这个。

[dev]

完整开发工具链: pytest、asyncio + httpx 测试插件、ruff、bandit、 MCP SDK 与 intelligence 依赖(让所有测试能跑)。


CLI

python -m thesisagents(也安装为 thesisagents)是入口程序。 有两个互斥的模式:

搜索模式

# 默认 25 条结果,默认导出(pptx、xlsx、bib)
thesisagents --query "diffusion models" --source arxiv

# 10 条结果,全部导出格式,自定义目录
thesisagents --query "transformer attention" --source arxiv \
             --max 10 --export pptx,xlsx,md,bib,json,ris,csv,csl \
             --out ./exports/

# 限制在近年论文
thesisagents --query "graph neural networks drug discovery" \
             --year-from 2022 --year-to 2025 \
             --max 15 --out ./exports/

单篇论文模式

# arXiv ID —— 单篇默认只出 pptx + bib
thesisagents --paper 1706.03762 --out ./exports/

# arXiv URL
thesisagents --paper "https://arxiv.org/abs/1706.03762" \
             --filename-stem attention --out ./exports/

# DOI(通过 Semantic Scholar resolve)
thesisagents --paper "10.1145/3411764.3445005" --out ./exports/

# PubMed PMID / URL
thesisagents --paper "https://pubmed.ncbi.nlm.nih.gov/34567890/" \
             --out ./exports/

# IEEE document URL(需 opt-in env var)
THESISAGENTS_DISABLE_IEEE_SCRAPING=1 \
thesisagents --paper "https://ieeexplore.ieee.org/document/10965643" \
             --out ./exports/

可用的 source plugin

不传 --source 时的默认组合是「所有不需要 API key 的 plugin」: arxivsemantic_scholaropenalexpubmedacmdblpcrossrefopenaire。设下面三个 env var 之一,对应 plugin 也会加入:

Plugin

Env var

备注

ieee

THESISAGENTS_IEEE_API_KEY(建议)**或**THESISAGENTS_DISABLE_IEEE_SCRAPING=1

官方 Xplore API 在订阅范围内会带 pdf_url;没 key 时可用 fallback 爬取路径。

springer

THESISAGENTS_SPRINGER_API_KEY

免费 key 申请 https://dev.springernature.com/。 涵盖 Nature、Scientific Reports、LNCS 等 Springer 全系。 没 key 时 plugin 会在构造时抛 ConfigError,被 pipeline 静默跳过。

scholar

THESISAGENTS_DISABLE_SCHOLAR_SCRAPING=1

Google Scholar ToS 禁止爬取,默认关闭。

搜索流水线默认套用「顶级期刊白名单」(旗舰级 CS 会议 + Nature / Science / PNAS / CACM / LNCS);传 --all-venues 可关闭。

本地化 deck 与 LLM enrichment

# 把幻灯片模板字符串改成繁体中文
thesisagents --paper 1706.03762 --lang zh-tw --out ./exports/

# Python pipeline 走 enrichment(PDF + Anthropic API → thesis-style)
export ANTHROPIC_API_KEY=sk-ant-...
thesisagents --paper "https://arxiv.org/abs/1706.03762" \
             --enrich --lang zh-tw --out ./exports/

完整参数表: CLI reference


输出文件

每种导出会在 --out写一个文件。默认文件名为 {关键词前 32 字}-{YYYYMMDD-HHMMSS}.{扩展名};用 --filename-stem固定 stem。默认值依模式不同:

  • --querypptx + xlsx + bib

  • --paperpptx + bib(单篇出 Excel 是浪费)

exports/
├── attention.pptx     # 16:9 宽屏幻灯片(布局见下)
├── attention.xlsx     # Papers 工作表 + Query 出处工作表
├── attention.bib      # 不会撞 key,LaTeX 特殊字符已转义
├── attention.md       # 完整来源 / 标题 / 摘要列表(opt-in)
└── attention.json     # 原始 payload(opt-in)

.xlsx 的 Papers 工作表有两个外观相近但含义不同的相邻列:

  • Source(第 5 列)—— 真实刊登出处,例如IEEE AccessNDSS 2026Nature Machine Intelligence

  • Indexed via(第 6 列)—— 是哪个 fetcher 抓到这条 metadata, 例如openalexcrossrefarxiv。当同一篇论文可以 从多条路径抓到时,这个分列很重要 —— 例如一篇 Nature 论文经 OpenAlex 索引时,Source 显示Nature,Indexed via 显示openalex

PPTX 布局

16:9 宽屏、带页码。三种 rendering tier 依数据多寡自动挑:

  • 轻量—— 只有 paper.abstract。封面 + agenda + 每篇 (section divider + overview + 句子切片的 Background / Approach / Findings)+ references。

  • 扁平结构化—— Paper.summary的扁平 tier 有值 (motivation / contributions / method / results / limitations / takeaways)。一张幻灯片 对应一个非空 section。

  • thesis-style 答辩级—— Paper.summary有 rich-tier 字段 (pain_points四宫格、研究问题 callout、contributions_detailed + headline_metrics、技术比较表、文献定位表、系统总览、 方法细节、评估方法、研究问题、每个 RQ 结果表、贡献总结、 核心观察、限制与未来工作、Q&A、参考文献)。每篇 20+ 张幻灯片。

所有模板字符串(议程 / 参考文献 / 第 N 篇 / 页脚)都走 thesisagents.exporters.i18n,跟 --lang联动。支持的语言: en(默认)、zh-twzh-cnjaesfrdekoptruitvihiid,共 14 种。传其他值会静默 fallback 到 en

每张幻灯片上的每个文本框都带有语义 name(titlemetabodysubheadfooterpage_numberkpirq_box),编辑工具可以靠 name 定位 shape,不必依赖视觉位置。 详见 PPTX editing & layout


MCP server

ThesisAgents 附带一个暴露 12 个工具 的 MCP server —— 来源发现 (list_sources)、搜索、单篇抓取、单个 PDF 正文提取 (fetch_pdf_text)、批量 PDF 下载(download_pdfs)、导出, 以及 5 个 PPTX 编辑操作。任何支持 MCP 的 LLM client(Claude Code、 Claude Desktop、Cursor …)都能驱动整套流程。

配置 MCP client(以 Claude Code 为例):

claude mcp add thesisagents -- ".venv\Scripts\python.exe" -m thesisagents.mcp

或直接编辑 settings 文件:

{
  "mcpServers": {
    "thesisagents": {
      "command": ".venv\\Scripts\\python.exe",
      "args": ["-m", "thesisagents.mcp"]
    }
  }
}

工具速查:

Tool

用途

list_sources

列出所有 plugin + 报告当前 process 下哪些已启用。search 前先调一次,agent 才知道要传什么 sources

search

关键词 → 论文列表(shape 同 Paper.to_dict())。可带 top_tier_only(默认 True)与 min_citations; 省略 sources 时默认扫所有不需要 API key 的来源。

fetch_paper

arXiv / DOI / PMID / IEEE 标识符 → 单篇论文。

fetch_pdf_text

抓单个 PDF 并返回提取的正文。MCP 路径下「让我读过论文」的入口。

download_pdfs

把一组论文的 PDF 批量下载到 {out_dir}/pdfs/。返回以 BibTeX key 为索引的逐篇结果。

export

论文列表 + 格式 → 写出 .pptx/.xlsx/.md/.bib/.json/.ris/.csv/.csl.json。每篇 论文可附 summary字段走 thesis-style;支持 language走 i18n,以及 max_slides_per_paper(默认 25;传 0代表不限)。

pptx_inspect

读已有幻灯片文件的 slide / shape 结构。

pptx_update_slide

替换 title/ body/ meta(通过 shape name)或 任意 shape(通过 index)。

pptx_delete_slide

删除一张 slide 及其 part relationship。

pptx_reorder_slides

通过 sldIdLst重排幻灯片。

pptx_add_slide

在末尾追加或在指定 position 插入一张新的 title / body / meta slide。

LLM-as-agent enrichment 流程(不需要 Anthropic API key):

  1. (可选)list_sources()看当前 process 下哪些 plugin 已启用。

  2. search(keywords, sources, top_tier_only, ...)多篇,或 fetch_paper(identifier)抓单篇。

  3. (可选)download_pdfs(papers, out_dir)把每篇 PDF 批量存到 本地。

  4. fetch_pdf_text(paper.pdf_url)逐篇拿正文。

  5. LLM 在自己 context 里读正文,产 structured summarydict。

  6. export(papers=[{..., "summary": {...}}], language="zh-tw", ...)

完整参考: MCP server


编辑生成好的幻灯片

幻灯片生成后,``pptx_*``工具(或 thesisagents.exporters.pptx_edit Python 模块)让你在不重跑搜索的情况下继续对它做迭代:

from thesisagents.exporters import pptx_edit

pptx_edit.update_slide(
    "exports/attention.pptx", slide_index=1,
    title="Attention Is All You Need (Vaswani et al., 2017)",
    body="The Transformer dispenses with recurrence and convolutions...",
)

pptx_edit.add_slide(
    "exports/attention.pptx",
    title="Conclusion",
    body="We covered transformers and follow-on work.",
)

pptx_edit.reorder_slides("exports/attention.pptx", [0, 2, 1])

每个 helper 默认原地存盘;传 out_path=...可以另存,原文件不动。 完整参考: PPTX editing & layout


架构

ThesisAgents/
├── thesisagents/                 # 主包
│   ├── core/                     # Paper / PaperSummary / RqResult / dedup / ranking / pipeline
│   ├── fetchers/                 # HTTPS-only http client、token bucket、Fetcher base
│   ├── exporters/                # pptx(thesis-style + lightweight)、xlsx、
│   │                             #   bibtex、markdown、json + pptx_edit + i18n
│   ├── intelligence/             # PDF 抓取 + Anthropic 摘要器([intelligence] extra)
│   ├── mcp/                      # 注册 12 个工具的 FastMCP server
│   ├── utils/                    # logging、path safety
│   ├── cli.py                    # argparse CLI
│   └── __main__.py               # `python -m thesisagents`
├── sources/                      # 各来源 plugin(arxiv、semantic_scholar、
│                                 #   openalex、pubmed、acm、ieee、scholar、
│                                 #   dblp、crossref、openaire、springer)
├── tests/                        # pytest suite + 录制 fixture,不打活 HTTP
├── docs/                         # 这份 Sphinx 文档(en + zh-tw + zh-cn)
├── scripts/                      # 一次性 regen / fixture-record 脚本
└── pyproject.toml                # metadata + ruff / bandit + optional extras

核心 vs 来源插件

thesisagents/(核心)与 sources/<name>/(插件)的分界线是 依赖负担与失败隔离,不是”跟来源有关的东西全丢插件”:

  • 核心跑在默认依赖集 (httpxpydanticdefusedxmlpython-pptxopenpyxlbibtexparserbeautifulsoup4lxmlmarkdown-it-py),覆盖所有用户都应默认可用的流程。

  • 插件是任何需要重 / 可选 runtime 依赖(selenium处理 Scholar 的 JS 页面、IEEE / ACM 厂商 SDK …)或独立发版节奏的东西。

两条 enrichment 路径

  • LLM-as-agent(不需要 API key)—— 由 MCP-aware 的 LLM 驱动。 fetch_paper+ fetch_pdf_text给它 metadata + 正文;LLM 在自己 context 里产 structured summary;``export``写出文件。

  • Python pipeline(``–enrich``) —— 给没有 LLM 在外面的自动化用。 需要 ANTHROPIC_API_KEY[intelligence]extra,默认模型 claude-opus-4-7,可用 --llm-modelTHESISAGENTS_LLM_MODEL覆盖。

网络安全

所有对外的 HTTP 都走 thesisagents.fetchers.http.get_client(source), 返回一个用 HTTPS-only transport 包起来的 per-source httpx.AsyncClient。 纯 HTTP 请求一律被拒(包括 redirect 后变 HTTP)。每个来源声明自己的 RateLimit策略,由 token bucket 强制执行;arXiv 默认为 每 3 秒 1 次、抖动 0.5s,对应它的官方软限制。


开发流程

Definition of Done

每次变更都要过三道闸才能 commit(见 CLAUDE.md):

.venv\Scripts\python.exe -m pytest tests/
.venv\Scripts\python.exe -m ruff check .
.venv\Scripts\python.exe -m bandit -c pyproject.toml -r thesisagents/ sources/

bandit 的 -c标志是 必需的—— 没它 bandit 不会读项目 skip 配置, 跑出来会充满假警报。

测试

测试结构镜像 production: 每个 production 模块 thesisagents/<area>/<feature>.py都有一个对应的 tests/test_<feature>.py。来源插件测试在 tests/sources/<name>/

测试是 hermetic—— 每个 fetcher 测试都通过 monkeypatched HTTP transport 载入录制好的 fixture。录新的 fixture 是独立的手动步骤 (scripts/record_fixture.py),录完的文件要 commit 进去。

跑整个 suite:

.venv\Scripts\python.exe -m pytest tests/

目前 89 个测试,约 2 秒跑完。

Lint + 安全

ruff 会自动抓掉大部分风格问题。项目执行 SonarQube / Codacy / pylint 的 默认规则(复杂度 ≤ 15、函数长度 ≤ 75 行、文件 ≤ 1000 行、不要 magic number、不要 bare except、不要 mutable default arg)。bandit 扫 安全相关 pattern(pickle.load、没有 SafeLoader 的 yaml.load、 拿 MD5 / SHA-1 做安全用途、shell=True、纯 HTTP 对外)。


故障排查

error: refusing non-HTTPS request

某个来源插件或测试把 HTTP client 指到 http://URL。修 URL —— 项目不会绕过 HTTPS-only egress。

error: could not classify identifier

--paper给的值没被识别为 arXiv ID、arXiv URL 或 DOI。可接受的形式:

  • 2401.087412401.08741v2arXiv:2401.08741

  • https://arxiv.org/abs/2401.08741(带不带 v<N>/ .pdf都行)

  • cs.LG/0001001(旧 arXiv)

  • 10.1234/exampledoi:10.1234/examplehttps://doi.org/10.1234/example

error: no source plugin available yet for doi identifiers

DOI 能被解析但 resolver 还没接上。等 Semantic Scholar / Crossref 插件,或先用该论文的 arXiv 镜像 ID。

arXiv rate-limit hits

内置 token bucket 已限制在 1/3s。如果还是被 429,可能是同时跑了多个 ThesisAgents process 对同一个 arXiv endpoint —— 统一走一个 process, 或调低 --max


授权与致谢

主程序采 MIT-style授权;详见 LICENSE

arXiv API 的使用受 arXiv 的 API 服务条款 约束。内置 fetcher 已通过 token bucket 强制每 3 秒 1 次的软限制 —— 新增 endpoint 时不要把这个 限速拿掉。