关于 semanticscholar-skill
semanticscholar-skill 是通过 Semantic Scholar API 检索学术文献的结构化工作流,适合研究人员查找论文与作者。它支持引文查询、相关论文推荐和结果导出,并由辅助模块处理速率限制。
主要功能
- 01使用多种策略搜索论文
- 02查询论文和作者
- 03遍历引文与参考文献
- 04查找相似论文和推荐结果
- 05按年份、领域等条件筛选
- 06导出为 BibTeX、Markdown 或 JSON
适用场景
- 01探索某个研究主题的文献
- 02按已知标题或标识符查找论文
- 03追踪引文与相关研究
- 04查找研究人员的发表成果
安装
复制下面的命令,在终端中运行。
npx skills add https:/ / github.com/ agents365-ai/ semanticscholar-skill --skill semanticscholar-skill安装后在 Claude Code 中输入/semanticscholar-skill确认已加载。
附带文件s2.py
详细介绍
Semantic Scholar 搜索工作流
通过 Semantic Scholar API 使用结构化的 4 阶段工作流搜索学术论文。
**关键规则:**绝不要为 API 请求连续多次调用 Bash。始终编写一个 Python 脚本来运行所有搜索,然后一次性执行。所有速率限制均由 s2.py 自动处理。
第 1 阶段:理解并规划
解析用户意图并选择搜索策略:
决策树
默认使用
search_bulk()。 根据 Semantic Scholar 官方文档,对于大多数情况,批量搜索优于相关性搜索,因为相关性搜索更消耗资源。只有在需要 TLDR 字段或内联作者/引文详情时,才使用search_relevance()。
| 用户需求 | 策略 | 函数 |
|---|---|---|
| 广泛探索主题 | 批量搜索(优先) | 使用 build_bool_query() 的 search_bulk() |
| 需要 TLDR/内联作者详情 | 相关性搜索 | search_relevance() |
| 精确技术术语、精确短语 | 使用布尔运算符进行批量搜索 | 使用 build_bool_query() 的 search_bulk() |
| 特定段落或方法 | 片段搜索 | search_snippets() |
| 已知标题的论文 | 标题匹配 | match_title() |
| 已知 DOI/PMID/ArXiv 的论文 | 直接查询 | get_paper() |
| 引用某篇已知研究的论文 | 引文遍历 | get_citations() |
| 与一篇论文相关 | 单种子推荐 | find_similar() |
| 与多篇论文相关 | 多种子推荐 | recommend() |
| 查找研究人员 | 作者搜索 | search_authors() |
| 研究人员的个人资料 | 作者详情 | get_author() |
| 研究人员的出版物 | 作者论文 | get_author_papers() |
查询构建规则
- 含义模糊的术语(例如,“stem cells”可能指间充质细胞,也可能指类干 T 细胞):使用
build_bool_query()配合精确短语和排除项- 示例:
build_bool_query(phrases=["stem-like T cells"], required=["CD4", "TCF7"], excluded=["mesenchymal", "hematopoietic stem cell"])
- 示例:
- 多语境查询(例如,“主题 X 在癌症 AND 自身免疫中的研究”):规划多个独立搜索,并使用
deduplicate()去重 - 宽泛主题:使用
search_relevance()并设置筛选条件(年份、出版物、研究领域、最低引文数)
规划筛选条件
| 筛选条件 | 适用情况 |
|---|---|
year="2020-" | 仅查找近期研究 |
publication_date="2024-01-01:2024-06-30" | 精确日期范围(YYYY-MM-DD) |
fields_of_study="Medicine" | 限定研究领域 |
min_citations=10 | 仅查找已有一定影响力的论文 |
pub_types="Review" | 查找综述/荟萃分析 |
pub_types="ClinicalTrial" | 仅查找临床试验 |
open_access=True | 仅查找开放获取论文 |
**检查点:**继续之前,请确认:(1) 搜索策略符合用户意图;(2) 筛选条件恰当;(3) 查询足够具体,能够避免无关结果。
阶段 2:执行搜索
编写一个 Python 脚本,开头包含以下标准前置代码,然后运行所有搜索:
# --- Standard prelude (use in every script) ---
import sys, os, glob
_candidates = [
os.path.expanduser("~/.claude/skills/semanticscholar-skill"),
os.path.expanduser("~/.openclaw/skills/semanticscholar-skill"),
*glob.glob(os.path.expanduser("~/.claude/plugins/**/semanticscholar-skill"), recursive=True),
*glob.glob(os.path.expanduser("~/.codex/skills/semanticscholar-skill")),
".",
]
SKILL_DIR = next((p for p in _candidates if os.path.isfile(os.path.join(p, "s2.py"))), None)
if SKILL_DIR is None:
raise RuntimeError("Cannot locate semanticscholar-skill (s2.py not found)")
sys.path.insert(0, SKILL_DIR)
from s2 import *
# --- end prelude ---
# Build precise query
q = build_bool_query(
phrases=["stem-like T cells"],
required=["CD4", "IBD"],
excluded=["mesenchymal"]
)
papers = search_bulk(q, max_results=30, year="2018-", fields_of_study="Medicine")
papers = deduplicate(papers)
print(format_results(papers, "Stem-like CD4 T cells in IBD"))
保存到 /tmp/s2_search.py,然后在一次 Bash 调用中运行 python3 /tmp/s2_search.py。速率限制、重试和退避会在 s2.py 内自动处理。
无需 API 密钥: 不设置 S2_API_KEY 也能使用此技能。密钥缺失或无效时,s2.py 会自动切换到未认证模式(不发送 x-api-key 标头),并将请求间隔延长至 5 s。根据 S2 文档,匿名调用会与所有未认证用户共用每秒 1000 次请求的全局配额池,而且在高峰时段可能会“受到进一步限制”——因此,保守地设置 5 s 间隔有助于避免高峰时段的限流,尽管稳定状态下的配额相当充足。如果仍持续收到 429 错误,请将 _MIN_GAP 调高至 10 s。每次搜索的 max_results 不要超过 30,并在每个脚本中合并较少的搜索。S2 建议在每个请求中都提供 API 密钥——请访问 https://www.semanticscholar.org/product/api#api-key-form 获取密钥。
检查点: 确认脚本成功运行(没有异常)并返回了结果。如果结果为 0,请在展示之前扩大查询范围或放宽筛选条件。
示例
以下每个示例都假定脚本顶部包含阶段 2 中的标准前置代码。
示例 1:作者工作流——“查找 Yann LeCun 关于自监督学习的论文”
authors = search_authors("Yann LeCun", max_results=5)
print(format_authors(authors))
# Use the first match's ID to get their papers
author_id = authors[0]["authorId"]
papers = get_author_papers(author_id, max_results=50)
# Filter locally for topic
ssl_papers = [p for p in papers if "self-supervised" in (p.get("title") or "").lower()]
print(format_results(ssl_papers, "Yann LeCun - Self-Supervised Learning"))
示例 2:引文链及意图——“哪些论文引用了 Transformer 论文?它们如何使用该论文?”
paper = get_paper("DOI:10.48550/arXiv.1706.03762")
print(f"Title: {paper['title']}, Citations: {paper['citationCount']}")
# Citation envelopes carry contextsWithIntent — keep them, don't flatten.
citing = get_citations(paper["paperId"], max_results=50)
citing.sort(key=lambda c: (c.get("citingPaper") or {}).get("citationCount", 0), reverse=True)
print(format_citations(citing, max_items=10)) # renders intent labels + context snippet
示例 3:多种子推荐并导出 BibTeX——“查找与这两篇论文相似、但不涉及 NLP 的论文”
recs = recommend(
positive_ids=["DOI:10.1038/nature14539", "ARXIV:2010.11929"],
negative_ids=["ARXIV:1706.03762"],
limit=20
)
print(format_results(recs, "Vision papers like Deep Learning & ViT, excluding NLP"))
# Export BibTeX for top results
bib_data = batch_papers([r["paperId"] for r in recs[:10]], fields="title,citationStyles")
print(export_bibtex(bib_data))
阶段 3:总结与展示
- 使用
format_results()生成格式一致的输出(摘要表格 + 前 10 条详情) - 如果用户使用中文,请用中文呈现摘要
- 始终注明结果总数和所用的搜索策略
- 根据用户的具体问题,重点介绍最相关的论文
阶段 4:用户交互循环
展示结果后,始终提供以下选项:
- 翻译——将标题/摘要翻译成中文(或其他语言)
- 详情——查看指定论文编号的完整摘要
- 优化——使用不同的词语/筛选条件缩小或扩大搜索范围
- 相似论文——查找与特定结果相似的论文(
find_similar()) - 引文——查看谁引用了特定论文,以及如何引用(
get_citations()+format_citations()获取意图标签) - 导出——通过
export_bibtex()、export_markdown()或export_json()保存结果 - 完成——结束搜索会话
持续循环,直到用户表示完成。每次后续操作都使用相同的单脚本模式。
其他资源
- S2folks GitHub——Semantic Scholar 官方代码示例:https://github.com/allenai/s2-folks
- Postman Collection——无代码 API 测试:链接见 https://www.semanticscholar.org/product/api/tutorial
- API 文档——完整的端点参考:https://api.semanticscholar.org/
API 快速参考
辅助模块(s2.py)
每个脚本开头都使用阶段 2 中的标准前置代码。然后调用以下任意函数——模块的文档字符串(help(s2) 或阅读 s2.py)按阶段列出了各函数及其单行简介。
论文搜索功能
| 函数 | 用途 | 最大结果数 |
|---|---|---|
search_relevance(query, **filters) | 简单的宽泛搜索 | 1,000 |
search_bulk(query, sort=..., **filters) | 布尔精确搜索 | 10,000,000 |
search_snippets(query, paper_ids=, authors=, inserted_before=, **filters) | 全文段落搜索 | 1,000 |
match_title(title) | 精确匹配标题 | 1 |
paper_autocomplete(query) | 查询补全建议 | — |
get_paper(paper_id) | 单篇论文详情 | — |
get_citations(paper_id, max_results, publication_date=) | 引用该论文的文献 | 10,000 |
get_references(paper_id, max_results) | 该论文引用的文献 | 10,000 |
find_similar(paper_id, limit, pool) | 基于单篇种子的推荐 | 500 |
recommend(positive_ids, negative_ids, limit) | 基于多个种子的推荐 | 500 |
batch_papers(ids, fields) | 批量查询(≤500) | — |
作者功能
| 函数 | 用途 | 最大结果数 |
|---|---|---|
search_authors(query, max_results) | 按姓名查找研究人员 | 1,000 |
get_author(author_id) | 作者资料(所属机构、h 指数) | — |
get_author_papers(author_id, max_results, publication_date=) | 作者的发表成果 | 10,000 |
get_paper_authors(paper_id, max_results) | 论文作者列表 | 1,000 |
batch_authors(ids, fields) | 批量查询作者(≤1000) | — |
筛选参数(kwargs)
snake_case kwargs 会自动转换为 S2 camelCase 参数(fields_of_study → fieldsOfStudy、min_citations → minCitationCount、publication_date → publicationDateOrYear、pub_types → publicationTypes、open_access → openAccessPdf)。此处请使用 snake_case。
year、publication_date、venue、fields_of_study、min_citations、pub_types、open_access
year:"2020-"、"-2019"、"2016-2020"publication_date:"2024-01-01:2024-06-30"(YYYY-MM-DD 范围,可以不指定起始或结束日期)pub_types:Review、JournalArticle、Conference、ClinicalTrial、MetaAnalysis、Dataset、Book、CaseReport、Editorial、LettersAndComments、News、Study、BookSection
布尔查询语法(仅限批量搜索)
| 语法 | 示例 | 含义 |
|---|---|---|
"..." | "deep learning" | 精确短语 |
+ | +transformer | 必须包含 |
- | -survey | 排除 |
| | CNN | RNN | 或 |
* | neuro* | 前缀通配符 |
() | (CNN | RNN) +attention | 分组 |
term~N | bugs~3 | 模糊匹配:匹配编辑距离不超过 N 的词(例如 buggy、buns) |
"phrase"~N | "blue lake"~3 | 邻近匹配:词语之间最多间隔 N 个词 |
使用 build_bool_query(phrases, required, excluded, or_terms, fuzzy, proximity) 安全地构造查询。
fuzzy:(term, edit_distance)元组列表proximity:(phrase, word_distance)元组列表
输出函数
| 函数 | 用途 |
|---|---|
format_table(papers, max_rows=30) | Markdown 摘要表格 |
format_details(papers, max_papers=10) | 包含 TLDR/摘要的详细条目 |
format_citations(citations, max_items=10) | 包含意图标签和上下文片段的引用信息 |
format_results(papers, query_desc) | 合并输出:摘要 + 表格 + 详情 |
format_authors(authors, max_rows=20) | 作者表格(姓名、所属机构、h 指数) |
export_bibtex(papers) | BibTeX 条目(需要 citationStyles 字段) |
export_markdown(papers, query_desc) | 将完整 Markdown 报告保存到文件 |
export_json(papers, path) | 将 JSON 导出到文件 |
deduplicate(papers) | 按 paperId 去除重复项 |
支持的 ID 格式
DOI:10.1038/...、ARXIV:2106.15928、PMID:19872477、PMCID:PMC2323569、CorpusId:215416146、ACL:2020.acl-main.447、DBLP:conf/acl/...、MAG:3015453090、URL:https://...
论文字段
默认:title,year,citationCount,authors,venue,externalIds,tldr
其他:corpusId(整数,S2 次级 ID)、url(S2 论文页面链接)、abstract、references、citations、openAccessPdf、publicationDate、publicationVenue、fieldsOfStudy、s2FieldsOfStudy、journal、isOpenAccess、referenceCount、influentialCitationCount(仅统计有影响力的引用)、citationStyles、embedding、textAvailability
externalIds 对象包含:ArXiv、MAG、ACL、PubMed、Medline、PubMedCentral、DBLP、DOI
作者字段:name、affiliations、paperCount、citationCount、hIndex、homepage、externalIds、papers
尽量减少字段。 根据官方 S2 教程:“避免包含超出所需的字段,因为这可能会降低响应速度。” 只有在用户明确需要时,才添加
abstract、references或citations。
sort 参数的取值(仅批量搜索)
sort 参数仅接受以下三个值:
| 值 | 含义 |
|---|---|
citationCount:desc | 引用次数最多的排在前面(默认) |
publicationDate:desc | 最新的排在前面 |
paperId:asc | 稳定的确定性排序(适用于分页) |
推荐结果数量限制
find_similar() 和 recommend() 每次调用最多返回 500 篇论文(limit 最大值为 500)。
数据集 API 函数
用于批量下载完整 S2 数据集(论文、作者、摘要、嵌入等):
| 函数 | 用途 | 是否需要密钥? |
|---|---|---|
list_releases() | 列出所有可用的发行日期字符串 | 否 |
list_datasets(release_id="latest") | 列出某个发行版中的数据集 | 否 |
get_dataset_links(release_id, dataset_name) | 获取数据集的预签名下载 URL | 是 |
get_dataset_diffs(start, end, dataset_name) | 获取两个发行版之间的增量差异 | 是 |
可用的数据集名称(作为 dataset_name 传入):
| 名称 | 说明 | 约略大小 |
|---|---|---|
papers | 论文核心属性(标题、作者、日期等) | 约 2 亿条记录,30 × 1.5 GB |
abstracts | 可用论文的摘要文本 | 约 1 亿条记录,30 × 1.8 GB |
authors | 作者核心属性(姓名、所属机构、论文数) | — |
citations | 论文之间的引用关系 | — |
embeddings-specter_v1 | 论文的稠密 SPECTER 向量嵌入 | 约 1.2 亿条记录,30 × 28 GB |
publication-venues | 发表场所的元数据 | — |
s2orc | 开放获取 PDF 中的全文文本 | — |
tldrs | 简短的自然语言摘要 | 约 1 亿条记录,30 × 200 MB |
所有数据集均以 JSON Lines 格式提供(每行一条记录)。差异响应包含 update_files(按主键插入或替换)和 delete_files(从数据集中删除)。
速率限制
s2.py 会根据是否设置了 S2_API_KEY 自动调整:
| 模式 | 间隔 | 官方限制 | 重试 |
|---|---|---|---|
| 已认证(有效密钥) | 1.1 s | 入门级每个密钥 1 req/s,拥有专属配额,所有端点累计计算(可申请提高) | 5 次指数退避(2s→60s) |
| 未认证(无密钥或密钥无效) | 5.0 s | 所有匿名用户共享全局 1000 req/s;“在使用量较大时可能会进一步限流” | 5 次指数退避(2s→60s) |
S2 建议每次请求都附带 API 密钥,即使匿名访问也能使用相应端点——这样可以获得专属配额,在负载较高时体验更流畅,并在需要帮助时获得更好的支持。入门级密钥的 1 req/s 限制可申请提高。请访问 https://www.semanticscholar.org/product/api#api-key-form 获取密钥。
匿名用户共享的 1000 req/s 配额在使用稳定时相当充足,但文档明确警告,在使用量较大时可能会遭到严格限流——因此,没有密钥时,
_MIN_GAP默认值为 5 s,而不是 1000 req/s 配额从理论上允许的 1 ms。如果你的工作负载仍持续触发 429,请在s2.py中设置_MIN_GAP = 10.0,或获取密钥。密钥的 1 req/s 配额会在所有端点间累计计算,因此链式调用(例如get_paper→get_citations)会分别计数。
批量搜索响应结构
search_bulk() 返回的论文列表已取消分页。内部原始响应包含:
| 字段 | 类型 | 含义 |
|---|---|---|
total | integer | 匹配论文的估算总数(并非精确值) |
token | string | 存在时表示还有更多页面;请在下一次请求中传入 |
data | array | 当前页面的论文 |
s2.py 会自动处理令牌分页——你只会看到最终的扁平列表。
故障排除
| 错误 | 原因 | 解决方法 |
|---|---|---|
HTTPError 403 | 已设置 S2_API_KEY,但密钥无效或已过期 | s2.py 会自动回退到未认证模式;也可以运行 unset S2_API_KEY,或访问 https://www.semanticscholar.org/product/api#api-key-form 获取新密钥 |
HTTPError 404 | 论文或作者 ID 错误 | 检查 ID 格式——S2 会返回 {"error": "Paper/Author/Object not found"} 或 "...with id ### not found" |
重试 5 次后仍出现 HTTPError 429 | 匿名用户持续触发速率限制 | 等待 60 s,将 s2.py 中的 _MIN_GAP 从 5.0 调高到 10.0,将 max_results 保持在 ≤ 30,或获取 API 密钥 |
ModuleNotFoundError: s2 | 技能目录不在路径中 | 确认技能已安装到 ~/.claude/skills/、~/.openclaw/skills/,或作为 Claude Code 插件安装在 ~/.claude/plugins/ 下 |
ModuleNotFoundError: requests | 未安装 requests | 运行 pip install requests 或 uv pip install requests |
| 返回 0 条结果 | 查询过于具体或筛选条件过窄 | 扩展查询范围、移除筛选条件,或尝试使用 search_relevance() 而非 search_bulk() |
KeyError: 'data' | 端点返回了错误对象 | 检查 r.get("message") 以查看 API 错误详情 |
tldr 字段为空 | 并非所有论文都有 TLDR;批量搜索不会返回该字段 | 改用 abstract 字段 |