Nmpa drug registry lookup
Skill EthanYoQ/Skill-hub/skills/06-data-search/nmpa-drug-registry-lookup
Reusable AI agent skills for Codex, Claude Code etc. — AI coding workflows, SKILL.md templates, and automation practices. 面向 Codex、Claude Code等agents 的可复用 AI Agent Skill 技能库:AI 编程工作流、SKILL.md 模板与自动化实践。
npx -y skills add EthanYoQ/Skill-hub --skill nmpa-drug-registry-lookupAssembled from the repository path, not quoted from the project. Check it against their README if it does not work.
One thing to look at
- 4 stars4 stars. Stars are a popularity signal and not a quality one, but at this level it is likely that nobody has read this closely except its author, and you would be relying on your own review.
What its author says it does
Copied from the file, not written here
中国药品权威数据库查询 — NMPA(国家药监局) + CDE(药品审评中心) + DrugBank(英文名/ATC) + PubChem(化学结构) 多源融合,提供(通用名 ↔ 商品名 ↔ 英文名 ↔ 适应症 ↔ NMPA 批文号 ↔ 上市日期)精确映射。Make sure to use this skill whenever the user mentions 药品名 / 通用名 / 商品名 / NMPA / 国药准字 / 药监局 / CDE / drug brand name / generic name / drug registry / pharmaceutical lookup / drug verification / 药物核验 / 商品名对应 / drug cross-check / drug authority lookup. 在任何 medical / market-sizing / clinical / disease-research 报告生成阶段,**所有药品提及必须先调 lookup_drug() 验证**,严禁 LLM 凭训练记忆拼凑通用名↔商品名↔英文名对应关系。LLM 训练截止后药企会更换商品名、新药持续上市,记忆完全不可信。Iron Law:lookup 返回 None → 调用方必须 raise UnverifiedDrugError,不允许 fallback 到记忆。免费公开数据源,跨平台:Claude Code / Codex / Gemini CLI 三端均可 auto-trigger,实现仅依赖 httpx + beautifulsoup4 标准生态,不绑定任何厂商 SDK。
The file declares its own license as MIT. That is the author’s claim about this one file, and it is not the same thing as the license GitHub reports for the repository, which is listed with the other numbers below.
SKILL.md
11.7 KB, as published. Nobody here has run it
nmpa-drug-registry-lookup · 中国药品权威 Registry
一句话定义
中国市场所有报告里的药品提及,都从此 skill 拿权威记录(NMPA + CDE + DrugBank + PubChem 多源融合);LLM 不允许凭记忆改写药品名。
Iron Law(违反此条 = 报告作废)
任何写入报告的药品名(通用名 / 商品名 / 英文名),必须通过 lookup_drug() 验证。
LLM 不允许凭训练记忆拼凑通用名↔商品名↔英文名对应关系 — 因为:
- 药企会更换商品名(如同一通用名在不同厂家有多个商品名)
- 新药持续上市,LLM 训练截止日期之后的数据完全不可信
- 中国市场命名经常与全球市场不同(如:Lorlatinib 中国商品名"博瑞纳",国外"Lorbrena")
- 一个药名错位 = 整份报告地基塌方(治疗推荐错 / GRADE 错 / LP 错 / 市场份额测算错)
唯一允许的姿势:
from nmpa_drug_registry_lookup.scripts.registry import lookup_drug, UnverifiedDrugError
rec = lookup_drug("洛拉替尼")
if rec is None:
raise UnverifiedDrugError("洛拉替尼 not in NMPA registry — refuse to write to report")
# 报告里写药名时,通用名和商品名都从 record 取,不要手输
generic_zh = rec.generic_name_zh # "洛拉替尼"
generic_en = rec.generic_name_en # "Lorlatinib"
brand_zh = rec.brand_names_zh[0] # "博瑞纳"
绝不允许:
# 错误!LLM 凭记忆
report_html += "<p>洛拉替尼(商品名:赛可瑞)...</p>" # 赛可瑞实际是克唑替尼!
report_html += "<p>布加替尼(商品名:博瑞纳)...</p>" # 博瑞纳实际是洛拉替尼!
何时调用
- 任何报告生成阶段(market-sizing / 治疗方案 / 决策树 / 市场份额测算)涉及具体药品名
- 用户问"X 药的通用名是什么?"、"Y 药什么时候在中国上市?"、"Z 药 NMPA 批文号是多少?"
medical-evidence-grading/disease-market-sizing-orchestration调用方需要药名锚定- 报告生成完毕,跑
cross_check_drug_mentions()全文扫描,catch LLM 偷偷凭记忆改写的药名
何时不调用
- 文献检索本身(给 PubMed query 时)— 不需要,query 自由文本即可
- 询问药物机制 / 靶点(用
pubtator-entity-search抓基因/通路) - 询问临床试验状态(用
clinical-trials-v2)
与其他 skill 的协作关系
┌─ pubmed-eutils(召回主力)
召回层 ───┬─────────────┤
│ └─ europepmc-search
│
│ ┌─ cn-clinical-guidelines-fetch(指南权威)
权威层 ───┼─────────────┤
│ └─ ★ nmpa-drug-registry-lookup(本 skill · 药品权威)
│
▼
报告生成层 ─── 所有药品名引用 → lookup_drug() / cross_check_drug_mentions()
调用顺序:
- orchestration 解析疾病 → fetch_chinese_guidelines() 拿指南治疗推荐表
- 用指南里提到的药品 → lookup_drugs_batch() 建立本疾病 drug_registry.json
- 报告生成时所有药品名引用从 drug_registry.json 取(LLM 禁止改写)
- 报告草稿出来 → cross_check_drug_mentions(html) 全文扫描,critical 严重性 → raise
核心函数签名
from dataclasses import dataclass
from pathlib import Path
@dataclass(frozen=True)
class DrugRecord:
"""中国药品权威记录。frozen 防止 LLM 修改。"""
generic_name_zh: str # 通用名(中文,首选 NMPA 命名)
generic_name_en: str # 通用名(英文,DrugBank/INN)
brand_names_zh: tuple[str, ...] # 商品名列表(中国市场,可能多个生产厂家)
brand_names_en: tuple[str, ...] # 商品名列表(全球)
nmpa_approval_no: str # NMPA 批准文号(如 国药准字 H20180123 / 进 J20180012)
first_approval_date_cn: str # 中国首次上市日期 ISO yyyy-mm-dd
indications_cn: tuple[str, ...] # 适应症(中文)
atc_code: str # ATC 分类(如 L01ED05 = 抗肿瘤 ALK 抑制剂)
target: str # 靶点(对靶向药,如 "ALK")
drug_class: str # 类别(如 "三代 ALK-TKI")
sources: tuple[str, ...] # 来源 URL,可追溯
class UnverifiedDrugError(Exception):
"""lookup 失败时调用方应 raise — 拒绝写入报告。"""
def lookup_drug(
name: str, # 任意名称(通用/商品/英文,模糊匹配)
market: str = "CN",
cache_dir: Path | None = None,
) -> DrugRecord | None:
"""单药查询。匹配优先级:
1. 已知 fallback dict 精确命中(NMPA 网站抓不到时的兜底)
2. NMPA 精确通用名
3. NMPA 商品名
4. DrugBank generic_name
5. PubChem 化学名 fallback
None = 该药不在权威数据库 → 调用方必须 raise UnverifiedDrugError。
"""
def lookup_drugs_batch(
names: list[str],
market: str = "CN",
cache_dir: Path | None = None,
) -> dict[str, DrugRecord | None]:
"""批量查询。返回 {name: DrugRecord or None}。"""
def cross_check_drug_mentions(
text: str, # 报告 HTML / Markdown 草稿
market: str = "CN",
cache_dir: Path | None = None,
) -> dict:
"""扫描文本里所有疑似药品名,逐个 lookup,返回错误清单。
Returns:
{
"ok": bool,
"verified_drugs": [...], # 命中权威数据库的药名
"unverified_drugs": [...], # 在数据库找不到 → 必须修
"name_mismatches": [ # 通用名/商品名混用错位(critical)
{"text_uses": "赛可瑞", "claimed_as": "洛拉替尼",
"actual_generic": "克唑替尼", "evidence_source": "NMPA"},
...
],
"violation_severity": "none" | "warning" | "critical",
}
严重性规则:
- 任何 name_mismatches 非空 → critical(LLM 把 A 药写成 B 药商品名)
- 仅 unverified_drugs 非空 → warning(可能是新药 / 仿制名)
- 全部 verified → none
"""
数据源(免费公开)
| 来源 | 提供 | 抓取方式 |
|---|---|---|
NMPA 国家药监局 (nmpa.gov.cn) | 通用名 / 批文号 / 适应症 / 上市时间 (权威 I 级) | REST + WebFetch + bs4 |
CDE 药品审评中心 (cde.org.cn) | 临床试验阶段 / 适应症详情 | WebFetch |
| DrugBank(免费学术) | 英文名 / ATC code / mechanism | API / scrape |
| PubChem(NIH) | 化学结构 / IUPAC / 同义词 | REST(pug.ncbi.nlm.nih.gov/rest/pug) |
| NCBI Gene | 靶点基因(已通过 pubtator-entity-search 间接) | 复用 |
fallback 兜底:NMPA 网站反爬严重时,scripts/_known_drugs_fallback.py 含一份手工核验的常用药字典,每条都有 NMPA 公开页 URL 引用作来源。
失败模式(8 条)
| # | 症状 | 原因 | 修复 |
|---|---|---|---|
| 1 | lookup 返回 None | 药品不在 NMPA(可能仿制名 / 进口未上市 / 拼写错) | 让用户确认是否仍写入,标 unverified;不允许 LLM 凭记忆补 |
| 2 | 同一通用名多个商品名 | 多厂家(如阿仑膦酸钠) | brand_names_zh 列出全部,不要任选一个 |
| 3 | 通用名↔商品名错位(LLM 偷偷脑补) | LLM 训练截止后数据老化 | cross_check_drug_mentions 全文扫描,critical 级 raise |
| 4 | NMPA 网站抓取失败(反爬) | nmpa.gov.cn 改版 / 验证码 | 降级:cache → fallback dict → 报错 |
| 5 | 同一英文名对应多个中文音译 | 早期未规范化 | NMPA 通用名为唯一权威,其他作 alias |
| 6 | DrugBank 拒绝学术抓取 | 反爬升级 | 该字段标 None,不阻塞主流程(NMPA 字段是必需) |
| 7 | LLM 在 prompt 里"脑补"通用名 | 训练数据过时 | 任何 grade_evidence / LP 阶段都强制 lookup,不接受 LLM 直出 |
| 8 | 进口药批文号格式 vs 国产不同 | NMPA 编号规则:H/J/Z/S 前缀 | 不要自行拆解,作为 opaque string 存储 |
跨平台
- Python: 3.10+(用 PEP 604
X | None类型注解) - 依赖:
httpx,beautifulsoup4, 可选pypdf(适应症附件解析) - 测试:
python -m pytest(Windows 用C:\Python3\python.exe -m pytest,不要用python3stub) - Windows GBK 终端兼容: 测试入口加
sys.stdout.reconfigure(encoding="utf-8") - Cache: JSON 文件
<cache_dir>/drug_registry.json,TTL 7 天;SQLite 是 future work - 不联网测试: 测试用
tests/fixtures/nmpa_responses/*.html预录制响应,绝不在 CI 里直连 NMPA
调用方典型用法
A. 单药 lookup
from nmpa_drug_registry_lookup.scripts.registry import lookup_drug, UnverifiedDrugError
rec = lookup_drug("洛拉替尼")
if rec is None:
raise UnverifiedDrugError("洛拉替尼 not in NMPA registry — refuse to write to report")
print(rec.generic_name_en) # "Lorlatinib"
print(rec.brand_names_zh) # ("博瑞纳",)
print(rec.atc_code) # "L01ED05"
print(rec.first_approval_date_cn) # "2022-04-29"
B. 批量预热(orchestration 在 Step 0b 调)
from nmpa_drug_registry_lookup.scripts.registry import lookup_drugs_batch
key_drugs = ["克唑替尼", "阿来替尼", "塞瑞替尼", "恩沙替尼",
"布加替尼", "洛拉替尼", "伊鲁阿克", "依奉阿克"]
results = lookup_drugs_batch(key_drugs)
missing = [d for d, r in results.items() if r is None]
if missing:
raise UnverifiedDrugError(f"NMPA registry missing: {missing}")
# 写入 .cache/<slug>/drug_registry.json,后续报告生成阶段 LLM 必须从此取
C. 报告生成完毕全文扫描
from nmpa_drug_registry_lookup.scripts.registry import cross_check_drug_mentions
result = cross_check_drug_mentions(report_html)
if result["violation_severity"] == "critical":
# LLM 把 A 药写成 B 药商品名 — 必须重生成
raise OrchestrationError(f"drug name mismatches: {result['name_mismatches']}")
elif result["violation_severity"] == "warning":
# 仅有 unverified(可能是新药)— §0 加红色警告
add_section_zero_warning(result["unverified_drugs"])
引用与下游
- 上游:
cn-clinical-guidelines-fetch(指南先告诉本 skill 该疾病有哪些药) - 下游:
disease-market-sizing-orchestration(在内容生成阶段强制锚定)、content-verification-layer(report-level cross-check 的事实审计层) - 同层互补:
pubtator-entity-search(基因靶点)、pubmed-eutils(文献召回)
参考文档:
references/nmpa-fetch-api.md— NMPA 网站结构 + 抓取策略references/drugbank-integration.md— DrugBank 学术免费用法references/failure-modes.md— 8 失败模式详解