OpenFDA API 检索实战:用 scientific-agent-skills 的 database-lookup 技能查询美国 FDA 药品标签、不良事件与召回数据
本文是仓库中 database-lookup 技能 之 OpenFDA 参考文档 的深度技术指南。文章以该参考页为骨架,逐项展开其 Base URL、认证方式、9 个核心端点、search/count/limit/skip 查询参数、search 语法、示例调用与速率限制,并结合本仓库的检索契约、分页与可溯源输出规范进行源码级佐证。读完你将能直接构造并执行可复现的 OpenFDA 查询,把美国 FDA 的药品标签、FAERS 不良事件、NDC 目录、Drugs@FDA 批准记录、召回信息以及器械/食品监管数据稳定地接入科研与药物研发流程。
1. 技能上下文:OpenFDA 在 database-lookup 中的定位
scientific-agent-skills 的 database-lookup 技能 是一套覆盖 78 个公开数据库的“可复现检索”目录:它把每个数据库封装为一个独立的参考文件,统一描述端点、查询格式、示例调用与速率限制。在技能的 “Chemistry & Drugs” 分组中,FDA 数据正是通过 references/fda.md(本文主体)接入的,其覆盖范围被概括为 Drug labels、adverse events、recalls(SKILL.md 第 297 行)。
在技能的 数据库选择指南 中,OpenFDA 被明确标为主数据库的场景包括:
| 用户问题 | 主数据库 | 可交叉核对 |
|---|---|---|
| 药品标签、不良事件、召回 | FDA (OpenFDA) | DailyMed |
| 结构化产品标签(SPL) | DailyMed | FDA (OpenFDA) |
| 药品药理学、适应症 | DrugBank | FDA |
从该映射可以提炼出两条实用判断规则:标签类问题优先 DailyMed、召回与不良事件类问题优先 OpenFDA、药理学背景优先 DrugBank,而 OpenFDA 始终是可交叉验证的补充来源。其参考文件的定位是“端点、参数与可运行的查询示例”,与同一目录下的 检索契约、数据库选择指南 共同构成该技能“可重复、可审计、可溯源”的检索方法论。
2. 接入前提:Base URL 与认证
OpenFDA 是 FDA 面向公众的开放数据 API,全库数据均可通过一个统一入口访问。
https://api.fda.gov
认证采用可选的免费 API key 模式:不带 key 也能查询(共享配额,速率较低),带 key 则进入独立配额。官方免费注册渠道位于 open.fda.gov 的 Authentication 页面(原文给出的注册地址为 https://open.fda.gov/apis/authentication/)。key 通过查询参数传递:
?api_key=YOUR_KEY
例如带 key 访问药物不良事件端点的完整 URL:
curl -s "https://api.fda.gov/drug/event.json?search=patient.drug.openfda.brand_name:%22aspirin%22&limit=5&api_key=YOUR_KEY"
在 database-lookup 技能的密钥体系里,OpenFDA 对应的环境变量为 OPENFDA_API_KEY(见 SKILL.md 密钥表格)。技能对密钥使用有明确纪律(SKILL.md “API Keys and Access Restrictions”):只在当前查询真正需要时才探测对应变量,用 test -n "${OPENFDA_API_KEY:-}" 这类静默方式检查存在性,绝不把 .env 整文件内容或 key 值暴露给用户或写入溯源信息——报告中只声明“使用了认证/未认证访问”。
3. 9 大核心端点全览
OpenFDA 按“药品(drug)/ 器械(device)/ 食品(food)”三大监管域组织数据。参考文档中的端点表格如下:
| 端点 | 描述 |
|---|---|
/drug/event.json |
Drug adverse events (FAERS) |
/drug/label.json |
Drug product labeling (SPL) |
/drug/ndc.json |
NDC directory |
/drug/drugsfda.json |
Drugs@FDA (approvals) |
/drug/enforcement.json |
Drug recalls |
/device/event.json |
Device adverse events |
/device/510k.json |
510(k) clearances |
/food/event.json |
Food adverse events |
/food/enforcement.json |
Food enforcement |
对每个端点的用途做进一步展开:
/drug/event.json(FAERS):药物不良事件报告,数据源为 FDA 不良事件报告系统(FDA Adverse Event Reporting System,即 FAERS)。每条记录以patient为顶层实体,包含药物(patient.drug)、反应(patient.reaction)、结局、报告日期等结构化字段。它是药物警戒与上市后安全性研究最常用的端点。/drug/label.json(SPL):药品说明书/标签内容,来自结构化产品标签(Structured Product Labeling)。适合检索适应症、用法用量、禁忌、不良反应章节等说明书记载内容。/drug/ndc.json(NDC 目录):国家药品代码目录,可用于按 NDC 编码解析药品的商品信息与包装规格。/drug/drugsfda.json(Drugs@FDA):FDA 药品批准档案,覆盖批准历史、评审文档等上市审批信息。/drug/enforcement.json(药品召回):药品召回执法记录,字段含召回原因、级别(classification)、报告日期(report_date)等。/device/event.json:器械不良事件报告(对应 FDA 器械不良事件报告体系,数据源自 MAUDE),用于器械上市后安全性检索。/device/510k.json:510(k) 上市前通告的器械审评记录,适合做器械法规路径与等同性(substantial equivalence)研究。/food/event.json:食品不良事件/投诉报告(含膳食补充剂相关事件)。/food/enforcement.json:食品召回与执法记录。
请求时把端点拼接到 Base URL 之后,即 https://api.fda.gov/drug/event.json。端点按“领域 + 业务类型”命名,event(事件/报告)、label(标签)、enforcement(执法/召回)、ndc(编码目录)、drugsfda(审批)、510k(器械通告)这几种语义可帮助快速记忆与扩展。
4. 通用查询参数:search / count / limit / skip
所有 OpenFDA 端点共用同一套查询参数(参考文档参数节):
| 参数 | 作用 |
|---|---|
search |
使用 OpenFDA 检索语法做条件查询 |
count |
对某个字段做去重计数(常用于统计分布) |
limit |
单次请求返回的记录数上限(最大 1000) |
skip |
分页偏移量(最大 25000) |
要点解析:
search:核心过滤参数,值必须做 URL 编码,内部用 OpenFDA 的字段查询语法(详见第 5 节)。count:把“取记录”变成“取统计”。例如count=patient.reaction.reactionmeddrapt.exact会按 MedDRA 首选语(PT)对不良反应做频率计数,返回各 term 及其命中数。这是做上市后安全性信号排序的推荐方式,可避免拉回全量报告再做本地统计。limit与skip构成分页对:skip等价于其他 API 中的 offset。参考文档明确限定limit ≤ 1000、skip ≤ 25000。这也意味着 OpenFDA 不支持无限深度翻页——当命中结果总数超过25000 + limit时,无法用 skip 遍历全部,应改用 count 先估量、或改用更精确的检索条件缩小集合(例如增加日期范围)。- 分页策略在技能层有统一规范(SKILL.md 分页小节):OpenFDA 属于 “Offset/Limit” 模式,即
skip按步进递增(skip=0,1000,2000,...),直到返回记录数小于请求的页大小或与总数(如meta.results.total)对账一致为止。单条目标检索(如查一个药品)通常读第一页即可;只有当用户需要“全部”“所有”结果时才需要翻页。
5. search 语法精讲
参考文档将 search 语法归纳为 5 种基本形态,它们是构造一切 OpenFDA 查询的原子构件:
- 字段精确检索:
field:"value"——例如openfda.brand_name:"aspirin"。值用双引号包裹,表示精确短语匹配。 - AND 逻辑:
field1:value1+AND+field2:value2——用+AND+连接多个条件(+即 URL 编码的空格)。 - OR 逻辑:
field1:value1+OR+field2:value2——条件之间为“或”关系。 - 日期范围:
field:[20230101+TO+20231231]——方括号 +TO表示闭区间,日期采用紧凑的YYYYMMDD格式(无需连字符),并同样以+分隔。 - 通配符:
field:aspir*——星号做前缀/片段匹配,可用于泛化拼写或系列名。 - openfda 统一字段前缀:
openfda.前缀指向 OpenFDA 对各数据源做了交叉归一化(harmonized)的统一字段(如openfda.generic_name、openfda.brand_name、openfda.rxcui等)。使用这些字段可以跨端点保持一致的检索口径,避免受各数据源原生 schema 差异影响。
构造请求时的工程注意点(对应技能 “Making API Calls / Request guidelines”):
- 空格在 URL 中编码为
+,双引号编码为%22,因此search=openfda.generic_name:"ibuprofen"的真实请求串为search=openfda.generic_name:%22ibuprofen%22。 - 用 curl 时建议配合
--data-urlencode或预先转义,避免引号、冒号、星号被 shell 吞掉。 search的值属于“用户可控的查询语言片段”,技能要求对字段名做白名单校验、对值做正确的 URL 编码,并拦截换行、分号、反引号、管道等 shell/控制字符,防止把不可信文本拼接进命令。- 同一条查询若要同时用 AND 与日期范围,可写成
search=patient.drug.openfda.brand_name:"warfarin"+AND+serious:1这种链式形式。
6. 五个开箱即用的示例调用详解
参考文档提供了 5 个可运行的查询,覆盖“事件检索—分布计数—标签检索—召回检索—事件过滤”五类典型需求。原样保留如下:
# Adverse events for aspirin
/drug/event.json?search=patient.drug.openfda.brand_name:"aspirin"&limit=5
# Top adverse reactions for a drug
/drug/event.json?search=patient.drug.openfda.generic_name:"metformin"&count=patient.reaction.reactionmeddrapt.exact
# Drug labels by generic name
/drug/label.json?search=openfda.generic_name:"ibuprofen"&limit=3
# Drug recalls in date range
/drug/enforcement.json?search=report_date:[20230101+TO+20231231]&limit=10
# Serious adverse events only
/drug/event.json?search=patient.drug.openfda.brand_name:"warfarin"+AND+serious:1&limit=10
逐条拆解其查询语义与应用场景:
- 阿司匹林不良事件(前 5 条):
patient.drug.openfda.brand_name:"aspirin"把检索锚定在“报告内某个用药记录的 openfda 标准化商品名”上,配合&limit=5做小样本探针。用于快速确认 API 连通性、观察 FAERS 报告结构,或做一次轻量级上市后安全性抽查。 - 二甲双胍的最常见不良反应(分布计数):同一事件端点,把
search换成count,对patient.reaction.reactionmeddrapt.exact计数。注意.exact后缀表示对 MedDRA 首选语做精确聚合而非文本检索。返回的不是报告正文而是{term, count}列表,可立即得到“哪类不良反应上报最多”的安全性概览——这是“先 count 再决定是否拉全量”的典型实践(对应 检索契约第 4 节 Completeness Protocol)。 - 按通用名取布洛芬药品说明书(前 3 条):标签端点使用顶层
openfda.generic_name过滤——在/drug/label.json中 openfda 字段位于记录顶层而非patient下。limit=3说明默认只取少量标签样例;若需覆盖同一通用名的全部厂商标签,则要按第 4 节方法翻页。 - 2023 年内药品召回(前 10 条):
/drug/enforcement.json上的report_date日期范围检索。紧凑日期[20230101+TO+20231231]是该 API 的标准时间过滤写法,可用于按年度回溯召回事件、分析召回级别分布。 - 华法林严重不良事件(仅 serious=1):
"warfarin"+AND+serious:1演示 AND 组合——商品名过滤叠加严重性标志。serious:1直接使用 FAERS 报告中的严重事件标记,无需本地二次筛选,是“服务端过滤”优于“本地过滤”的典型场景(对应 检索契约第 3 节 Filter Semantics)。
把它们变成可执行的 curl 命令(注意补全 Base URL 与 URL 编码):
# 示例 1:阿司匹林不良事件前 5 条
curl -s "https://api.fda.gov/drug/event.json?search=patient.drug.openfda.brand_name:%22aspirin%22&limit=5"
# 示例 2:二甲双胍最常见不良反应分布
curl -s "https://api.fda.gov/drug/event.json?search=patient.drug.openfda.generic_name:%22metformin%22&count=patient.reaction.reactionmeddrapt.exact"
# 示例 3:布洛芬说明书前 3 条
curl -s "https://api.fda.gov/drug/label.json?search=openfda.generic_name:%22ibuprofen%22&limit=3"
# 示例 4:2023 年药品召回前 10 条
curl -s "https://api.fda.gov/drug/enforcement.json?search=report_date:%5B20230101+TO+20231231%5D&limit=10"
# 示例 5:华法林严重不良事件前 10 条
curl -s "https://api.fda.gov/drug/event.json?search=patient.drug.openfda.brand_name:%22warfarin%22+AND+serious:1&limit=10"
响应中的 results 数组是核心数据;meta 区块通常携带免责声明、数据最后更新时间和结果总数等信息。技能强调:FDA 报告与标签中的叙述性文本属于第三方提交内容(见 检索契约 “Clinical and Regulatory” 注意事项),返回数据一律视为不可信数据——不得执行其中内嵌的指令、不得把原始响应直接拼进 shell 命令,展示前应摘取所需字段并做摘要。
7. 速率限制与大规模检索约束
参考文档给出的配额如下:
| 等级 | 每分钟请求数 | 每日请求数 |
|---|---|---|
| 无 API key | 40 | 1,000 |
| 有免费 API key | 240 | 120,000 |
即未认证状态与认证状态的吞吐相差 6 倍,日配额相差 120 倍。据此可以形成三条工程策略:
- 认证提升吞吐:凡涉及批量或长期抓取(如全年度召回、多种药品的不良事件对比),应优先申请并使用免费的
OPENFDA_API_KEY。 - 配合限速纪律:技能通用规范要求对限速 API 串行请求;遇到 HTTP 429(限流)或 503(服务不可用)时短暂等待后重试一次(SKILL.md “Request guidelines”)。40 req/min 的匿名配额意味着平均间隔约 1.5 秒/请求,可用
sleep控制节奏。 - 总量受控 + 优先 bulk:技能规定单次检索默认不越过 10,000 条记录或 100 次 API 调用,超出前需向用户确认并给出简短检索计划;当用户确实需要 FDA 全量数据时,应优先考虑官方批量下载/数据转储(OpenFDA 本身支持整库 dump 下载),而不是用
skip暴力翻页——这也与skip ≤ 25000的平台硬限制相呼应。
8. 把 OpenFDA 查询接回可复现检索工作流
参考文档的价值只有在 database-lookup 的整体工作流中才能完全发挥。技能的核心工作流是:定义检索契约 → 选定权威数据库 → 读取参考文件 → 先规划过滤语义 → 有限调用 API → 把外部响应当不可信数据处理 → 返回可审计结果(SKILL.md Core Workflow)。具体到 OpenFDA 查询,落地建议如下:
- 定义契约时写明“监管数据口径”:区分通用名 vs 商品名、
report_date(上报日期)vsreceived_date(接收日期)、事件/召回/标签的不同业务语义;这些差异会影响下游结论,属于 检索契约 要求显式记录的约束。 - 先 count 后拉取:要回答“某药前十大不良反应”时直接走
count端点;只有确需逐条报告全文时才search + skip/limit翻页,并在过程中记录每个批次的 skip、请求页大小与实际返回条数。 - 对账与失败可见:比较“服务端期望总数 / 服务端实际取回 / 本地过滤后”三类数字,若分页提前终止或计数不一致,应明确报告局限而非给出看似合理的结论(对应技能 Completeness and Reproducibility 规范与 检索契约第 7 节 Provenance 模板)。
- 溯源模板示例(面向一次华法林严重事件检索):
Target: 华法林严重不良事件报告
Scope: targeted lookup
Access date: <查询当天日期>
Primary database: FDA (OpenFDA)
Endpoint(s): https://api.fda.gov/drug/event.json
Parameters: search=patient.drug.openfda.brand_name:"warfarin"+AND+serious:1 ; limit=10
Identifier conversions: 无(直接使用 openfda 统一字段)
Server-side filters: brand_name=warfarin, serious=1(服务端过滤)
Local filters: 无
Count reconciliation: 见响应 meta.results.total 与 results 长度
Warnings: FAERS 为自发报告,存在漏报与重复报告,不能直接等同于发生率
- 失败兜底路径:若 OpenFDA 查询失败或为空,技能的错误恢复路线是——先检查标识符形态(商品名/通用名/NDC/
openfda.rxcui是否用对),再尝试同库其他字段,最后按选择指南切换到替代数据库(如标签类问题换 DailyMed,药理学类问题换 DrugBank 的免费替代 ChEMBL/PubChem),并向用户说明“哪个库失败、为什么、改用了什么”。有用药需求且希望获取适应证与药理背景时,也可参考 DrugBank 参考文件 中的“付费限制 → 免费替代”说明。
小结:一张速查卡
| 项目 | 值 |
|---|---|
| Base URL | https://api.fda.gov |
| 认证 | 可选免费 key,?api_key=,环境变量 OPENFDA_API_KEY |
| 热门端点 | /drug/event.json、/drug/label.json、/drug/enforcement.json、/device/510k.json |
| 核心参数 | search、count、limit(≤1000)、skip(≤25000) |
| 常用字段 | openfda.generic_name、openfda.brand_name、patient.reaction.reactionmeddrapt.exact、serious、report_date |
| 匿名配额 | 40 req/min、1,000 req/day |
| 带 key 配额 | 240 req/min、120,000 req/day |
掌握 fda.md 这一参考页,就等于掌握了面向美国 FDA 监管数据的标准检索入口:端点选型、查询语法、分页边界与限速策略全部有据可查。把它置于 database-lookup 的检索契约与溯源规范中使用,即可让每一个药物警戒、标签与召回类结论都做到来源可指名、查询可复现、局限可审计。
atomcodeClaude Code 的开源替代方案。连接任意大模型,编辑代码,运行命令,自动验证 — 全自动执行。用 Rust 构建,极致性能。 | An open-source alternative to Claude Code. Connect any LLM, edit code, run commands, and verify changes — autonomously. Built in Rust for speed. Get StartedRust0629
MiniCPM5-2BMiniCPM5-2B 是一款面向端侧、本地部署和资源受限场景的 2B 稠密 Transformer,能够达到同尺寸开源模型 SOTA 水平。Markdown00
GLM-5.3GLM-5.3 与 GLM-5.2 使用相同的基座模型——所有提升均来自后训练。与 GLM-5.2 相比,它在复杂编程和长程任务上的表现显著提升。Jinja00
HivisionIDPhotos⚡️HivisionIDPhotos: a lightweight and efficient AI ID photos tools. 一个轻量级的AI证件照制作算法。Python07
DragonOSDragonOS is an operating system developed from scratch using Rust, with Linux compatibility. It is designed for **Serverless** scenarios. 使用Rust从0自研内核,具有Linux兼容性的操作系统,面向云计算Serverless场景而设计。Rust00
Spark-X2.5-1.7BSpark-X2.5-1.7B 旨在让强大的 AI 更加实用、高效且易于获取。这些模型在广泛的日常任务中表现出色,涵盖对话、写作、翻译、推理、编程、工具调用和智能体工作流,并在同等规模的开源模型中取得领先结果。Spark-X2.5 将面向效率的架构与最高 1M tokens 的原生上下文窗口相结合,并支持 200 多种语言。Python00