关于 alterlab-openalex
alterlab-openalex 是面向学术研究者的 OpenAlex API 查询技能,可检索文献、分析研究产出并追踪引用。它提供直接 API 客户端和常用研究查询辅助函数。
主要功能
- 01跨学科文献检索
- 02按作者或机构查找论文
- 03引用与发表趋势分析
- 04开放获取状态筛选
- 05批量 DOI 查询与随机抽样
适用场景
- 01查找特定主题或年份的论文
- 02分析机构或作者的研究产出
- 03追踪论文引用和研究趋势
安装
复制下面的命令,在终端中运行。
npx skills add https:/ / github.com/ alterlab-ieu/ alterlab-academic-skills --skill alterlab-openalex安装后在 Claude Code 中输入/alterlab-openalex确认已加载。
包含的文件
除 SKILL.md 外,安装时一起下载的参考资料和脚本。
evals/evals.jsonreferences/api_guide.mdcommon_queries.mdscripts/openalex_client.pyquery_helpers.py详细介绍
OpenAlex 数据库
概述
OpenAlex 是一个内容全面的开放目录,包含超过 3 亿篇学术作品(默认的“core”语料;corpus=all 会增加约 60%,主要是数据集和知识库记录)、作者、机构、主题、来源、出版商和资助方。此技能提供查询 OpenAlex API 的工具和工作流,可用于检索文献、分析研究成果、追踪引用和开展文献计量研究。
何时使用此技能
- 跨学科检索学术文献(按关键词、语义检索,或按年份、OA 状态、类型筛选)
- 通过 OpenAlex/ORCID/ROR/ISSN ID 查找作者、机构、资助方或来源的作品
- 查询引用次数、引用作品,并开展文献计量或趋势分析(
group_by聚合) - 查看论文的开放获取状态和位置,或批量解析 DOI 以获取元数据
不适用的场景
| 场景 | 改用 |
|---|---|
| 使用 MeSH 术语、PMID 或 PubMed Central 全文检索生物医学文献 | alterlab-pubmed |
| 围绕种子论文构建引用图/共引图 | alterlab-citation-graph |
| 检查参考书目中的每条文献是否存在或已被撤稿 | alterlab-citation-verifier |
| 管理 Zotero 文库(条目、分类、附件) | alterlab-pyzotero |
| 根据找到的论文撰写结构化文献综述 | alterlab-literature-review |
快速开始
基本设置
OpenAlex 使用每日费用额度(参见下文“速率限制与费用”)。即使没有凭据也能获取响应,但无密钥调用会与同一 IP 地址上的所有人共享每天 0.10 美元的额度;在大学、VPN 或云网络中,这一额度往往早已用完,此后每次列表或搜索调用都会返回 HTTP 429,直到 UTC 午夜。免费 API 密钥可为你提供每天 1 美元的专属额度——在 openalex.org/settings/api 获取密钥,并将其导出为 OPENALEX_API_KEY;客户端会读取该密钥并将其作为 Authorization: Bearer 标头发送,从而避免密钥出现在 URL 和日志中(也可使用 ?api_key=)。旧版 mailto“礼貌池”已于 2026 年 2 月停用,因此 mailto= 不再带来任何好处。
from scripts.openalex_client import OpenAlexClient
# Recommended: export OPENALEX_API_KEY=... (free; own $1/day budget)
client = OpenAlexClient() # or OpenAlexClient(api_key="...")
# With no key set, the client still works on the shared keyless budget
安装要求
使用 uv 安装所需的软件包:
uv pip install requests
核心功能
1. 搜索论文
适用场景:按标题、摘要或主题查找论文
# Simple search
results = client.search_works(
search="machine learning",
per_page=100
)
# Semantic (embedding) search — matches meaning rather than words; accepts up to
# 2,000 characters (e.g. a grant aim), returns at most 50 results, 1 request/second
results = client._make_request('/works', {
'search.semantic': 'predicting drug toxicity from molecular structure',
'select': 'id,title,relevance_score',
})
# Search with filters
results = client.search_works(
search="CRISPR gene editing",
filter_params={
"publication_year": ">2020",
"is_oa": "true"
},
sort="cited_by_count:desc"
)
2. 按作者查找作品
适用场景:获取特定研究人员的所有出版物
使用两步模式(实体名称 → ID → 作品):
from scripts.query_helpers import find_author_works
works = find_author_works(
author_name="Jennifer Doudna",
client=client,
limit=100
)
手动两步操作:
# Step 1: Get author ID
author_response = client._make_request(
'/authors',
params={'search': 'Jennifer Doudna', 'per-page': 1}
)
author_id = author_response['results'][0]['id'].split('/')[-1]
# Step 2: Get works
works = client.search_works(
filter_params={"authorships.author.id": author_id}
)
3. 查找机构的作品
适用场景:分析大学或组织的研究成果
from scripts.query_helpers import find_institution_works
works = find_institution_works(
institution_name="Stanford University",
client=client,
limit=200
)
4. 高引用论文
适用场景:查找某个领域中具有影响力的论文
from scripts.query_helpers import find_highly_cited_recent_papers
papers = find_highly_cited_recent_papers(
topic="quantum computing",
years=">2020",
client=client,
limit=100
)
5. 开放获取论文
适用场景:查找可免费获取的研究
from scripts.query_helpers import get_open_access_papers
papers = get_open_access_papers(
search_term="climate change",
client=client,
oa_status="any", # or "gold", "green", "hybrid", "bronze"
limit=200
)
6. 出版趋势分析
适用场景:追踪研究成果随时间的变化
from scripts.query_helpers import get_publication_trends
trends = get_publication_trends(
search_term="artificial intelligence",
filter_params={"is_oa": "true"},
client=client
)
# Sort and display
for trend in sorted(trends, key=lambda x: x['key'])[-10:]:
print(f"{trend['key']}: {trend['count']} publications")
7. 研究成果分析
适用场景:全面分析作者或机构的研究成果
from scripts.query_helpers import analyze_research_output
analysis = analyze_research_output(
entity_type='institution', # or 'author'
entity_name='MIT',
client=client,
years='>2020'
)
print(f"Total works: {analysis['total_works']}")
print(f"Open access: {analysis['open_access_percentage']}%")
print(f"Top topics: {analysis['top_topics'][:5]}")
8. 批量查询
适用场景:高效获取多个 DOI、ORCID 或 ID 的信息
dois = [
"https://doi.org/10.1038/s41586-021-03819-2",
"https://doi.org/10.1126/science.abc1234",
# ... any number; sent in batches of 100 (the per-filter OR limit)
]
works = client.batch_lookup(
entity_type='works',
ids=dois,
id_field='doi'
)
9. 随机抽样
适用场景:获取具有代表性的样本以供分析
# Small sample
works = client.sample_works(
sample_size=100,
seed=42, # For reproducibility
filter_params={"publication_year": "2023"}
)
# Large sample (>10k) - automatically handles multiple requests
works = client.sample_works(
sample_size=25000,
seed=42,
filter_params={"is_oa": "true"}
)
10. 引用分析
适用场景:查找引用特定作品的论文
# Get the work
work = client.get_entity('works', 'https://doi.org/10.1038/s41586-021-03819-2')
# Get citing papers using cited_by_api_url
import requests
citing_response = requests.get(
work['cited_by_api_url'],
params={'per_page': 100},
headers=client.auth_headers(), # Bearer key, if one is configured
)
citing_works = citing_response.json()['results']
11. 主题与学科分析
适用场景:了解研究重点领域
# Get top topics for an institution
topics = client.group_by(
entity_type='works',
group_field='topics.id',
filter_params={
"authorships.institutions.id": "I136199984", # MIT
"publication_year": ">2020"
}
)
for topic in topics[:10]:
print(f"{topic['key_display_name']}: {topic['count']} works")
12. 大规模数据提取
适用场景:下载大型数据集以供分析
# Paginate through all results (the client uses cursor paging, so it can go past
# the 10,000-result limit of page-based paging; for whole-corpus pulls use the
# free OpenAlex snapshot instead of the API)
all_papers = client.paginate_all(
endpoint='/works',
params={
'search': 'synthetic biology',
'filter': 'publication_year:2020-2024'
},
max_results=10000
)
# Export to CSV
import csv
with open('papers.csv', 'w', newline='', encoding='utf-8') as f:
writer = csv.writer(f)
writer.writerow(['Title', 'Year', 'Citations', 'DOI', 'OA Status'])
for paper in all_papers:
writer.writerow([
paper.get('title', 'N/A'),
paper.get('publication_year', 'N/A'),
paper.get('cited_by_count', 0),
paper.get('doi', 'N/A'),
paper.get('open_access', {}).get('oa_status', 'closed')
])
关键最佳实践
使用免费 API 密钥提高每日额度
没有凭据时,你需要与同一 IP 上的所有人共享每天 0.10 美元的额度;免费 API 密钥可为你提供每天 1 美元的专属额度。将密钥传递给客户端:
export OPENALEX_API_KEY=... # free at openalex.org/settings/api; OpenAlexClient() picks it up
实体查询使用两步模式
按 ID 筛选,而不是按名称筛选——名称可能有歧义(“Smith”对应数千位作者,“MIT”对应多个机构),因此应先将实体解析为其 ID:
# ✅ Correct
# 1. Search for entity → get ID
# 2. Filter by ID
# ❌ Wrong
# filter=author_name:Einstein # This doesn't work!
使用最大页大小
使用 per_page=100(支持的最大值;per_page=200 是已弃用的旧行为,OpenAlex 表示将移除)。无论返回 1 条还是 100 条结果,列表调用的成本都相同:
results = client.search_works(search="topic", per_page=100)
批量查询多个 ID
查询多个 ID 时,使用 batch_lookup(),而不是逐个发送请求:
# ✅ Correct - 1 request per 100 DOIs
works = client.batch_lookup('works', doi_list, 'doi')
# ❌ Wrong - one request per DOI
for doi in doi_list:
work = client.get_entity('works', doi)
使用 Sample 参数获取随机数据
使用带 seed 的 sample_works(),以便进行可复现的随机抽样:
# ✅ Correct
works = client.sample_works(sample_size=100, seed=42)
# ❌ Wrong - random page numbers bias results
# Using random page numbers doesn't give true random sample
仅选择所需字段
选择特定字段以缩减响应大小:
results = client.search_works(
search="topic",
select=['id', 'title', 'publication_year', 'cited_by_count']
)
常见筛选模式
filter_params 条目以逗号连接(AND)。完整语法、运算符和字段名请参阅:references/api_guide.md(筛选语法)。
filter_params = {
"publication_year": "2020-2024", # also "2023", ">2020", "<2020"
"is_oa": "true", # several keys = AND
"cited_by_count": ">100",
"authorships.institutions.id": "I136199984|I27837315", # | = OR (≤100 values): MIT or Harvard
# "authorships.institutions.id": "I136199984+I27837315", # + = AND within one attribute (co-authored)
"type": "!paratext", # ! = negation
}
实体类型
OpenAlex 提供以下实体类型:
- works - 学术文献(文章、书籍、数据集)
- authors - 具有消歧身份的研究人员
- institutions - 大学和研究机构
- sources - 期刊、知识库、会议
- topics - 学科分类
- publishers - 出版机构
- funders - 资助机构
使用一致的模式访问任意实体类型:
client.search_works(...)
client.get_entity('authors', author_id)
client.group_by('works', 'topics.id', filter_params={...})
外部 ID
直接使用外部标识符:
# DOI for works
work = client.get_entity('works', 'https://doi.org/10.7717/peerj.4375')
# ORCID for authors
author = client.get_entity('authors', 'https://orcid.org/0000-0003-1613-5981')
# ROR for institutions
institution = client.get_entity('institutions', 'https://ror.org/02y3ad647')
# ISSN for sources
source = client.get_entity('sources', 'issn:0028-0836')
参考文档
详细 API 参考
请参阅 references/api_guide.md,了解:
- 完整的筛选语法
- 所有可用端点
- 响应结构
- 错误处理
- 性能优化
- 速率限制详情
常见查询示例
请参阅 references/common_queries.md,了解:
- 完整的可运行示例
- 真实使用场景
- 复杂查询模式
- 数据导出工作流
- 多步分析流程
脚本
openalex_client.py
主要 API 客户端,支持:
- 自动速率限制
- 指数退避重试逻辑
- 分页
- 批量操作
- 错误处理
适用于需要完全控制的直接 API 访问。
query_helpers.py
用于常见操作的高级辅助函数:
find_author_works()- 获取作者的论文find_institution_works()- 获取机构的论文find_highly_cited_recent_papers()- 获取有影响力的论文get_open_access_papers()- 查找开放获取出版物get_publication_trends()- 分析随时间变化的趋势analyze_research_output()- 综合分析
适用于通过简化接口执行常见研究查询。
故障排除
每日限额 / 限流(429)
如果遇到 429(请求过多)错误:
- 添加免费的 API 密钥,以使用属于你自己的每日 $1 额度,而不是共享的每日 $0.10 无密钥额度(
export OPENALEX_API_KEY=...)。如果 429 响应的Retry-After时长为数小时,说明每日额度已用完——在 UTC 午夜之前重试也无济于事,此时客户端会立即引发错误 - 降低成本:优先使用单实体查询和列表+筛选调用,而不是
search=(每次搜索调用消耗的额度更多);使用select=以降低响应成本 - 客户端会自动退避并重试短暂的限流情况(429/403/5xx),例如超过每秒 100 个请求
- 查看
x-ratelimit-remaining-usd/x-ratelimit-cost-usd响应标头,了解剩余额度
结果为空
如果搜索没有返回结果:
- 检查筛选语法(参见
references/api_guide.md) - 对实体查询使用两步模式(不要按名称筛选)
- 确认实体 ID 格式正确
超时错误
对于大型查询:
- 使用
per_page=100分页 - 使用
select=限制返回字段 - 如有需要,拆分为较小的查询
速率限制与费用
OpenAlex 采用每日费用预算,并设有每秒 100 个请求的硬性上限。每次调用都会产生少量美元费用;你每天都有免费额度,超出后才需付费(可预充值或购买年度套餐)。
- 无密钥:每天 $0.10,由使用同一 IP 地址的所有人共享。
- 使用免费 API 密钥(
openalex.org/settings/api,通过Authorization: Bearer <key>或?api_key=发送):你有专属的每天 $1 额度。推荐使用。自 2026 年 2 月停用礼貌请求池后,mailto=参数将被忽略。 - 每 1,000 次调用的费用(help.openalex.org,2026-08):按 ID/DOI 查询单个实体免费;列表加筛选 $0.10;
search=$1;search.semantic=$1;内容(PDF)下载 $10。因此,$1 可购买约 10,000 次筛选调用(per_page=100时约返回 100 万条结果)或约 1,000 次搜索——尽量使用筛选。 - 查询限制:
per_page≤ 100;基于页码的分页在 10,000 条结果后停止(请使用cursor=*);每个筛选器最多包含 100 个 OR 值;sample≤ 10,000。 - 使用
GET /rate-limit?api_key=...查看剩余额度。 - 响应标头会报告实时额度:
x-ratelimit-limit-usd、x-ratelimit-remaining-usd、x-ratelimit-cost-usd(以及响应中的meta.cost_usd)。 - 每日额度耗尽后,会返回 429 Too Many Requests,并附带倒计时至 UTC 午夜的
Retry-After;每秒请求数超过 100 的突发流量也会返回 429(等待时间较短)。403 也可能表示“请减慢请求速度”。
备注
- 所有数据均开放且免费;每日额度足以满足典型研究工作负载。
- 对于任何有一定规模的工作流,建议使用免费 API 密钥;临时查询则可不使用密钥。
- 费用和限制按凭据计算(按密钥计算,或在无密钥时按 IP 计算),而不只是按请求类型计算——尽量减少
search=的使用,并使用select=来延长额度使用时间。 - 如果需要基于大模型进行分析,请将 LitLLM 与 OpenRouter 搭配使用(不要直接使用 Perplexity API)。
- 客户端会自动处理分页、重试和退避。