semanticscholar-skill
此技能用于通过Semantic Scholar API进行学术论文检索、引用分析、作者查找和论文推荐。用户可执行批量搜索、布尔查询、相似论文推荐等操作,支持结果去重和格式化输出,大幅提升文献调研效率。
npx skills add https://github.com/agents365-ai/365-skills --skill semanticscholar-skillBefore / After 效果对比
1 组用户需要手动浏览多个学术数据库,逐一筛选和整理相关论文,平均耗时30分钟,且容易遗漏重要文献或重复劳动。
此技能通过统一的API接口快速执行批量搜索、布尔查询和去重,2分钟内即可获得结构化结果,查全率和查准率显著提升。
Semantic Scholar Search Workflow
Search academic papers via the Semantic Scholar API using a structured 4-phase workflow.
Critical rule: NEVER make multiple sequential Bash calls for API requests. Always write ONE Python script that runs all searches, then execute it once. All rate limiting is handled inside s2.py automatically.
Phase 1: Understand & Plan
Parse the user's intent and choose a search strategy:
Decision Tree
Default to
search_bulk(). Per Semantic Scholar's own docs, bulk search is preferred over relevance search for most cases because relevance search is more resource-intensive. Usesearch_relevance()only when you need TLDR fields or author/citation details inline.
| User wants... | Strategy | Function |
|---|---|---|
| Broad topic exploration | Bulk search (preferred) | search_bulk() with build_bool_query() |
| Need TLDR / inline author details | Relevance search | search_relevance() |
| Precise technical terms, exact phrases | Bulk search with boolean operators | search_bulk() with build_bool_query() |
| Specific passages or methods | Snippet search | search_snippets() |
| Known paper by title | Title match | match_title() |
| Known paper by DOI/PMID/ArXiv | Direct lookup | get_paper() |
| Papers citing a known work | Citation traversal | get_citations() |
| Related to one paper | Single-seed recommendations | find_similar() |
| Related to multiple papers | Multi-seed recommendations | recommend() |
| Find a researcher | Author search | search_authors() |
| Researcher's profile | Author details | get_author() |
| Researcher's publications | Author papers | get_author_papers() |
Query Construction Rules
- Ambiguous terms (e.g., "stem cells" could mean mesenchymal or stem-like T cells): Use
build_bool_query()with exact phrases and exclusions- Example:
build_bool_query(phrases=["stem-like T cells"], required=["CD4", "TCF7"], excluded=["mesenchymal", "hematopoietic stem cell"])
- Example:
- Multi-context queries (e.g., "topic X in cancer AND autoimmunity"): Plan separate searches, deduplicate with
deduplicate() - Broad topics: Use
search_relevance()with filters (year, venue, fieldsOfStudy, minCitationCount)
Plan Filters
| Filter | Use when |
|---|---|
year="2020-" | Recent work only |
publication_date="2024-01-01:2024-06-30" | Precise date range (YYYY-MM-DD) |
fields_of_study="Medicine" | Restrict to domain |
min_citations=10 | Only established papers |
pub_types="Review" | Find reviews/meta-analyses |
pub_types="ClinicalTrial" | Clinical trials only |
open_access=True | Only open access papers |
Checkpoint: Before proceeding, verify: (1) search strategy matches user intent, (2) filters are appropriate, (3) query is specific enough to avoid irrelevant results.
Phase 2: Execute Search
Write ONE Python script that begins with the standard prelude below, then runs all searches:
# --- 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"))
Save to /tmp/s2_search.py, then run with python3 /tmp/s2_search.py in a single Bash call. Rate limiting, retries, and backoff are automatic inside s2.py.
No API key: The skill works without S2_API_KEY. When the key is absent or invalid, s2.py automatically switches to unauthenticated mode (no x-api-key header) and widens the request gap to 5 s. Per S2 docs, anonymous calls share a global 1000 req/s pool across all unauthenticated users and can be "further throttled during periods of heavy use" — so a conservative 5 s gap protects against the heavy-use throttling, even though the steady-state pool is generous. If you still see sustained 429s, raise _MIN_GAP to 10 s. Keep max_results ≤ 30 per search and combine fewer searches per script. S2 recommends including an API key on every request — get one at https://www.semanticscholar.org/product/api#api-key-form.
Checkpoint: Verify the script ran successfully (no exceptions) and returned results. If 0 results, broaden the query or relax filters before presenting.
Worked Examples
Each example below assumes the standard prelude from Phase 2 is at the top of the script.
Example 1: Author workflow — "Find papers by Yann LeCun on self-supervised learning"
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"))
Example 2: Citation chain with intent — "Who cited the Transformer paper and how did they use it?"
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
Example 3: Multi-seed recommendations with BibTeX export — "Find papers like these two but not about 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))
Phase 3: Summarize & Present
- Use
format_results()for consistent output (summary table + top-10 details) - If user's language is Chinese, present summaries in Chinese
- Always note total results count and search strategy used
- Highlight most relevant papers based on the user's specific question
Phase 4: User Interaction Loop
After presenting results, always offer these options:
- Translate — titles/summaries to Chinese (or other language)
- Details — full abstract for specific paper numbers
- Refine — narrow or expand search with different terms/filters
- Similar — find papers similar to a specific result (
find_similar()) - Citations — who cited a specific paper and how (
get_citations()+format_citations()for intent labels) - Export — save results via
export_bibtex(),export_markdown(), orexport_json() - Done — end search session
Loop until user says done. Each follow-up uses the same single-script pattern.
Additional Resources
- S2folks GitHub — Official Semantic Scholar code examples: https://github.com/allenai/s2-folks
- Postman Collection — No-code API testing: linked from https://www.semanticscholar.org/product/api/tutorial
- API Documentation — Full endpoint reference: https://api.semanticscholar.org/
API Quick Reference
Helper Module (s2.py)
Use the standard prelude from Phase 2 at the top of every script. Then call any of the functions below — the module's docstring (help(s2) or read s2.py) lists each by phase with one-line summaries.
Paper Search Functions
| Function | Purpose | Max Results |
|---|---|---|
search_relevance(query, **filters) | Simple broad search | 1,000 |
search_bulk(query, sort=..., **filters) | Boolean precise search | 10,000,000 |
search_snippets(query, paper_ids=, authors=, inserted_before=, **filters) | Full-text passage search | 1,000 |
match_title(title) | Exact title match | 1 |
paper_autocomplete(query) | Query-completion suggestions | — |
get_paper(paper_id) | Single paper details | — |
get_citations(paper_id, max_results, publication_date=) | Who cited this | 10,000 |
get_references(paper_id, max_results) | What this cites | 10,000 |
find_similar(paper_id, limit, pool) | Single-seed recommendations | 500 |
recommend(positive_ids, negative_ids, limit) | Multi-seed recommendations | 500 |
batch_papers(ids, fields) | Batch lookup (≤500) | — |
Author Functions
| Function | Purpose | Max Results |
|---|---|---|
search_authors(query, max_results) | Find researchers by name | 1,000 |
get_author(author_id) | Author profile (affiliations, h-index) | — |
get_author_papers(author_id, max_results, publication_date=) | Author's publications | 10,000 |
get_paper_authors(paper_id, max_results) | Paper's author list | 1,000 |
batch_authors(ids, fields) | Batch author lookup (≤1000) | — |
Filter Parameters (kwargs)
snake_case kwargs are translated to S2 camelCase params automatically (fields_of_study → fieldsOfStudy, min_citations → minCitationCount, publication_date → publicationDateOrYear, pub_types → publicationTypes, open_access → openAccessPdf). Use snake_case here.
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 range, open-ended OK)pub_types:Review,JournalArticle,Conference,ClinicalTrial,MetaAnalysis,Dataset,Book,CaseReport,Editorial,LettersAndComments,News,Study,BookSection
Boolean Query Syntax (bulk search only)
| Syntax | Example | Meaning |
|---|---|---|
"..." | "deep learning" | Exact phrase |
+ | +transformer | Must include |
- | -survey | Exclude |
| | CNN | RNN | OR |
* | neuro* | Prefix wildcard |
() | (CNN | RNN) +attention | Grouping |
term~N | bugs~3 | Fuzzy: matches words within N edits (e.g. buggy, buns) |
"phrase"~N | "blue lake"~3 | Proximity: up to N words between terms |
Use build_bool_query(phrases, required, excluded, or_terms, fuzzy, proximity) to construct safely.
fuzzy: list of(term, edit_distance)tuplesproximity: list of(phrase, word_distance)tuples
Output Functions
| Function | Purpose |
|---|---|
format_table(papers, max_rows=30) | Markdown summary table |
format_details(papers, max_papers=10) | Detailed entries with TLDR/abstract |
format_citations(citations, max_items=10) | Citation envelopes with intent labels + context snippet |
format_results(papers, query_desc) | Combined: summary + table + details |
format_authors(authors, max_rows=20) | Author table (name, affiliations, h-index) |
export_bibtex(papers) | BibTeX entries (requires citationStyles field) |
export_markdown(papers, query_desc) | Full markdown report saved to file |
export_json(papers, path) | JSON export saved to file |
deduplicate(papers) | Remove duplicates by paperId |
Supported ID Formats
DOI:10.1038/..., ARXIV:2106.15928, PMID:19872477, PMCID:PMC2323569, CorpusId:215416146, ACL:2020.acl-main.447, DBLP:conf/acl/..., MAG:3015453090, URL:https://...
Paper Fields
Default: title,year,citationCount,authors,venue,externalIds,tldr
Additional: corpusId (integer, S2 secondary ID), url (S2 paper page link), abstract, references, citations, openAccessPdf, publicationDate, publicationVenue, fieldsOfStudy, s2FieldsOfStudy, journal, isOpenAccess, referenceCount, influentialCitationCount (influential citations only), citationStyles, embedding, textAvailability
externalIds object contains: ArXiv, MAG, ACL, PubMed, Medline, PubMedCentral, DBLP, DOI
Author fields: name, affiliations, paperCount, citationCount, hIndex, homepage, externalIds, papers
Minimize fields. Per the official S2 tutorial: "Avoid including more fields than you need, because that can slow down the response rate." Only add
abstract,references, orcitationswhen the user explicitly needs them.
sort Parameter Values (bulk search only)
The sort kwarg accepts only these three values:
| Value | Meaning |
|---|---|
citationCount:desc | Most-cited first (default) |
publicationDate:desc | Newest first |
paperId:asc | Stable deterministic order (useful for pagination) |
Recommendations Limits
find_similar() and recommend() return at most 500 papers per call (limit max = 500).
Datasets API Functions
For bulk download of full S2 datasets (papers, authors, abstracts, embeddings, etc.):
| Function | Purpose | Requires key? |
|---|---|---|
list_releases() | List all available release date strings | No |
list_datasets(release_id="latest") | List datasets in a release | No |
get_dataset_links(release_id, dataset_name) | Pre-signed download URLs for a dataset | Yes |
get_dataset_diffs(start, end, dataset_name) | Incremental diffs between two releases | Yes |
Available dataset names (pass as dataset_name):
| Name | Description | Approx size |
|---|---|---|
papers | Core paper attributes (title, authors, date, etc.) | ~200M records, 30 × 1.5 GB |
abstracts | Paper abstract text where available | ~100M records, 30 × 1.8 GB |
authors | Author core attributes (name, affiliation, paper count) | — |
citations | Citation relationships between papers | — |
embeddings-specter_v1 | Dense SPECTER vector embeddings of papers | ~120M records, 30 × 28 GB |
publication-venues | Venue metadata | — |
s2orc | Full-body text from open-access PDFs | — |
tldrs | Short natural-language summaries | ~100M records, 30 × 200 MB |
All datasets are delivered as JSON Lines (one record per line). The diffs response contains update_files (insert/replace by primary key) and delete_files (remove from dataset).
Rate Limiting
s2.py adapts automatically based on whether
...
用户评价 (0)
发表评价
暂无评价
统计数据
用户评分
为此 Skill 评分