njucm njucm.org
← Projects

药品法规知识库 · NMPARegHub

仓库:leerogerstheman/NMPARegHub

纯 Python 标准库实现,零第三方依赖。 一个 SQLite 文件即全部数据。

做注册和药事管理,最耗时的不是理解法规,而是找到并确认法规:某条要求出自哪份 文件?现行有效还是已被替代?某个 ICH 指导原则在国内是否已适用?三年前那份公告和现在 的版本差在哪?通用搜索引擎做不到「按发文字号精确检索」「只看现行有效」「比对两个 版本」。本项目把这件事变成一个可以离线运行、数据完全自持的库。

能做什么

能力说明
全文检索SQLite FTS5 trigram 索引;中文两字词自动回退 LIKE,不会出现「搜不到」
检索语法药品注册 -化妆品(排除)、"精确短语"、多词隐式 AND
ICH / CTD 自动归类按 ICH 编号(Q1–Q12、S1–S11、E1–E14、M1–M8)与 CTD 模块归类
主题分类药品注册 / 药物警戒 / 药品生产 / 价格与采购 / 中医药 等 18 类
发文字号归一化药监局公告2021年第32号 → 国药监〔2021〕32号,同一文件只有一个标识
版本追踪与 diff正文变化时自动归档旧版本,输出 unified diff,可定位到具体条款
效力状态推断从正文尾部识别「自…起施行」/「起废止」,保守标注
本地导入HTML / PDF / TXT / Markdown 拖入即入库,保留来源路径便于审计
Web 界面零依赖 http.server 实现,支持分面筛选与文档阅读

实测数据

在中国政府网政策文件库真实数据上的验证结果(4 组关键词 × 1 页):

库中共 62 份文件,16 个标签

主题分布      中医药 25 · 药品注册 10 · 药品生产 8 · 化妆品 6 · 价格与采购 5 · 药物警戒 5
发文机关      国家药品监督管理局 27 · 国务院办公厅 9 · 国务院 8
年份跨度      2019 – 2026
效力状态      现行有效 16 · 已废止 6 · 未标注 40

快速开始

git clone https://github.com/leerogerstheman/NMPARegHub
cd NMPARegHub

python regkb.py crawl                    # 采集中国政府网药品法规
python regkb.py import D:\我的法规资料     # 导入本地公告(HTML/PDF/TXT/MD)
python regkb.py search "药品注册 -化妆品"  # 检索
python regkb.py facets                   # 分面统计
python regkb.py diff 11                  # 比对版本
python webui.py                          # Web 界面 → http://127.0.0.1:8765

环境要求:Python 3.9+。不需要 pip install 任何东西。

数据来源与合规说明

nmpa.gov.cn、cde.org.cn、nhc.gov.cn 均部署 JavaScript 反爬验证(阿里云盾 WAF), 对普通 HTTP 客户端返回 HTTP 412/202 与一段混淆的挑战脚本,必须执行该脚本生成签名 Cookie 才能访问。

本项目不实现绕过该保护机制。 绕过网站明确部署的安全控制,既违背站点所有者的 意愿,也不适合出现在一个以合规为主题的作品里。这些机构的文件通过离线导入进入 知识库 —— 在浏览器中正常打开并另存,再用 import 命令入库,这是完全合规且可审计 的路径,导入时会记录来源文件路径。

来源状态
中国政府网政策文件库 gov.cn自动采集(公开 JSON 检索接口 + 服务端渲染文章页)
国家药典委员会 chp.org.cn自动采集
NMPA / CDE / 卫健委离线导入(见上)
本地文件离线导入,支持 HTML / PDF / TXT / MD

开发中由真实数据暴露的三个缺陷

这三个 bug 都不是想出来的,是跑真实数据跑出来的,均有回归测试覆盖:

  1. 纯排除查询静默返回 0 条 —— doc_number NOT LIKE ? 在字段为 NULL 时结果为 NULL,而 NULL AND x 永不为真,导致所有无发文字号的文件被静默丢弃。用 COALESCE 包裹修复。这类 bug 在生产环境可以潜伏很久。
  2. FTS5 的 NOT 无法独立成立 —— 纯排除查询在 FTS 中恒为空,排除条件改用 SQL 谓词实现。
  3. 分类子串误匹配 —— 「化妆品注册备案」因含「注册」被误归为「药品注册」, 引入标题级排除规则修复。

设计取舍

为什么用规则分类而不是模型? 注册专员需要知道某份文件为什么被归到某一类。 关键词表可审计、可复现、可解释;不透明的分类器三者皆无。每个标签都能追溯到正文中 的字面匹配。

为什么保留历史版本? 重复采集时静默覆盖正文,恰好会摧毁合规用户最关心的信息 —— 法规什么时候改了什么。

为什么效力状态标注保守? 把一份现行有效的法规误标为「已废止」,比留成 unknown 危害大得多,所以只在正文尾部出现明确废止表述时才标注。

测试

python tests/test_regkb.py     # 22/22 passed

覆盖发文字号解析(含反例)、归类排除规则、效力推断、FTS 索引同步、检索语义 (含纯排除查询与两字词回退)、版本归档与 diff。

局限

  • 分类规则是启发式的,不是法律意见。标签用于辅助检索,不能替代对原文的阅读。
  • 效力状态为推断值,来源页面通常不提供结构化的废止标记。
  • gov.cn 收录范围有限:主要收录国务院及部门层面文件,NMPA 的大量技术指导原则 并不在其中,这是需要离线导入的原因。
  • 本项目不是法律依据,正式注册申报请以官方发布文本为准。

资源