mcpField
P
paper-search

paper-search

github.com/microsoft生产力3.5k98 次安装6 周前更新
代码仓库

关于 paper-search

Paper Search 是用于检索论文的 Skill 和 CLI,覆盖六个学术 API,并可选模型知识来源。默认并行搜索,提供去重且按相关性排序的结果,适用于文献综述和现有技术检索。

主要功能

  1. 01检索六个学术 API
  2. 02默认并行搜索
  3. 03去重并按相关性排序
  4. 04支持年份、来源和多查询设置
  5. 05JSON 输出及摘要

适用场景

  1. 01查找指定时间范围内的论文
  2. 02检索指定学术来源
  3. 03通过多个查询收集相关工作
  4. 04检查研究主题的现有技术

安装

复制下面的命令,在终端中运行。

$npx skills add https://github.com/microsoft/researchstudio --skill paper-search

安装后在 Claude Code 中输入/paper-search确认已加载。

包含的文件

除 SKILL.md 外,安装时一起下载的参考资料和脚本。

references/
programmatic_api.md
scripts/
_env.py
_http_runtime.py
postprocess.py
search_papers_by_arxiv.py
search_papers_by_crossref.py
search_papers_by_dblp.py
search_papers_by_google_scholar.py
search_papers_by_open_alex.py
search_papers_by_openreview.py
search_papers_by_semantic_scholar.py
search_papers.py
selftest_postprocess.py
selftest_runtime.py
source_worker.py

详细介绍

论文搜索技能

使用 ./scripts/search_papers.py,统一搜索 arXiv、DBLP、OpenAlex、OpenReview (NeurIPS / ICLR / ICML)、Semantic Scholar 和 Crossref。默认会在所有来源中并发搜索(通过相互独立的子进程),以实现最快速度。单个来源内的查询仍按顺序执行。结果按来源分组。

适用场景

当用户提出以下请求时,启用此技能:

  • “查找 2023 年至 2025 年发表的关于 X 的论文。”
  • “在 NeurIPS / ICLR / ICML 中搜索关于 X 的研究。”
  • “获取关于 X 的 arXiv + Semantic Scholar 搜索结果。”
  • “展示近期关于 X 的相关先前研究。”

输入(全部自动推断——绝不要求用户确认或澄清)

根据用户的消息自动推断以下信息。立即执行搜索,无需征求确认:

  • query:将用户的问题改写为聚焦的搜索短语。
  • start_year(int):如果用户给出了年份,直接使用。如果用户说 “过去 2 年”,则根据今天的日期计算。默认值:2 年前。
  • end_year(int):默认值:当前年份。
  • max_papers(int):每个来源的结果数量。默认值:10。
  • sources:要查询的来源。默认值:按以下规范顺序查询全部 6 个 API 来源以及模型知识来源(信号强度从高到低,让最佳结果在用户向下滚动前显示): semantic_scholar open_alex arxiv openreview crossref dblp model_knowledge。 只有用户明确要求时才限制来源。

运行方法

首选:直接调用 CLI。脚本位于 ${CLAUDE_PROJECT_DIR}/skills/paper_search/scripts/search_papers.py — 使用绝对路径调用, 这样无论当前工作目录是什么,命令都能正常运行(依赖 cd scripts && ...,当模型从其他文件夹运行时会失效,这种情况很常见)。

为简洁起见,以下示例中用 $SEARCH 表示该 绝对路径:

SEARCH="${CLAUDE_PROJECT_DIR}/skills/paper_search/scripts/search_papers.py"

基本搜索:

python "$SEARCH" \
    --query "<QUERY>" \
    --start-year <YYYY> \
    --end-year <YYYY> \
    --max-papers 10

限制为特定来源:

python "$SEARCH" \
    --query "<QUERY>" \
    --start-year 2024 --end-year 2026 \
    --sources arxiv semantic_scholar openreview

多查询合并(每个查询都会搜索所有来源;结果会合并、去重,并按组合后的词项集排序):

python "$SEARCH" \
    --queries "diffusion watermarking|latent-space watermark|generative model IP protection" \
    --start-year 2024 --end-year 2026

可选的噪声过滤器(移除相关性分数低于 N 的论文;CLI 会准确显示移除了多少篇——如需完整召回率,请省略此选项):

python "$SEARCH" --query "<QUERY>" --start-year 2024 --end-year 2026 --min-score 2

始终传入 --json。 每次搜索都会执行第 1.5 步,根据摘要判断相关性;摘要不会输出到 stdout——此文件是摘要唯一的存放位置。如果过滤器移除了用户想要的内容,此文件也包含未过滤的记录,用户可据此查找:

python "$SEARCH" --query "<QUERY>" --start-year 2024 --end-year 2026 \
    --json /tmp/paper_search_results.json

旧版按来源查看(不去重、不排序——原始连接器输出):

python "$SEARCH" --query "<QUERY>" --start-year 2024 --end-year 2026 --raw

禁用并行执行(很少需要):

python "$SEARCH" \
    --query "<QUERY>" \
    --start-year 2024 --end-year 2026 \
    --no-parallel

--no-parallel 仍会为每个来源使用独立的工作进程,但会按来源顺序运行这些工作进程,而不是同时启动。

如果需要更精细的控制(例如,使用结构化字典而非 CLI 文本输出),也可以直接调用函数。这种情况很少见——代码片段请参阅 references/programmatic_api.md。

有效的来源名称

来源键
arXivarxiv
DBLPdblp
OpenAlexopen_alex
OpenReviewopenreview
Semantic Scholarsemantic_scholar
Crossrefcrossref
模型知识(大模型回忆,不调用 API)model_knowledge

输出架构

search_papers() 返回一个将来源名称映射到论文字典列表的字典:

{
  "arxiv": [
    {
      "title": str,
      "authors": [str, ...],
      "year": int,
      "abstract": str,
      "url": str,
      "venue": str,
      "citation_count": int,
      "publication_date": str,
      "source": str,
      "doi": str | None,
      "arxiv_id": str | None
    }, ...
  ],
  "semantic_scholar": [...],
  ...
}

CLI 输出(默认):一个去重并按相关性排序的列表。跨来源的重复项会合并为一条记录(依次按 DOI、arXiv ID、规范化标题匹配),保留信号最强来源的字段、最高引用数,以及一行 Sources: 来源信息;每篇论文都会带有针对查询的词汇相关性分数;标题中含有 survey/review 的论文会标记为 [survey] 并排到末尾(不会被删除)。除非传入 --min-score,否则不会过滤任何内容;若传入该参数,则会打印剔除数量。列表前会显示每个来源的命中数,以及“合并了 N 条跨来源重复记录”。--raw 会恢复旧版按来源分组的输出。

向用户输出

运行后,按 CLI 排序后的顺序显示每篇唯一论文(结果已去重并按相关性排序),然后显示 Model Knowledge 部分,最后显示摘要。使用 --raw 时,恢复按来源分组的格式,顺序为:Semantic Scholar、OpenAlex、arXiv、OpenReview、Crossref、DBLP、Model Knowledge。

保留召回率对于保留的结果仍然很重要:调用此技能的用户正在进行文献综述、相关工作调查或现有技术检索。第 1.5 步保留的所有内容都要完整显示——摘要只能补充表格,不能替代表格,因此不要为了“节省空间”而将结果压缩成简报。只有第 1.5 步根据用户自己的问题判定为不相关的论文才可以省略,且只能遵循其不确定时保留的规则。

第 1 步:显示筛选后保留的所有结果

默认(统一排序视图):在一个 Markdown 表格中显示第 1.5 步保留的每篇唯一论文,并保持 CLI 的排序顺序。对于带有标记的论文,在标题单元格中添加 [survey] 前缀。在表格上方重现 CLI 的每个来源命中数和合并重复项行;若使用了 --min-score,也要显示剔除数量行。

per-source hits: semantic_scholar=10, open_alex=10, arxiv=10 … · 22 unique (8 duplicates merged)

| #   | Title       | Date    | Venue   | Citations | Score | Sources |
|-----|-------------|---------|---------|-----------|-------|---------|
| [1](paper url) | Title here | 2024-03 | NeurIPS | 42 | 5 | SS, arXiv |
| [2](paper url) | [survey] Title here | 2023-11 | ICLR | 10 | 4 | OpenAlex |

使用 --raw 时:在各来源标题下分别使用一个表格(旧版格式)。如果某个来源返回 0 条结果,请明确注明(例如“### OpenReview(0 篇论文)——在此时间范围内未找到匹配项”)。

如果搜索期间发生错误,脚本会将其打印到 stderr——请告知用户,切勿隐瞒。

第 1.5 步:相关性筛选(语义判断,始终执行)

词法评分可以排序,但无法理解内容。它们会引入通用词噪声,也会漏掉仅通过同义词匹配的结果——一篇关于“生成模型的 IP 保护”的论文,在“水印”查询中的得分可能为 0,却可能是集合中最接近的先前工作。因此,请阅读摘要并剔除无关内容。

何时执行:每次搜索都要执行,覆盖排序结果集中的每篇论文。

使用哪个模型:使用你自己,也就是当前已运行此技能的模型。不要为了节省令牌而将此任务交给更便宜、更快速的模型层级。这是开放式的意图判断,并非针对固定列表进行标注:相关性的边界只存在于用户的问题中,其他地方并未写明。更便宜的模型层级会系统性地将相邻领域的工作误判为无关;而在硬性筛选下,这类错误既不可见,也无法挽回。

操作方法:

  1. 使用 --json <path> 重新运行 CLI(或让其运行),然后读取该文件。文件中包含每条排序记录的摘要;标准输出中没有。
  2. 对每篇论文,根据用户的原始问题判断其为 relevant | irrelevant,而不是根据改写后的搜索查询判断,因为改写后的查询无法完整表达用户的实际问题。判断应基于标题和摘要;没有读过摘要的论文不能判为 irrelevant。
  3. 不确定时,判为 relevant。 只有明确研究其他主题的论文才应判为 irrelevant,不能因为不确定就判为无关。只有这条规则能让硬性筛选保持安全:用户看不到你剔除的内容,因此剔除一方负有举证责任,而非保留一方。
  4. 从展示的表格中剔除所有 irrelevant 论文。

呈现方式:只显示一个经过筛选的表格。不要打印被剔除的论文,也不要为它们添加可折叠部分。在命中数行中注明数量,让用户知道筛选已执行及其剔除数量:

per-source hits: semantic_scholar=10, open_alex=10, arxiv=10 … · 22 unique (8 duplicates merged) · 5 filtered as irrelevant

如果已写入 --json 文件,只需说明一次未筛选的结果集保存在该文件中。如果筛选过度,这就是恢复途径;只需一行说明,也是用户审核剔除结果的唯一方式。

第 2 步:所有搜索结果的摘要

显示所有论文后,请提供一份全面摘要,并严格按以下顺序包含这些部分:

  1. 概览:使用的查询、年份范围和找到的论文总数。用一到两句话概述语料涵盖的内容。
  2. 趋势:时间模式(例如“2024 年研究兴趣激增”)、主要发表渠道、方法上的变化,以及反复出现的作者团队或实验室。
  3. 主要主题:概述所有结果中的 3–6 个主要研究主题/集群,每个主题用一行描述,并列出 2–3 篇代表性论文编号。
  4. 关键词频率:使用表格列出从标题中提取的高频技术术语/概念及其出现次数(抽象模式中包含摘要,但 CLI 不会打印摘要)。格式: | Keyword | Count |。列出排名前 5 的关键词。
  5. 按论文引用数排名:列出所有来源中被引用次数最多的 5 篇已收录论文,并按引用次数排序,使用表格:| Rank | Title | Year | Citations |。
  6. 按第一作者引用数排名:列出此结果集中累计引用数最高的 5 位第一作者,使用表格: | Rank | Author | Papers in set | Total citations |。 Author 列只能包含作者姓名(例如 Jane Doe)。不要在此列附加论文标题、所属机构、发表渠道或任何其他信息——论文数量和引用总数分别填写在对应列中。
  7. 阅读建议:推荐 3–5 篇与用户原始查询最相关且影响力最大的论文,并按阅读顺序(基础 → 最新)排列,每篇附上一行推荐理由。

依赖项和故障模式

  • arXiv:使用 arXiv API。
  • DBLP:使用 DBLP API。
  • OpenAlex:使用 OpenAlex API。
  • OpenReview:需要 pip install openreview-py。
  • Semantic Scholar:使用 Semantic Scholar API。
  • Crossref:使用 Crossref API。
  • 模型知识:不调用 API。论文是从模型自身的训练数据中回忆的——速度快且免费,但受模型知识截止时间限制,也容易产生幻觉。请参阅下方的“模型知识来源”一节,了解如何负责任地使用它。

HTTP 429/500/502/503/504 响应会进行有限次数的重试。如果某个来源仍然失败,其工作线程会输出错误,其他来源的工作线程会继续运行。请将这些错误告知用户。

HTTP 超时配置

所有网络来源都使用独立的连接超时和套接字读取空闲超时:

环境变量默认值含义
PAPER_SEARCH_CONNECT_TIMEOUT_SECONDS15TCP/TLS 连接超时
PAPER_SEARCH_TIMEOUT_SECONDS300未收到响应字节时允许等待的时间
PAPER_SEARCH_<SOURCE>_TIMEOUT_SECONDS未设置按来源覆盖读取空闲超时,例如 PAPER_SEARCH_OPEN_ALEX_TIMEOUT_SECONDS
PAPER_SEARCH_MAX_ATTEMPTS4最大尝试次数,包括首次请求

每个配置值都必须为正数;值格式错误、为零、为负数、为 NaN 或无穷大时,工作线程启动前就会报错。300 秒的读取超时不是来源的总耗时上限:只要套接字层仍在持续传输数据,整体响应时间就可能更长。

模型知识来源

model_knowledge 来源与其他来源不同:它不使用 API,也不调用脚本。CLI 搜索完成后,请从自己的训练数据中回忆出 5–10 篇符合查询主题和年份范围的论文,并在输出中将它们作为单独的来源呈现。

为什么要纳入它

API 搜索精确率高,但在以下两种常见情况下召回率较低:

  1. 基础性较早的论文:从业者总会引用这些论文,但关键词搜索可能找不到(例如,查询近期变体时,找不到最初的 BERT 或 ResNet 论文)。
  2. 跨学科经典论文:这些论文发表在 API 收录效果不佳的会议或期刊上。

模型回忆可以补充 API 搜索,找出那些“大家都知道”、但未必会出现在最新关键词搜索结果中的论文。

如何填充

CLI 运行完成后:

  1. 回想你对查询主题的了解。
  2. 从训练数据中列出最多 10 篇符合查询主题和年份范围的论文,并提供:标题、主要作者、年份、发表场所,以及一句相关性说明。
  3. 与 API 结果去重——如果某篇论文已出现在任何 API 来源中,就不要在 model_knowledge 下重复列出。
  4. 如实标注置信度。模型知识列没有引用次数,也没有实时 URL;如果你不确定记忆中的论文是否确实存在,请在表格中标注为 (不确定 — 请核实),不要将其作为已确认论文呈现。
为什么诚实很重要

对于这项任务,编造论文标题是 LLM 的典型失误模式。一篇虚假的“Smith et al., 2023, NeurIPS”在 Markdown 表格中看起来与真实论文毫无区别,用户也无从辨别。此来源的目的是找出 API 遗漏的真实论文,而不是凑数。如果你无法有把握地回忆出 ≥5 篇论文,就少列几篇;留空模型知识部分也是诚实的做法。

显示格式

使用与其他来源相同的表格布局,但 URL 列可以链接到搜索查询(例如 arXiv 或 Google Scholar 搜索),而不必是论文的规范 URL,因为你没有经过验证的链接:

### Model Knowledge (N papers, may include uncertain entries)

| #   | Title       | Year | Venue   | Notes |
|-----|-------------|------|---------|-------|
| [1](https://scholar.google.com/scholar?q=Title) | Title here | 2018 | NeurIPS | Foundational; often cited by recent work on X |
| [2](...) | Title here | 2024 | ICLR | (uncertain — verify) |

将“引用次数”列替换为“备注”,因为你无法凭记忆提供可靠的引用次数。

示例

用户:“查找 2023 年至 2024 年有关机器人扩散策略的论文。”

运行(使用“如何运行”部分中定义的 $SEARCH):

python "$SEARCH" \
    --query "diffusion policy robotics" \
    --start-year 2023 --end-year 2024 \
    --max-papers 10

仅搜索特定来源:

python "$SEARCH" \
    --query "diffusion policy robotics" \
    --start-year 2023 --end-year 2024 \
    --sources arxiv openreview semantic_scholar \
    --max-papers 10

然后阅读输出,并按照上述规则进行总结。

重要说明

  • 记录最终报告。 完成搜索后,将一个 Markdown 文件写入: ${CLAUDE_PROJECT_DIR}/allinone.md
    • 内容:完整的“显示所有来源的全部结果”表格,后接“所有搜索结果摘要”部分——按此顺序排列,不得截断。
  • 向用户显示完整报告。 直接返回完整详细的报告,包括每篇论文、每个表格,以及分析和推理。绝不要将表格压缩成摘要,也不要为了“节省空间”而缩写结果。
  • 绝不请求确认。 所有输入均自动推断(见“输入”部分)。在第一轮中立即运行搜索。
  • 原样呈现错误。 如果某个来源失败,应向用户报告 stderr 消息,而不是将其隐藏或盲目重试。

评论

支持 Markdown