[ blog · tutorial ]11 min read

把 ClinicalTrials.gov v2 + openFDA + ChEMBL 接成一个授权干净的药物情报端点

Sarah Choy发布于 2026年5月3日约 11 分钟阅读
把 ClinicalTrials.gov v2 + openFDA + ChEMBL 接成一个授权干净的药物情报端点

药企研发、医疗 AI 创业团队、药物警戒团队想要的其实是同一样东西:一个端点,以授权干净的方式把试验、标签、不良事件和生物活性拉到一起。下面是能跑的架构,以及那些在生产环境里坑过团队的暗门。

一句话总结

  • ClinicalTrials.gov v2(REST + JSON)在 2024 年取代了旧版 v1 —— schema 更干净,但分页、可选字段和历史数据漂移会坑住新接入方。
  • openFDA 覆盖药品标签(SPL)、FAERS 不良事件报告和召回数据,免费;未认证限流 240 req/min,带 key 后每天 120k。
  • ChEMBL 提供生物活性(IC50、Ki、Kd、EC50)、靶点和实验数据 —— 这是其他数据库缺失的结构/机制维度。
  • DrugBank 的商用授权是陷阱:学术使用允许;任何产品,哪怕是小型 SaaS,都落入大多数开发者直到收到通知才会去读的商用授权条款。
  • API Pick Clinical Search 把 ClinicalTrials、openFDA、ChEMBL 和 DrugBank 药理数据包进一个 POST 端点 —— 每次调用 30 credits,授权干净,仅对成功扣费。

问题的形状

三类受众最终需要的是大致相同的药物数据管线,理由各不相同:

  • 生物制药研发和药物再利用团队想把生物活性数据(ChEMBL)、试验历史(ClinicalTrials.gov)和不良事件信号(FAERS)拼起来,评估一个候选药物。
  • 医疗 AI 创业团队在搭聊天机器人或临床决策支持层,需要把药品标签(openFDA SPL)和试验数据拼起来,让 LLM 的回答有监管来源作依据。
  • 药物警戒团队想要 FAERS 加上药品标签的结构化字段,再加上来自 ChEMBL/DrugBank 的机制信息,来评估信号的合理性。

这几类受众最终都得把四个数据库接到一起:ClinicalTrials.gov、openFDA、ChEMBL 和 DrugBank。每个数据库都有自己的 schema、限流和授权条款。咬人的是 DrugBank —— 它的商用条款会坑住那些开发阶段接入却没读授权的团队,而向小型 SaaS 创始人寄送律师函是真会发生的事。

下面是我们推荐的架构,包括一条避开 DrugBank 陷阱的授权干净的替代路径。

四个数据源,各一段

ClinicalTrials.gov v2

美国国家医学图书馆。美国注册临床试验的权威登记库,也是事实上的全球标准。v2 于 2024 年上线 —— REST + JSON,取代了旧版 v1 的 CSV/XML。免费,限流(10 req/sec)。文档见 clinicaltrials.gov/data-api/api。优点:权威、全面、无授权问题。缺点:老研究的可选字段稀疏,仍在 v1 上的团队迁移有摩擦。

openFDA

FDA 运营的公开 API。覆盖药品标签(SPL —— 结构化产品标签)、FAERS(不良事件报告系统)、召回数据,以及食品/器械的对应内容。免费,未认证限流 240 req/min,带 API key 后每天 120,000 req。优点:权威的监管来源、结构化数据、覆盖面广。缺点:解析 SPL 需要理解 HL7 约定;FAERS 去重得你自己搞定。

ChEMBL

EBI / EMBL-EBI。经过整理的生物活性数据库 —— 跨化合物、靶点和实验的 IC50、Ki、Kd、EC50 测量值。免费,REST + JSON,中等流量下没有限流烦恼。优点:别处都没有的结构与机制数据。缺点:定位是研究级;治疗/临床映射并不完整。

DrugBank

起源于阿尔伯塔大学,现已商业化。药物-靶点映射、药理学、药物相互作用、多药理学。学术使用免费;商业使用需要付费授权。该授权适用于任何商业产品,包括免费的 SaaS 工具 —— 接入前先读条款。

跨 ClinicalTrials.gov、FDA 药品标签、ChEMBL 生物活性,以及我们授权的 DrugBank 药理元数据做语义搜索。JSON 进 / JSON 出,每次调用 30 credits(约 $0.03),仅对成功扣费。输出与监管和结构数据条款一致;对终端用户没有商用授权陷阱。

逐项对比

为写作时的快照。商业集成前请核实当前的限流与授权条款。
ClinicalTrials.gov v2openFDAChEMBLDrugBankAPI Pick Clinical
覆盖范围试验登记库标签 + FAERS + 召回生物活性、靶点、实验药物 + 靶点 + 相互作用四者全覆盖,语义化
格式REST + JSONREST + JSONREST + JSONREST + JSON / SQL 转储JSON,snippet 预先 shaping
限流10 req/sec未认证 240/min,带 key 120k/天宽松视授权档而定按调用(无按用户)
授权公有领域公有领域CC-BY-SA学术免费 / 商用付费API Pick 服务条款
最佳契合试验方案、申办方消歧监管标签、不良事件信号机制 / 结构药物相互作用、多药理学AI Agent 跨全部源检索

能跑的代码:逐个数据源

ClinicalTrials.gov v2

import requests

# Trials for a specific condition + intervention
r = requests.get(
    "https://clinicaltrials.gov/api/v2/studies",
    params={
        "query.cond": "non-small cell lung cancer",
        "query.intr": "pembrolizumab",
        "filter.overallStatus": "RECRUITING",
        "pageSize": 25,
        "format": "json",
    },
)
studies = r.json()["studies"]
for s in studies[:3]:
    proto = s["protocolSection"]
    nct = proto["identificationModule"]["nctId"]
    title = proto["identificationModule"]["briefTitle"]
    sponsor = proto["sponsorCollaboratorsModule"]["leadSponsor"]["name"]
    print(f"{nct}: {title} (sponsor: {sponsor})")

openFDA:药品标签 + FAERS 信号

import requests
from collections import Counter

# Drug label lookup
r = requests.get(
    "https://api.fda.gov/drug/label.json",
    params={"search": "openfda.brand_name:Lipitor", "limit": 1},
).json()
label = r["results"][0]
print("Indications:", label.get("indications_and_usage", ["—"])[0][:200])

# FAERS — most reported adverse events for atorvastatin
r = requests.get(
    "https://api.fda.gov/drug/event.json",
    params={
        "search": 'patient.drug.medicinalproduct:"ATORVASTATIN CALCIUM"',
        "count": "patient.reaction.reactionmeddrapt.exact",
        "limit": 10,
    },
).json()
print("Top reported reactions:")
for r_ in r["results"]:
    print(f"  {r_['term']}: {r_['count']}")

ChEMBL:靶点生物活性

import requests

# Target search → activity for a specific target
r = requests.get(
    "https://www.ebi.ac.uk/chembl/api/data/activity.json",
    params={
        "target_chembl_id": "CHEMBL204",      # PD-L1
        "standard_type": "IC50",
        "limit": 25,
    },
).json()
for a in r["activities"][:5]:
    cid = a["molecule_chembl_id"]
    val = a["standard_value"]
    unit = a["standard_units"]
    print(f"{cid}: IC50 = {val} {unit}")
import requests

r = requests.post(
    "https://www.apipick.com/api/search/clinical",
    headers={"x-api-key": "pk_yourkey"},
    json={"query": "PD-L1 inhibitors in NSCLC trials and adverse events"},
)
for hit in r.json()["results"][:5]:
    print(hit["title"], "→", hit["url"], f"(source: {hit.get('source')})")
# Returns ranked semantic matches across trials + labels + bioactivity.
# 30 credits per call, only on HTTP 200.

生产环境里常见的三种模式

1. 药物再利用筛查

拿一个已上市药物。拉它的机制(ChEMBL 靶点)、当前适应症(openFDA 标签),以及任何在新适应症上测试它的试验(ClinicalTrials.gov)。再和 FAERS 交叉比对,看新适应症下的安全信号。Agent 把这四块拼起来,把值得药理学家花时间看的候选项浮出来。

2. 药物警戒信号分诊

每小时一个 cron 拉取观察名单上药物的新 FAERS 报告。相对数据库其余部分计算报告比值比。标记任何 ROR > 2 且 95% 置信区间不含 1 的信号。配合 ClinicalTrials.gov 检查用药适应症是否在标签内。给团队输出一份排序列表供晨会评审 —— 类似新闻领域的晨报简报模式

3. AI 医疗助手的依据接地

对助手给出的任何药物相关回答,拉取 openFDA 标签,把它当作权威的事实依据。明确引用 FDA 标签的具体章节。当标签无法获取时,拒绝回答剂量相关的问题。这就是英国判例法那篇文章里的引用接地模式,套用到医学上 —— 而且赌注更高。

DrugBank 陷阱

值得再强调一遍。DrugBank 的学术授权广为人知,但它的条款在你为任何用到该数据的东西向任何人收费的那一刻就变了 —— 包括一个免费产品,只要你打算之后把它的用户转成付费。好几位小型 SaaS 创始人都是在律师函落进收件箱后才吃了这个亏。

两条干净的路:

  • 付商用授权费。标准定价不透明;做好谈判的准备。对有融资的成熟产品,这是正确答案,因为 DrugBank 的药物相互作用数据很难替代。
  • 早期阶段用授权干净的替代方案。ChEMBL 覆盖了大部分机制数据。RxNorm + DailyMed(NIH)覆盖药名规范化和标签。FAERS 覆盖不良事件。这套组合会缺一些 DrugBank 特有的数据(丰富的相互作用表、多药理学),但对大多数早期产品已经够用。API Pick Clinical Search 已经替你把授权干净的那部分包好了。

这套方法能推广到哪

「把四个公开数据库接到一起,处理好限流,守住授权纪律」这种模式在很多受监管的垂直领域都会出现 —— 金融申报(SEC + 财报电话会纪要 + 股票统计)、专利(USPTO + EPO + WIPO + JPO + KIPO + CNIPA)、法律(Find Case Law + legislation.gov.uk + 各国对应来源)。药物数据这一版之所以特殊,主要是因为授权的根基争议更大。其他每一个维度 —— schema 差异、限流、去重、跨源标识符映射 —— 都能推广。

想要一次调用就跨授权干净的药物数据源做检索,API Pick Clinical Search 帮你把线接好。对更深的集成(完整的 SPL 解析、FAERS 信号计算、ChEMBL 靶点树),你还是要直接去对应的源。为管线的每个部分挑对抽象层级。

常见问题

ClinicalTrials.gov v2 里有哪些变化会搞坏管线?

三处。(1) 端点结构 —— v2 是 REST + JSON,而非 v1 的 CSV/XML。(2) 字段命名 —— 新的 protocolSection 包装层,以及 snake_case 到 camelCase 的改动,是最常见的重构点。(3) 可选字段填充 —— 很多文档里标注「可用」的字段其实填充得很稀疏,老研究尤其如此。迁移通常要 2-3 天,再加上一周边角 case 研究冒出来时的修 bug 时间。

DrugBank 的授权到底是怎么回事?

DrugBank 对学术和个人研究免费。任何商业用途 —— 包括免费的 SaaS 产品、创业公司的 MVP,或付费咨询里用到的工具 —— 都落入 DrugBank 的商用授权条款。几年前 Thinklab 那篇 'Sounding the alarm on DrugBank's new license' 至今仍是这件事的权威综述。很多开发者在开发阶段接入了 DrugBank,没意识到一旦产品上线,授权就生效了。接入前先读条款,或者用一个授权干净的替代方案。

怎么做基础的药物警戒信号检测?

标准的失衡度量 —— 报告比值比(ROR)、比例报告比(PRR)、贝叶斯 BCPNN —— 跑在 FAERS 不良事件数据库上。像 vigipy 这样的开源库实现了这些。陷阱在于 FAERS 去重:很多报告是同一个病例由不同方重复提交的;像 WHO 的 VigiMatch 这样的库能处理,但要付费。对大多数医疗 AI 用例,openFDA 的 FAERS 端点加一个简单的 ROR 计算,就足以把值得深挖的信号筛出来。

API Pick Clinical Search 符合 HIPAA 吗?

我们封装的数据源(ClinicalTrials.gov、openFDA、ChEMBL、DrugBank 药理元数据)不含受保护健康信息 —— 它们覆盖的是试验方案、药品标签、不良事件汇总和结构/生物活性数据。HIPAA 合规针对的是 PHI,而 PHI 不出现在我们的索引里。如果你在构建一个下游产品确实会处理 PHI(比如基于患者病历的临床决策支持),那部分你得单独处理。流经我们端点的数据与公开监管数据一致。

它的输出能用于临床决策吗?

不能。任何检索 API 的输出都只是信息性的;它不构成医疗建议或临床决策支持。用这些数据去支持有资质的人员 —— 药师、医生、监管专员 —— 而不是替代他们。这一点适用于 API Pick Clinical Search,也适用于这个领域里任何其他 API。

本文涉及的 API

Sarah Choy
作者
Sarah Choy
CEO, API Pick

Sarah Choy 是 API Pick 的 CEO,专注于为 AI Agent 与 LLM 工作流构建可用于生产的 API。