跳转至

学术搜索 API 一览

Agentero Host 端(src-tauri/src/features/)在论文识别、入库、引用补全、推荐等流程中,会调用若干外部学术服务。本文档列出所有当前在用的学术搜索/元数据 API,说明其用途、调用入口、请求形态、fallback 链路与并发控制。

范围限定在学术元数据与论文发现相关的外部 HTTP API。翻译 API(Google/Bing/DeepL/OpenAI 等)、版面分析 ONNX、本地 Agent/ACP、PostHog 遥测不在本文讨论范围内。

路径简写:scholar_api/… 与 features/paper/import/ 的映射 / resolver / 路由(scholar_api::identifiers、api_mapper.rs、search_router.rs、search.rs、download.rs、sources/)已随 crate 拆分迁到 crates/agentero-core/src/features/paper/…;import/recognize/(PDF 识别)与 import/commands.rs 仍在 src-tauri。其余 features/… 均指 src-tauri/src/features/…。

1. API 总览

服务 主要端点 用途 核心调用模块
Semantic Scholar Graph API GET /graph/v1/paper/search 标题/关键词搜索 features/paper/import/search_router.rs
Semantic Scholar Graph API GET /graph/v1/paper/{id}/references 在线参考文献补全 features/refs/online.rs
Semantic Scholar Graph API GET /graph/v1/paper/ARXIV:{id} / DOI:{doi} venue 回填(publicationVenue.name) features/paper/scholar_api/sources/semantic_scholar.rs(fetch_venue_by_*),调用方 features/paper/import/commands.rs
Semantic Scholar Graph API GET /graph/v1/paper/{id}/citations "谁引用了我" 候选发现 features/refs/citing.rs
arXiv Atom API GET https://export.arxiv.org/api/query 按 ID 取元数据 / 按标题搜索 features/paper/import/mod.rs, features/paper/import/search_router.rs
arXiv 二进制端点 https://arxiv.org/pdf/{id} / https://arxiv.org/e-print/{id} / https://arxiv.org/src/{id} PDF / TeX 源码下载 features/paper/import/download.rs
Crossref REST API GET https://api.crossref.org/works/{doi} DOI → 元数据 / 参考文献 features/paper/import/recognize/pdf_recognize.rs, features/paper/analyze/refs/online.rs, features/paper/catalog/commands.rs
OpenAlex REST API GET https://api.openalex.org/works 标题搜索兜底(含 cited_by_count) features/paper/scholar_api/search.rs(SourceScope::All 兜底源)
Unpaywall GET https://api.unpaywall.org/v2/{doi} DOI → 开放获取 PDF features/paper/import/download.rs
PubMed / NCBI E-utilities GET https://eutils.ncbi.nlm.nih.gov/entrez/eutils/esearch.fcgi / efetch.fcgi 标题/PMID → 医学/生命科学元数据 features/paper/scholar_api/sources/pubmed.rs
alphaXiv GET https://api.alphaxiv.org/papers/v3/{id}/preview、GET /v1/search/paper?q= arXiv 元数据/标题搜索的末位备份源(未文档化匿名 JSON API) features/paper/scholar_api/sources/alphaxiv.rs
bioRxiv GET https://api.biorxiv.org/details/biorxiv/{doi} DOI → 生命科学预印本元数据 features/paper/scholar_api/sources/biorxiv.rs
medRxiv GET https://api.biorxiv.org/details/medrxiv/{doi} DOI → 医学预印本元数据 features/paper/scholar_api/sources/biorxiv.rs
Zotero Recognizer POST https://services.zotero.org/recognizer/recognize PDF 首页文字几何识别 features/paper/import/recognize/pdf_recognize.rs
Translator Runtime POST {base}/web, POST {base}/search, POST {base}/import 通用 URL/标识符/题录解析 features/import/mod.rs
Cool Papers (papers.cool) GET https://papers.cool/{branch}/search?query=..., GET https://papers.cool/{branch}/kimi?paper={id} Kimi 论文解析 / 广场导入 features/coolpapers/
arXiv RSS GET https://rss.arxiv.org/rss/{category} 推荐与订阅流 features/recommend/mod.rs, features/feeds/

2. 调用链路详解

2.1 论文识别与魔棒入库

入口:features/import/commands.rs::paper_resolve_identifier、features/import/mod.rs::import_by_identifier_with_progress。

当前主路径按以下顺序尝试:

  1. 标题/关键词搜索(features/paper/import/search_router.rs::search_papers)
  2. Semantic Scholar GET /graph/v1/paper/search?query=...&fields=title,authors,year,venue,publicationVenue,journal,externalIds,citationCount,url 与 arXiv Atom GET export.arxiv.org/api/query?search_query=ti:"..." 并行发起。S2 在 5s 预算(S2_SEARCH_BUDGET)内返回非空则优先(venue 取 publicationVenue.name(跳过 type=repository),其次 journal.name,再次 venue),否则取已在途的 arXiv 结果;最坏耗时 ≈ max(预算, 单请求 20s 超时)。
  3. 仅保留带 DOI 或 arXiv id 的候选;返回结果会按精确标题匹配重新排序。
  4. resolve_search_queries 接收前端 task_id:关闭搜索卡片取消任务后,剩余查询直接跳过。
  5. Translator Runtime(features/import/mod.rs::resolve_metadata)
  6. 若用户输入被识别为 arXiv id / DOI / URL,会构造 {base}/web 或 {base}/search 请求。
  7. arXiv 的各类输入(2508.05004、arXiv:2508.05004v2、https://arxiv.org/pdf/...、https://arxiv.org/html/...)都会被规范化为 https://arxiv.org/abs/{id} 再走 /web。
  8. Translator 失败时按标识符类型走直连兜底链(scholar_api::identifiers::fallback,见下)。
  9. 直连兜底链(features/paper/scholar_api/identifiers/fallback.rs)
  10. arXiv → ARXIV_CHAIN = arXiv Atom → S2 ARXIV:{id} → alphaXiv /papers/v3/{id}/preview。
  11. DOI → DOI_CHAIN = Crossref works/{doi} → S2 DOI:{doi} → OpenAlex。
  12. PMID → PMID_CHAIN = PubMed efetch。
  13. 执行模型是错峰投机并发 + 优先级顺序接受(hedged chain):链内所有源同时 spawn,第 i 个源先睡 i×600ms 再请求,随后严格按优先级顺序 await——首个非空 Ok 胜出并 abort 其余在飞请求。健康主源在错峰窗口内完成时请求数与单源直连相同;主源 429/慢时失败前缀时延取 max 而非 sum。整趟全失败且含 429 → 2s 冷却后重试一趟,仍失败按 rate_limited 上报(#524:不再误报「无结果」)。
  14. arXiv Atom 解析 <arxiv:journal_ref> 作为 publication/venue(链内其余源不提供 venue 回填语义,透明受益于既有 merge 偏好)。

被引数(citation_count):Crossref 解析 is-referenced-by-count、OpenAlex 解析 cited_by_count、Semantic Scholar 解析 citationCount,三者 capabilities() 均声明 PROVIDE_CITATION_COUNT;Crossref / OpenAlex 的 title search 还必须把该字段列进 select 白名单,否则 API 根本不返回它。api_paper_to_meta 把值带进 PaperRecord,merge_api_papers 合并两个源时取较大值(各自索引的引用文献子集不同)。arXiv Atom 与 Translator 不产出被引数。注意:入库以 Translator 为主路径,map_zotero_item_to_record 不带被引数,因此常规导入写入的仍是 NULL;只有 Translator 失败后降级到 Crossref 直连的 DOI 导入才会落进真实值。完整缺口见 catalog.md。

2.2 PDF 元数据识别

入口:features/paper/import/recognize/pdf_recognize.rs::recognize_and_resolve。

流程:

  1. 本地 liteparse 探测 PDF 前若干页文字几何。
  2. 将文字几何按 Zotero Worker 形状提交到 https://services.zotero.org/recognizer/recognize,获取可能的 DOI / arXiv / title。
  3. 若识别出 DOI → import/mod.rs::resolve_metadata → Translator → DOI 兜底链(Crossref→S2→OpenAlex)。
  4. 若识别出 arXiv → arXiv 兜底链(Atom→S2→alphaXiv);meta_source 如实反映实际应答源。
  5. 仅有 title/authors 时 → 生成本地 PDF 占位元数据(meta_from_recognize)。

2.3 参考文献在线补全

入口:features/refs/online.rs::fetch_references。

  • 优先 Semantic Scholar:GET /graph/v1/paper/{id}/references?fields=title,authors,year,venue,externalIds,url&limit=1000,{id} 为 arXiv:... 或 DOI:...。
  • 失败或无结果且存在 DOI 时,fallback Crossref:GET api.crossref.org/works/{doi}?mailto=agentero@users.noreply.github.com,取 message.reference[]。

2.4 反向引用发现("谁引用了我")

入口:features/refs/citing.rs。

  • 仅使用 Semantic Scholar:GET /graph/v1/paper/{id}/citations?fields=...&offset={offset}&limit={limit}。
  • 因为 OpenAlex 的 arXiv 预印件引用边稀疏,所以未采用。
  • 内部有 L0/L1/L2 三层过滤与 SPECTER2 相似度排序,分页上限受 S2 offset + limit < 10000 限制。

2.5 Venue / Publication 回填

入口:features/import/commands.rs::paper_backfill_publication。

用于 Library 的 publication 列批量补全。实测各源准确度:

源 适合 缺陷
arXiv <arxiv:journal_ref> 作者已回填的发表信息,最完整(含年/卷) 大量已发表论文仍为空(如 Attention Is All You Need)
S2 publicationVenue.name 会议 + 期刊的规范化全名 免费端点限流;venue 字段常为空或缩写
Crossref container-title 期刊(Nature 等)准确 ACL/NAACL 等会议名会被截断(Proceedings of the 2019 Conference of the North)
OpenAlex / DBLP — OpenAlex 对 CS arXiv 常无 venue;DBLP 只有缩写(NIPS / NAACL-HLT)

因此顺序是:

  1. arXiv id → arXiv Atom export.arxiv.org/api/query?id_list={id},取 <arxiv:journal_ref>;缺失则 GET /graph/v1/paper/ARXIV:{id}?fields=venue,publicationVenue,journal(s2_venue_from_paper)。丢弃 arXiv / CoRR 等仓储名。
  2. DOI → 取 S2 publicationVenue 与 Crossref container-title 中更长的可用名(S2 赢截断的 ACL/NAACL;Crossref 赢完整 proceedings 标题)。跳过 10.48550/arXiv.…。
  3. 仅 title → Semantic Scholar search_papers(title, 1),同样走 publicationVenue。

UI 刷新(paper_resolve_identifier)对 DOI/arXiv/URL 先走标识符解析,再用 S2 补全空缺或 Crossref 截断的 proceedings 标题;自由文本才走 title search。

2.6 arXiv / DOI Venue 回填

入口:features/paper/scholar_api/sources/semantic_scholar.rs::SemanticScholarApi::fetch_venue_by_arxiv / fetch_venue_by_doi / fetch_venue_by_ids(取值逻辑 venue_from_paper)。

请求 GET /graph/v1/paper/{ARXIV:id\|DOI:doi}?fields=venue,publicationVenue,journal。取值顺序:

  1. publicationVenue.name(type=repository 跳过)
  2. journal.name
  3. 遗留 venue 字符串

用于:

  • paper_backfill_publication 的 arXiv 分支:Atom 的 <arxiv:journal_ref>(scholar_api/sources/arxiv.rs::parse_entries → ApiPaper.venue)缺失时补 venue。
  • 批量 publication 回填与 Edit Metadata 刷新(enrich_publication_from_s2)。
  • title search 候选的 venue 字段。

2.7 推荐与订阅

入口:features/recommend/mod.rs。

  • 按用户关注的 arXiv category 拉取 https://rss.arxiv.org/rss/{category}。
  • 解析后基于本地 embedding 做相似度排序,产生推荐候选。

2.8 广场 Feed 解析

入口:features/feeds/。

  • 订阅源同样以 rss.arxiv.org 为主。
  • features/feeds/parse.rs::extract_paper_url 会把 rss.arxiv.org 链接规范化到 arxiv.org/abs/{id},并支持 Nature DOI 链接提取。

2.9 Cool Papers (papers.cool)

入口:features/coolpapers/mod.rs。

  • 解析论文 URL:https://papers.cool/{arxiv|venue}/{id}。
  • 按标题搜索:GET https://papers.cool/{branch}/search?query=...。
  • 获取 Kimi 解析:GET https://papers.cool/{branch}/kimi?paper={id}。
  • 这是一个人工整理的学术站点,不是开放 API;解析结果写入 NOTES.md。FAQ 问题写成 ## Qn,保留答案内 ### 小节;丢弃末尾「想要进一步了解论文」FAQ(跳转 Kimi 网页版的推广段)。

2.10 PDF / TeX 资产下载

入口:features/paper/import/download.rs。

  • arXiv PDF 候选链:https://arxiv.org/pdf/{id} → https://arxiv.org/pdf/{id}.pdf → https://export.arxiv.org/pdf/{id}。
  • arXiv TeX 源码:https://arxiv.org/e-print/{id}(/src/ 为别名)。
  • DOI 论文 PDF:先查 api.unpaywall.org/v2/{doi},再查 Crossref message.link 中的 PDF 链接。

2.11 PubMed / bioRxiv / medRxiv 元数据兜底

入口:features/paper/scholar_api/sources/pubmed.rs、features/paper/scholar_api/sources/biorxiv.rs。

  • PubMed:实现 AcademicApi,支持标题搜索和 PMID 查询。流程为 esearch.fcgi(JSON)拿 PMID 列表 → efetch.fcgi(XML)批量取详情;请求带 email 与 tool 参数以符合 NCBI 礼貌使用要求。解析字段包括 title、authors、year、venue、volume、issue、pages、DOI、PMID、abstract;PMC 存在时给出 PDF 候选。
  • bioRxiv / medRxiv:共用 biorxiv.rs,实现 AcademicApi,仅支持 FETCH_BY_DOI(上游 API 无 title 搜索端点)。请求 https://api.biorxiv.org/details/{server}/{doi},解析 title、authors、date、abstract,并构造 .full.pdf 直链。
  • PMID 在 scholar_api::identifiers::resolver 中已有识别器,现在为其补充 PubMed efetch 直连 fallback(scholar_api::identifiers::fallback::fetch_pubmed_metadata);Translator 失败时可直接从 NCBI 拉取。

3. 并发与限流

能力 并发控制 说明
scholar_api 全部请求 GLOBAL_CONCURRENCY = 4(scholar_api/client.rs Semaphore) 6 个标题搜索源并发时尾部排队,排队计入各源 8s FETCH_BUDGET;429→RateLimited、404→NotFound 统一处理
直连兜底链 错峰 600ms/源 + 优先级顺序接受 主源健康时零请求放大;链整体限流才 2s 重试一趟
在线参考文献 ONLINE_REFERENCE_CONCURRENCY = 2 与 title search 独立
批量入库 默认 concurrency = 5 LookupImportBatchArgs.concurrency 可覆盖
反向引用发现 FETCH_CONCURRENCY = 8 实测 8 并发比串行快约 4.6 倍
Cool Papers /kimi 1 避免触发上游 LLM 配额
通用 HTTP crate::core::http::client 共享连接池,单个请求超时 20s,PDF/TeX 下载 180s

默认所有调用均使用无 API key 的免费端点(Semantic Scholar、arXiv、Crossref、Unpaywall);Semantic Scholar、PubMed 与 OpenAlex 额外支持可选的 BYOK 环境变量(见第 4 节)。Cool Papers 无 auth。Translator Runtime 默认使用项目托管实例 https://translation-server.agentero.app,用户可在设置中替换。

4. 配置与可替换项

配置项 位置 默认值 说明
translatorBaseUrl features/system/settings/mod.rs https://translation-server.agentero.app 可替换为自托管 Translator Runtime
LookupImportArgs.translator_base_url 单次请求参数 空则使用设置值 CLI/批量导入可临时覆盖
后台 PDF 识别(RecognizeMetadata job) job_runners.rs 直接读设置 translator_base_url 空则用 DEFAULT_TRANSLATOR_BASE_URL 不经 IPC 入参传入(ImportLocalPdfArgs 无此字段)
SEMANTIC_SCHOLAR_API_KEY 环境变量,scholar_api/client.rs::auth_headers 按请求读取 未设置 对 api.semanticscholar.org 的请求追加 x-api-key 头;免费 key 可将共享池限速提升至 1 req/s+
NCBI_API_KEY 环境变量,scholar_api/sources/pubmed.rs 按请求读取 未设置 esearch/efetch 追加 api_key= 参数;免费 key 将单 IP 限速从 3 提升到 10 req/s
institutionProxyType 设置项 ezproxy 网关形态:ezproxy(查询透传 {prefix}{urlencode(target)},裸域名自动补 /login?url=)或 wengine(网瑞达路径式 /https/{AES-128-CTR(host)}/{path},浙大等,见 settings.md)
institutionProxyPrefix 设置项(settings.json,camelCase) 未设置 机构网关地址(源站即可),如 https://webvpn.zju.edu.cn(wengine)。设置页提供常见院校快速填充(浙大 / 中科大 / 西交 / 东北大学 / 浙江师范 / 沈阳建筑 / 肇庆学院,均为实测 wengine 网关)。配置后 PDF 下载链在 Unpaywall 未命中时经前缀重写请求,覆盖 #654 一类"浏览器能看、直连 403"的机构订阅场景(预设表为 #677 第一期后的延续项)
institutionProxyCookie 设置项 空 随机构代理请求发送的会话 Cookie(从浏览器 DevTools 粘贴);配套 institution_proxy_probe 命令可测试连通性(取 10.1038/nature12373 校验 %PDF)。桌面与 headless CLI 共用同一份 settings.json:CLI 启动时经 download::load_institution_proxy_from_settings 读取并注入下载链,故 import id / paper download 同样走机构网关(#654 之后补齐的 CLI 侧接线)
OPENALEX_MAILTO 环境变量,scholar_api/sources/openalex.rs 按请求读取 agentero@users.noreply.github.com 覆盖 OpenAlex polite pool 联系邮箱;同时补齐 doi: 端点的 mailto 参数

Translator Runtime 约定端点:

  • POST {base}/web:解析 URL(arXiv abstract page、期刊 landing page 等)。
  • POST {base}/search:按标识符或标题搜索。
  • POST {base}/import:解析 BibTeX / RIS 等题录。

5. Fallback 行为速查

场景 第一选择 Fallback 最后兜底
用户输入 title/关键词 6 源并发(S2/Crossref/OpenAlex/arXiv/PubMed/alphaXiv,S2 match 3s 快路径优先) 单源失败 warn 降级;任一源应答即返回 全源失败且含 429 → 报 rate limited(#524 不再误报无结果)
用户输入 arXiv id Translator /web (canonical abs URL) arXiv 链:Atom → S2 → alphaXiv(错峰投机并发) 链整体限流 → 2s 重试一趟 → rate_limited
用户输入 DOI Translator /search DOI 链:Crossref → S2 → OpenAlex(错峰投机并发) 同上
用户输入 PMID Translator /search PubMed 链:efetch 同上
用户输入 URL Translator /web - 无
PDF 识别出 DOI Translator DOI 链(Crossref→S2→OpenAlex) 本地 title fallback
PDF 识别出 arXiv arXiv 链(Atom→S2→alphaXiv) - 本地 title fallback;链整体限流 → arxiv_rate_limited 警告
在线参考文献 S2 references Crossref reference[] 本地 TeX/.bbl
反向引用 S2 citations 无 无
补全 publication arXiv journal_ref / S2 publicationVenue S2 DOI:{doi} → Crossref container-title S2 title search
下载 PDF arXiv 直连 arXiv export / Unpaywall / Crossref link 无 PDF
下载 TeX arXiv e-print - PDF only

6. 相关文档