semanticscholar-skill について
semanticscholar-skillは、Semantic Scholar APIで論文や研究者を検索する段階的なワークフローを提供します。文献調査向けに、検索方法の選択、絞り込み、引用の探索、結果の整形とエクスポートを扱います。
主な機能
- 01一括・関連度・スニペット検索
- 02DOI、タイトル、論文IDで検索
- 03引用と参考文献の追跡
- 04著者とその論文の検索
- 05結果の絞り込み、整形、出力
活用シーン
- 01特定テーマの学術文献を調査
- 02研究者とその出版物を検索
- 03引用と引用文脈をたどる
- 04検索結果をBibTeXで出力
インストール
コマンドをコピーしてターミナルで実行します。
npx skills add https:/ / github.com/ agents365-ai/ 365-skills --skill semanticscholar-skillインストール後、Claude Code で/semanticscholar-skillを入力して読み込まれたか確認します。
同梱ファイルs2.py
詳細
Semantic Scholar 検索ワークフロー
構造化された4段階のワークフローを使用して、Semantic Scholar API 経由で学術論文を検索します。
重要なルール: API リクエストのために、Bash 呼び出しを複数回連続して行うことは絶対に避けてください。すべての検索を実行する Python スクリプトを1つだけ作成し、一度だけ実行してください。レート制限はすべて 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"])
- 例:
- 複数の文脈を含むクエリ(例:「がん AND 自己免疫におけるトピック X」):検索を個別に計画し、
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 スクリプトを 1 つ作成します。
# --- 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 に保存し、1 回の Bash 呼び出しで python3 /tmp/s2_search.py を実行します。レート制限、再試行、バックオフは s2.py 内で自動的に処理されます。
API キーなし: このスキルは S2_API_KEY がなくても動作します。キーがないか無効な場合、s2.py は自動的に未認証モード(x-api-key ヘッダーなし)に切り替え、リクエスト間隔を 5 秒に広げます。S2 のドキュメントによると、匿名リクエストは未認証ユーザー全員で共有されるグローバルな 1000 req/s のプールを利用しますが、「利用が集中する時間帯には、さらにスロットリングされる場合があります」。そのため、通常時のプールには余裕がありますが、慎重に 5 秒の間隔を空けることで、利用集中時のスロットリングを避けられます。それでも 429 が継続して発生する場合は、_MIN_GAP を 10 秒に増やしてください。検索ごとの max_results は 30 以下にし、1 つのスクリプトに含める検索数を減らしてください。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 エクスポート — 「この 2 件に似ているが、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:要約と提示
- 一貫した出力(要約表+上位 10 件の詳細)には
format_results()を使用します - ユーザーの言語が中国語の場合、要約は中国語で提示します
- 結果の総数と使用した検索戦略を必ず明記します
- ユーザーの具体的な質問に基づき、最も関連性の高い論文を強調します
フェーズ 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 の標準プリアンブルを使用します。その後、以下の関数を呼び出します。各関数のフェーズ別の概要は、モジュールの docstring(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-index) | — |
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 | OR |
* | 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-index) |
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 キーワード引数で受け付ける値は、次の 3 つのみです。
| 値 | 意味 |
|---|---|
citationCount:desc | 被引用数の多い順(デフォルト) |
publicationDate:desc | 新しい順 |
paperId:asc | 安定した決定論的な順序(ページネーションに便利) |
レコメンデーションの上限
find_similar() と recommend() は、1 回の呼び出しにつき最大 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) | 2 つのリリース間の差分 | はい |
利用可能なデータセット名(dataset_name として渡します):
| 名前 | 説明 | おおよそのサイズ |
|---|---|---|
papers | 論文の主要属性(タイトル、著者、日付など) | 約 2 億件、1.5 GB × 30 |
abstracts | 利用可能な論文の抄録テキスト | 約 1 億件、1.8 GB × 30 |
authors | 著者の主要属性(名前、所属、論文数) | — |
citations | 論文間の引用関係 | — |
embeddings-specter_v1 | 論文の高密度 SPECTER ベクトル埋め込み | 約 1 億 2,000 万件、28 GB × 30 |
publication-venues | 掲載先のメタデータ | — |
s2orc | オープンアクセス PDF の全文テキスト | — |
tldrs | 自然言語による短い要約 | 約 1 億件、200 MB × 30 |
すべてのデータセットは JSON Lines(1 行につき 1 レコード)として提供されます。差分のレスポンスには、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 | 整数 | 一致する論文の推定総数(正確な値ではありません) |
token | 文字列 | 次のページがある場合に設定されます。次のリクエストで渡してください |
data | 配列 | このページの論文 |
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/plugins/ 配下の Claude Code プラグインとしてインストールされていることを確認してください |
ModuleNotFoundError: requests | requests がインストールされていない | pip install requests または uv pip install requests を実行してください |
| 返される結果が 0 件 | クエリが具体的すぎる、またはフィルターが絞り込みすぎている | クエリの範囲を広げ、フィルターを削除し、search_bulk() の代わりに search_relevance() を試してください |
KeyError: 'data' | エンドポイントがエラーオブジェクトを返した | r.get("message") で API エラーの詳細を確認してください |
tldr フィールドが空 | すべての論文に TLDR があるわけではありません。一括検索では TLDR は返されません | abstract フィールドを使用してください |