Try it free in the sandbox · first FHIR call in 5 minutesFree · 30 synthetic patients · no card
应用程序和 AI 代理的药物数据
患者用药列表与药物知识:FHIR 资源、RxNorm、ATC、openFDA 和 EMA 来源,以及 FHIR 记录与 RxNorm 和 FDA 标签的已测试连接。
医疗软件需要两种不同类型的药物数据:患者的用药列表——这个人服用什么药物,从何时开始,剂量如何,由谁记录——以及药物知识——产品包含什么,其官方标签,警告和相互作用。 前者属于患者记录;后者来自权威药物数据库。混淆它们会导致 AI 代理从模型记忆中陈述药物事实。本页将解释这两者,涉及的 FHIR R4 资源和代码系统,美国和欧盟存在的公共数据源,以及一个将 FHIR 记录中的患者列表与 RxNorm 和 FDA 标签联合的有效示例。
两种药物数据
| 患者用药列表 | 药物知识 | |
|---|---|---|
| 回答 | Ana 正在服用什么药物,从什么时候开始,多久一次? | 什么是二甲双胍 500 毫克,其标签有什么警告? |
| 变更 | 当患者或临床医生更新时 | 当监管机构或发布者更新时 |
| 存储位置 | 患者记录(EHR、PHR、FHIR 服务器) | 药物数据库和术语集 |
| FHIR | MedicationStatement、MedicationRequest、MedicationAdministration、Medication |
大部分在记录之外;产品信息本身可以是 FHIR |
| 谁可以读取 | 仅在获得患者同意后 | 公开或已授权 |
一个回答“我是否可以与我的降压药一起服用布洛芬?”的应用程序或代理需要两者:患者的列表以了解服用的是哪种药物,以及药物知识来源以了解有关该组合的已知信息——再加上临床医生或药剂师来给出答案。
药物列表的 FHIR 资源
- MedicationStatement:患者正在服用、已服用或已停用的药物(患者报告或由临床医生记录)。通常用于 PHR 或核对列表的资源。
- MedicationRequest:处方或医嘱。
- MedicationAdministration:已服用或已给予(或跳过)的一剂药物,用于依从性分析。
- Medication:药物产品本身,当需要比代码更多的详细信息时(成分、剂型、批次)。
药物通过代码进行编码:在美国使用 RxNorm(来自美国国家医学图书馆)和 NDC 产品代码;国际上使用 WHO ATC 分类;在欧洲也使用国家产品代码,并且越来越多地使用 EMA 的基于 FHIR 的电子产品信息。一个声明可以携带同一种药物的多个编码。
药物知识来源
美国
- RxNorm API (NLM): 临床药物的标准化名称和标识符 (RXCUI);免费,除一项例外,无需许可。
- openFDA drug label API (FDA): 结构化的产品标签 — 适应症、黑框警告、禁忌症、药物相互作用部分 — 可通过 RXCUI 进行搜索。
- DailyMed (NLM): 供人们阅读的相同标签。
欧洲联盟
- 欧洲药品管理局发布了集中授权药品的上市许可信息,其电子上市许可信息 (ePI) 基于 FHIR 构建。国家授权的产品存在于国家注册表中。
- ATC 代码和标准日剂量由世界卫生组织药物统计方法合作中心维护。
相互作用是最难的部分。NLM 于 2024 年 1 月左右停用了其药物相互作用 API,而如今全面的相互作用检查依赖于获得许可的临床知识库。标签的相互作用部分是为临床医生编写的文本,而不是用于检查的工具。
关联记录与药物知识
该示例从 Anpheros 读取患者的活动用药,将每个名称解析为 RxNorm 概念,并获取 FDA 标签。它在平台的本地实例以及实时的 RxNorm 和 openFDA API 上运行。
import { Anpheros, apiKey } from '@anpheros/sdk';
const anpheros = new Anpheros({ auth: apiKey(process.env.ANPHEROS_KEY!) });
// 1. What the person takes: from their record (ATC codes, names as they were entered)
const { data: meds } = await anpheros.medications.list(patientId, { status: 'active' });
// 2. What each medicine is: RxNorm (US National Library of Medicine), free, no key
async function rxcui(name: string): Promise<string | null> {
const r = await fetch(`https://rxnav.nlm.nih.gov/REST/approximateTerm.json?term=${encodeURIComponent(name)}&maxEntries=1`);
const j: any = await r.json();
const id = j.approximateGroup?.candidate?.[0]?.rxcui;
if (!id) return null;
// An approximate match can be an outdated concept: keep it only if RxNorm still describes it as a drug
const props: any = await (await fetch(`https://rxnav.nlm.nih.gov/REST/rxcui/${id}/properties.json`)).json();
return ['SCD', 'SBD', 'GPCK', 'BPCK'].includes(props.properties?.tty) ? id : null;
}
// 3. What the official label says: openFDA drug label API (US FDA), free
async function label(id: string) {
const r = await fetch(`https://api.fda.gov/drug/label.json?search=openfda.rxcui:%22${id}%22&limit=1`);
if (!r.ok) return null;
const doc: any = (await r.json()).results?.[0];
return doc && { set_id: doc.set_id, boxed_warning: doc.boxed_warning?.[0]?.slice(0, 120), has_interactions_section: !!doc.drug_interactions };
}
for (const m of meds) {
const id = await rxcui(m.display);
console.log(JSON.stringify({ record: { display: m.display, atc: m.code, dosage: m.dosage }, rxnorm: id, fda_label: id ? await label(id) : null }));
}
一位报告了二甲双胍和依那普利患者的输出:
{"record":{"display":"Metformin 500 mg tablet","atc":"A10BA02","dosage":"500 mg twice a day"},"rxnorm":"861007",
"fda_label":{"set_id":"011de1a5-…","boxed_warning":"BOXED WARNING WARNING: LACTIC ACIDOSIS …","has_interactions_section":true}}
{"record":{"display":"Enalapril maleate 10 mg oral tablet","atc":"C09AA02","dosage":"10 mg once a day"},"rxnorm":"858817",
"fda_label":{"set_id":"074fe718-…","boxed_warning":"WARNING: FETAL TOXICITY …","has_interactions_section":true}}
运行中我们学到的经验。 当名称写为“Enalapril 10 mg tablet”时,RxNorm 的近似匹配返回了 RXCUI 328290,这是一个 RxNorm 不再描述的概念,没有与之关联的标签。使用完整的临床名称“enalapril maleate 10 mg oral tablet”时,它返回了 858817,这是一个当前有标签的临床药物。人们输入的名称是近似的;请检查匹配项解析到的内容,一旦确认就存储代码,并向用户展示匹配的内容。
AI 代理的规则
- 绝不允许模型从内存中提供药物事实。 提供患者的记录列表和权威来源的相关文本,并要求其引用。
- 保持两个来源可见。 “您服用二甲双胍(您的记录,您于 3 月 3 日录入)”和“FDA 标签警告乳酸性酸中毒(标签集 011de1a5…)”是具有不同所有者的不同声明。
- 缩小范围。 只需要药物列表的代理应获得
MedicationStatement的读取访问权限,而不是整个记录。使用 Anpheros,这可以通过授权范围或 MCP 服务器的只读工具来实现。 - 不要回答需要临床医生才能回答的问题。 药物相互作用、剂量调整和停药应咨询药剂师或医生;代理可以准备问题。
Anpheros 的定位
Anpheros 存储了用药列表:MedicationStatement 和 MedicationAdministration(包含 ATC 或其他代码)、记录每项的个人、历史记录以及其他应用的授权信息;上下文 API 在为模型准备的摘要中包含当前用药信息,而 MCP 服务器 以只读方式向代理公开这些信息。它包含一个小的 ATC 子集(约 50 种常用药物)以自动命名代码;任何其他代码均被接受,但没有自动命名。
它不是药物数据库:它不提供药品标签、药物相互作用、剂量或禁忌症信息,并且目前不支持 MedicationRequest 或 Medication 资源。
常见问题解答
哪个 FHIR 资源应该用于药物列表?
MedicationStatement 用于记录一个人正在服用或曾经服用过的药物,包括患者报告的药物。处方是 MedicationRequest;单个剂量是 MedicationAdministration。
有免费的药物数据库 API 吗?
在美国,RxNorm (NLM) 提供药物标识符和名称,openFDA 提供官方产品标签,这些都是免费的。在欧洲,EMA 和各国机构会发布产品信息。全面的药物相互作用检查通常需要一个授权的知识库。
AI 代理应如何获取药物信息?
通过两个工具:一个工具在获得同意后读取患者记录中的药物列表,另一个工具查询权威的药物来源。代理应引用两者,并将临床决策留给专业人士。
Anpheros 是否检查药物相互作用?
否。它存储一个人正在服用的药物,并附带来源和同意信息。药物相互作用检查属于药物知识来源和临床医生的职责。
相关
Try it free in the sandbox · first FHIR call in 5 minutesFree · 30 synthetic patients · no card