中华药典 AI Agent 方案文档
版本:v1.2.0
最后更新:2026-07-11
项目代号:Pharmacopoeia AI
项目概述
为「开邻药惠购」微信小程序新增 AI 药典查询功能,面向药店医师、营业员和医生,提供基于《中华人民共和国药典》及 NMPA 官方数据的权威、及时、准确的药品信息查询服务。后续扩展为执业药师考试学习辅导平台。
核心目标
| 目标 |
说明 |
| 权威 |
数据源自药典原文 + NMPA 官方,AI 回答必须带来源引用 |
| 及时 |
爬虫增量更新,药典修订第一时间同步 |
| 准确 |
RAG 强约束,不编造、不推测,置信度低时明示 |
| 可用 |
自然语言交互,三秒内返回结果,SSE 流式输出 |
技术栈
| 层级 |
技术 |
说明 |
| 小程序 |
uni-app |
存量项目,增量开发 AI 模块 |
| 后端 |
Python FastAPI |
AI/ML 生态最完善 |
| 数据库 |
PostgreSQL 16 + Redis |
结构化数据 + 缓存/限流 |
| 向量库 |
pgvector (PostgreSQL 扩展) |
与主库一体,免维护,Milvus 等价能力 |
| Embedding |
BGE-M3 |
中文最优,1024维 + 稀疏向量 |
| 重排序 |
BGE-Reranker-v2-m3 |
Cross-Encoder 精排 |
| LLM(当前) |
Qwen API(阿里云百炼 DashScope) |
OpenAI 兼容,qwen-max / qwen-plus,中文能力强 |
| LLM(后期) |
Qwen3-35B-A3B 本地部署 |
MoE 模型,激活 3B,推理成本低 |
| 推理框架 |
vLLM |
高吞吐,Continuous Batching |
| 爬虫 |
Scrapy + Selenium |
数据采集 |
| 管理后台 |
Vue3 + Vite |
数据管理 / 反馈审核 |
| 部署 |
Docker Compose → K8s |
渐进式部署 |
整体架构
┌────────────────────────────────────────────────────────┐
│ 微信小程序 "开邻药惠购"(uni-app 存量 + AI 增量) │
│ ┌──────────┐ ┌──────────┐ ┌──────────────────────┐ │
│ │ 现有首页 │ │ 药品浏览 │ │ ✨ AI 药典查询(新增) │ │
│ │ +入口按钮 │ │ +问 AI │ │ 自然语言对话式查询 │ │
│ └──────────┘ └──────────┘ └──────────┬───────────┘ │
└──────────────────────────────────────────┼────────────┘
│ HTTPS (SSE)
┌──────────────────────────────────────────▼────────────┐
│ Nginx API 网关 │
└─────────┬────────────────────────────────┬────────────┘
│ │
┌─────────▼──────────────┐ ┌────────────▼─────────────┐
│ FastAPI 后端服务 │ │ 管理后台 (Vue3) │
│ - JWT 鉴权 (微信登录) │ │ - 数据导入管理 │
│ - 对话会话管理 │ │ - 反馈审核 │
│ - SSE 流式推送 │ │ - 知识库更新 │
│ - 限流 & 安全护栏 │ │ - 用量统计 │
└─────────┬──────────────┘ └──────────────────────────┘
│
┌─────────▼──────────────────────────────────────────────┐
│ RAG 引擎(核心) │
│ │
│ 用户问题 → 意图分类 → 混合检索 → 重排序 → LLM 生成 │
│ │ │ │ │ │
│ ┌────▼────┐ ┌───▼────┐ ┌──▼────┐ ┌───▼────┐ │
│ │ 药品查询 │ │向量检索 │ │BGE │ │ Qwen │ │
│ │ 用法咨询 │ │BM25检索│ │Rerank│ │ API │ │
│ │ 法规条款 │ │关键词 │ │ │ │ │ │
│ │ 考试答疑 │ └───┬────┘ └──────┘ └────────┘ │
│ └─────────┘ │ │
│ ┌───────────▼─────────────┐ │
│ │ 知识库 (Milvus + PG) │ │
│ │ ┌─────────────────────┐ │ │
│ │ │ 药典药品条目(向量) │ │ │
│ │ │ 考试知识点(向量) │ │ │
│ │ │ 结构化元数据 (PG) │ │ │
│ │ └─────────────────────┘ │ │
│ └─────────────────────────┘ │
└─────────────────────────────────────────────────────────┘
目录结构
pharmacopoeia-ai/
│
├── backend/ # FastAPI 后端
│ ├── app/
│ │ ├── api/
│ │ │ ├── chat.py # SSE 流式对话
│ │ │ ├── drug.py # 药品 CRUD
│ │ │ ├── auth.py # 微信登录 / JWT
│ │ │ ├── exam/ # ✨ 学习模块(预留)
│ │ │ │ ├── chapter.py # 章节知识点
│ │ │ │ ├── practice.py # 刷题
│ │ │ │ ├── exam_qa.py # 考试答疑
│ │ │ │ └── progress.py # 学习进度
│ │ │ └── admin.py # 管理后台 API
│ │ │ └── admin_knowledge.py # 知识库维护 CRUD API
│ │ ├── core/
│ │ │ ├── config.py # Pydantic Settings
│ │ │ ├── security.py # JWT / 限流
│ │ │ └── llm_client.py # DeepSeek / Qwen 统一调用
│ │ ├── rag/
│ │ │ ├── retriever.py # 混合检索(向量 + BM25)
│ │ │ ├── retriever_exam.py # 考试场景检索
│ │ │ ├── reranker.py # BGE-Reranker-v2-m3
│ │ │ ├── prompt.py # 多场景 Prompt 模板
│ │ │ └── intent.py # 意图分类路由
│ │ ├── models/
│ │ │ ├── drug.py # 药品 ORM
│ │ │ ├── conversation.py # 对话 / 消息
│ │ │ ├── user.py # 用户
│ │ │ ├── knowledge_point.py # ✨ 知识点
│ │ │ ├── question.py # ✨ 题目
│ │ │ └── user_progress.py # ✨ 学习进度
│ │ └── main.py # FastAPI 入口
│ ├── alembic/ # 数据库迁移
│ ├── requirements.txt
│ └── Dockerfile
│
├── data-pipeline/ # 数据采集 & 处理管道
│ ├── crawlers/
│ │ ├── spider.py # Scrapy 基础框架
│ │ ├── nmpa_spider.py # NMPA 药品数据采集
│ │ ├── pharmacopoeia.py # 药典 PDF 解析
│ │ └── exam_outline.py # ✨ 考试大纲采集
│ ├── processors/
│ │ ├── chunker.py # 药品条目切片
│ │ ├── knowledge_chunker.py # ✨ 知识点切片
│ │ ├── question_generator.py # ✨ AI 自动出题
│ │ ├── embedder.py # BGE-M3 向量化
│ │ └── cleaner.py # 文本清洗纠错
│ ├── schemas/
│ │ ├── drug_schema.json # 药品数据结构
│ │ ├── knowledge_point.json # ✨ 知识点结构
│ │ └── question_schema.json # ✨ 题目结构
│ ├── docker-compose.yml
│ └── requirements.txt
│
├── miniprogram/ # uni-app 微信小程序增量
│ ├── pages/
│ │ └── ai-yaodian/ # ✨ AI 药典查询页面
│ │ └── index.vue
│ ├── components/
│ │ └── ai-chat/ # ✨ 可复用 AI 对话组件
│ │ └── index.vue
│ ├── api/
│ │ └── ai.js # ✨ AI 模块 API
│ └── utils/
│ └── sse.js # ✨ SSE 流式接收
│
├── admin/ # 管理后台 (Vue3)
│ ├── src/
│ │ ├── App.vue
│ │ ├── views/
│ │ │ ├── Dashboard.vue
│ │ │ ├── KnowledgeBase.vue
│ │ │ └── Feedback.vue
│ │ └── router/
│ │ └── index.js
│ ├── package.json
│ └── vite.config.js
│
├── deploy/ # 部署配置
│ ├── nginx.conf
│ ├── supervisord.conf
│ └── k8s/ # 后期 K8s 配置
│
├── docker-compose.yml # 全栈一键启动
├── .env.example
├── .gitignore
├── SCHEME.md # 本文档
└── README.md
数据方案
数据来源
| 来源 |
数据类型 |
采集方式 |
优先级 |
| NMPA 药品数据库 |
批准文号、说明书、备案 |
Scrapy + Selenium |
P0 |
| 药典 PDF |
正文内容(需已购买版权) |
PyMuPDF 解析 |
P0 |
| 省药监局公告 |
地方标准、补充批件 |
API 接口 |
P1 |
| 执业药师考试大纲 |
章节、考点分布 |
公开文档解析 |
P2 |
| 历年真题 |
题目及答案 |
公开资料整理 |
P2 |
| 丁香园/用药助手 |
药品说明书 |
公开 API(有限度) |
P2 |
爬虫策略
- 频率控制:2-5 秒/次,尊重 robots.txt
- 反爬对抗:User-Agent 池 + 代理 IP 池轮换
- 增量采集:按批准文号 / 更新时间差量,每日增量调度
- 容错:失败重试 3 次 + 断点续传
- 监控:爬虫健康状态告警,数据量异常检测
药典 PDF 解析流程
PDF 原文件
→ PyMuPDF 提取文本 + 坐标信息
→ 基于字体/位置识别标题层级(部/类/品种)
→ 正则匹配药品条目边界("×××" 品种名称标记)
→ 结构化输出 JSON
输出 schema:
{
"drug_id": "H20000001",
"name": "阿莫西林",
"name_cn": "阿莫西林",
"name_en": "Amoxicillin",
"name_pinyin": "Amoxilin",
"category": "化学药",
"subcategory": "β-内酰胺类抗生素",
"sections": {
"性状": "白色或类白色结晶性粉末...",
"鉴别": "(1) 取本品...",
"检查": "酸度 取本品...",
"含量测定": "照高效液相色谱法...",
"类别": "β-内酰胺类抗生素",
"贮藏": "遮光,密封保存",
"制剂": "阿莫西林片、阿莫西林胶囊..."
},
"source": {
"version": "2020年版",
"volume": "二部",
"page": "567-569",
"entry_id": "Amoxicillin-2020-2"
}
}
切片策略
| 内容类型 |
切片方式 |
理由 |
| 药品条目 |
按条目为单位(非固定长度) |
保证药品信息完整性 |
| 凡例/通则 |
按小标题切分 |
长篇法规需分段检索 |
| 考试知识点 |
按大纲章节切分 |
学习场景需要章节粒度 |
每个 chunk 附带元数据:药品名、分类、来源、版本、页码、章节、难度等级(考试场景)等。
向量化
- 模型:BGE-M3(BAAI),1024 维,支持稠密 + 稀疏向量
- 批次大小:32 条 / batch
- 更新策略:增量 Embedding,只处理新增 / 变更的 chunk
RAG 引擎设计
意图分类
| 意图类型 |
路由策略 |
检索权重 |
| 药品查询 |
精确匹配优先 + 语义兜底 |
向量 0.4 + BM25 0.6 |
| 用法用量 |
语义检索为主 |
向量 0.7 + BM25 0.3 |
| 法规条款 |
BM25 关键词为主 |
向量 0.3 + BM25 0.7 |
| 综合 |
混合融合 |
向量 0.5 + BM25 0.5 |
| 考试答疑 |
按科目/章节过滤 + 语义检索 |
向量 0.6 + BM25 0.4 |
混合检索流程
用户问题
→ 意图分类(药品查询/用法咨询/法规条款/考试答疑)
→ 多路召回:
├── 向量检索(Milvus, Top-50)
├── BM25 关键词检索(PG 全文索引, Top-50)
└── 结构化字段过滤(分类/章节/版本)
→ 融合去重
→ BGE-Reranker-v2-m3 重排序(Top-10)
→ 上下文完整性校验(确保药品条目不截断)
→ 送入 LLM
Prompt 模板
药品查询场景:
你是中华药典AI助手,服务于药店医师和执业药师。
知识来源:最新版《中华人民共和国药典》及NMPA官方数据。
回答规则:
1. 必须严格基于提供的【药典原文】回答,不得添加原文没有的信息
2. 每个回答必须引用来源标注(药典版本/部/页码)
3. 若检索内容不足以回答问题,必须明确告知"药典中未找到相关内容"
4. 涉及处方药必须加注"请在医师指导下使用"
5. 回答格式:结论 → 原文引用 → 来源标注
【药典原文】
{检索到的上下文}
【用户问题】
{用户输入}
考试辅导场景(预留):
你是执业药师考试辅导助手。你擅长将复杂的药典知识以易理解的方式讲解,
帮助考生掌握考点。知识来源:最新版《中华人民共和国药典》及执业药师考试大纲。
回答规则:
1. 基于检索到的药典原文和考试大纲知识点作答
2. 解释要通俗易懂,举一反三,对比归纳
3. 标注该知识点的考试频率和重点程度
4. 注重原理讲解而非死记硬背
5. 引用来源(药典版本/部/页/大纲章节)
【参考内容】
{检索到的上下文}
【用户问题】
{用户输入}
安全护栏
| 层级 |
措施 |
说明 |
| 输入过滤 |
敏感词检测 + 无关提问识别 |
拒绝非药典相关 + 违法提问 |
| 检索校验 |
检索相关性阈值 > 0.5 |
低于阈值则提示"未找到" |
| 输出校验 |
来源引用格式正则匹配 |
缺失引用则告警 + 标记低置信度 |
| 内容审核 |
违禁词二次过滤 |
政治敏感 / 违法药物信息拦截 |
| 免责声明 |
固定附加文案 |
"本回答仅供参考,请以药典原文为准" |
学习模块设计(Phase 4 开发,当前预留)
核心功能
| 功能 |
描述 |
数据依赖 |
| 章节化学习 |
按考试大纲展示知识点树,逐章学习 |
knowledge_point 表 |
| AI 答疑 |
考试场景 RAG 检索,教学型回答 |
知识点向量库 |
| 智能出题 |
LLM 自动生成 A/B/X 型题 + 解析 |
知识点 + 药典原文 |
| 刷题模式 |
顺序刷题 / 随机组卷 / 错题重做 |
题库 + 答题记录 |
| 错题集 |
按科目/章节分类,AI 分析薄弱点 |
答题记录表 |
| 模拟考试 |
按真实考试比例组卷,限时作答 |
审核通过的题库 |
| 考点预测 |
历年考点频率统计 + AI 趋势分析 |
历年真题数据 |
| 学习进度 |
章节完成度 / 正确率 / 学习时长 |
user_progress 表 |
题库生成策略
知识点 + 药典原文
→ LLM 提取关键考点
→ 生成题干 + 正确答案 + 干扰项(需有迷惑性)
→ 自动验证:答案必须在原文中找到明确依据
→ 标注来源和知识点关联
→ 人工抽检审核(首次 100%,后续 10% 抽检)
→ 上线 + 用户反馈闭环淘汰低质量题
题库 Schema
{
"question_id": "Q202401001",
"type": "A", // A型(单选)/ B型(配伍)/ X型(多选)
"subject": "药学专业知识一",
"chapter": "第01章 药品与药品质量标准",
"difficulty": 3,
"content": "关于阿莫西林的叙述,错误的是?",
"options": [
"A. 属于半合成青霉素",
"B. 抗菌谱包括革兰阳性菌和阴性菌",
"C. 口服吸收不受食物影响",
"D. 与丙磺舒合用可延长半衰期"
],
"answer": "C",
"explanation": "阿莫西林口服吸收良好,但食物对吸收有轻微影响...",
"knowledge_points": ["KP-01001", "KP-01005"],
"source": "药典2020版 二部 P567-569",
"audited": true,
"frequency": "高频"
}
部署方案
初期(DeepSeek API 阶段)— 单机部署
┌────────────────────────────────────┐
│ 4C 16G Linux 服务器 (x2,主备) │
│ │
│ Primary: │
│ ├── Nginx (HTTPS + WAF) │
│ ├── FastAPI (uvicorn x4 workers) │
│ ├── PostgreSQL 16 │
│ ├── Milvus Lite (向量库) │
│ ├── Redis (缓存 / 限流) │
│ └── Celery Worker (异步任务) │
│ │
│ Standby: │
│ ├── PG 流复制(只读副本) │
│ └── Milvus 定期备份 │
│ │
│ LLM: DeepSeek API (云端) │
└────────────────────────────────────┘
后期(本地 Qwen 阶段)— GPU 服务器
┌────────────────────────────────────┐
│ GPU 推理服务器 │
│ ├── 2× NVIDIA 4090 (24GB ×2) │
│ ├── vLLM 推理框架 │
│ └── Qwen3-35B-A3B (INT8 量化) │
│ 全量 ~70GB / INT8 ~35GB │
│ 2×4090 48GB 可支撑 │
│ 预计并发 50-100 QPS │
└────────────────────────────────────┘
成本估算
| 阶段 |
项目 |
月成本(元) |
备注 |
| 初期 |
云服务器 (4C16G x2) |
~800 |
主备 |
| 初期 |
Qwen API(阿里云百炼) |
~2,500 |
10万用户,90万次/月 |
| 初期 |
CDN + 对象存储 + 其他 |
~500 |
- |
| 初期 |
合计 |
~3,800 |
- |
|
|
|
|
| 后期 |
云服务器 |
~800 |
不变 |
| 后期 |
GPU 服务器 (2×4090) |
~3,000 |
按月租用 |
| 后期 |
Qwen API(备用) |
~200 |
减少到 5 万次/月 |
| 后期 |
合计 |
~4,000 |
成本下降后持平 |
Qwen API 成本测算(qwen-max):
| 指标 |
数值 |
| 用户总量 |
100,000 |
| 日活率 |
10% |
| 人均查询次数 |
3 次/天 |
| 月查询总量 |
900,000 次 |
| 单次输入 tokens |
~3,000 |
| 单次输出 tokens |
~500 |
| 月输入 tokens |
2,700M |
| 月输出 tokens |
450M |
| 输入单价 |
¥2.5 / 百万 tokens |
| 输出单价 |
¥10 / 百万 tokens |
| 月费用 |
2,700×2.5 + 450×10 ≈ 11,250 元 |
注:以上为 qwen-max 定价。实际可选用 qwen-plus(输入 ¥0.8/百万 tokens,输出 ¥2/百万 tokens)将成本降至约 3,000 元/月。
知识库维护 API
管理后台提供完整的 RESTful 接口,支持随时增删改查知识库内容:
药品管理
| 方法 |
路径 |
说明 |
| GET |
/admin/knowledge/drugs |
分页列表(支持关键词搜索、分类筛选) |
| GET |
/admin/knowledge/drugs/{id} |
药品详情 |
| POST |
/admin/knowledge/drugs |
新增药品 |
| PUT |
/admin/knowledge/drugs/{id} |
更新药品 |
| DELETE |
/admin/knowledge/drugs/{id} |
删除(软删除) |
| POST |
/admin/knowledge/drugs/import |
批量导入(JSON/CSV) |
| POST |
/admin/knowledge/drugs/reindex |
重建向量索引(全量/指定ID) |
知识点管理
| 方法 |
路径 |
说明 |
| GET |
/admin/knowledge/knowledge-points |
分页列表(按科目/章节/难度/频率筛选) |
| GET |
/admin/knowledge/knowledge-points/{id} |
知识点详情 |
| POST |
/admin/knowledge/knowledge-points |
新增知识点 |
| PUT |
/admin/knowledge/knowledge-points/{id} |
更新知识点 |
| DELETE |
/admin/knowledge/knowledge-points/{id} |
删除 |
| POST |
/admin/knowledge/knowledge-points/import |
批量导入 |
题库管理
| 方法 |
路径 |
说明 |
| GET |
/admin/knowledge/questions |
分页列表(按科目/章节/题型/审核状态筛选) |
| GET |
/admin/knowledge/questions/{id} |
题目详情 |
| POST |
/admin/knowledge/questions |
新增题目 |
| PUT |
/admin/knowledge/questions/{id} |
更新题目 |
| DELETE |
/admin/knowledge/questions/{id} |
删除 |
| POST |
/admin/knowledge/questions/import |
批量导入 |
| POST |
/admin/knowledge/questions/batch-audit |
批量审核 |
| POST |
/admin/knowledge/questions/generate |
AI 根据知识点自动出题 |
知识库统计
| 方法 |
路径 |
说明 |
| GET |
/admin/knowledge/stats |
库总量、各分类统计、向量索引状态 |
分阶段实施计划
Phase 1:骨架搭建(当前)
Phase 2:数据采集 & 知识库
Phase 3:RAG 引擎 + AI 药典查询上线
Phase 4:学习模块开发
关键风险 & 应对
| 风险 |
影响 |
应对 |
| 药典数据版权 |
法律风险 |
仅使用已购买授权的正版药典;NMPA 公开数据为主 |
| 爬虫被封 |
数据中断 |
IP 代理池 + 频率控制 + 多源备份 |
| AI 幻觉编造 |
安全风险 |
RAG 强约束 + 引用校验 + 置信度阈值 |
| 医疗合规审核 |
上线受阻 |
已有资格证书;固定免责声明;不提供处方建议 |
| 小程序审核 |
上线延期 |
参考医疗类小程序审核规则;内容审核前置 |
| 本地模型推理性能 |
用户体验差 |
vLLM + 量化 + GPU 规格充分;留 Qwen API 兜底 |
变更记录
| 版本 |
日期 |
变更内容 |
| v1.2.0 |
2026-07-11 |
RAG 链路打通(pgvector 向量检索 + DashScope Embedding + Qwen LLM 端到端);意图分类优化;新增 DATA_GUIDE.md / CRAWLER_ASSESSMENT.md / MINIPROGRAM_INTEGRATION.md 三份操作文档 |
| v1.1.0 |
2026-07-11 |
LLM 切换为 Qwen API(阿里云百炼 DashScope);新增知识库维护 CRUD API(药品/知识点/题库管理、批量导入、向量重建索引);更新成本估算 |
| v1.0.0 |
2026-07-11 |
初始版本,包含完整方案和 Phase 1 骨架计划 |