mcpField
A
alterlab-openalex

alterlab-openalex

github.com/alterlab-ieu生产力7870 次安装5 周前更新
代码仓库

关于 alterlab-openalex

alterlab-openalex 是面向学术研究者的 OpenAlex API 查询技能,可检索文献、分析研究产出并追踪引用。它提供直接 API 客户端和常用研究查询辅助函数。

主要功能

  1. 01跨学科文献检索
  2. 02按作者或机构查找论文
  3. 03引用与发表趋势分析
  4. 04开放获取状态筛选
  5. 05批量 DOI 查询与随机抽样

适用场景

  1. 01查找特定主题或年份的论文
  2. 02分析机构或作者的研究产出
  3. 03追踪论文引用和研究趋势

安装

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

$npx skills add https://github.com/alterlab-ieu/alterlab-academic-skills --skill alterlab-openalex

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

包含的文件

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

evals/
evals.json
references/
api_guide.md
common_queries.md
scripts/
openalex_client.py
query_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(请求过多)错误:

  1. 添加免费的 API 密钥,以使用属于你自己的每日 $1 额度,而不是共享的每日 $0.10 无密钥额度(export OPENALEX_API_KEY=...)。如果 429 响应的 Retry-After 时长为数小时,说明每日额度已用完——在 UTC 午夜之前重试也无济于事,此时客户端会立即引发错误
  2. 降低成本:优先使用单实体查询和列表+筛选调用,而不是 search=(每次搜索调用消耗的额度更多);使用 select= 以降低响应成本
  3. 客户端会自动退避并重试短暂的限流情况(429/403/5xx),例如超过每秒 100 个请求
  4. 查看 x-ratelimit-remaining-usd / x-ratelimit-cost-usd 响应标头,了解剩余额度
结果为空

如果搜索没有返回结果:

  1. 检查筛选语法(参见 references/api_guide.md)
  2. 对实体查询使用两步模式(不要按名称筛选)
  3. 确认实体 ID 格式正确
超时错误

对于大型查询:

  1. 使用 per_page=100 分页
  2. 使用 select= 限制返回字段
  3. 如有需要,拆分为较小的查询

速率限制与费用

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)。
  • 客户端会自动处理分页、重试和退避。

评论

支持 Markdown