当前位置: 首页 > news >正文

[开源] 门急诊药房语音核验助手:面向基层断网场景的处方-药品双码核验系统,本地规则驱动、离线播报、联网可扩展解释

本项目是专为门急诊药房设计的轻量级语音核验工具,核心解决基层药房在无网络或弱网环境下「处方扫码→药盒条码比对→结果即时反馈」的闭环需求。我们不做云端SaaS,不依赖中心化服务,整套逻辑运行在本地终端:药师扫处方二维码和药品EAN-13条码后,由SQLite内置规则引擎完成剂量、规格、通用名、适应症等维度的结构化比对;结果通过离线TTS(pyttsx3)语音播报,不匹配时优先调用本地规则生成说明,联网状态下可选调用LLM补充中文解释;所有核验记录支持导出为Excel与HTML报告。它是一个CLI命令行系统,无Web界面、无后台进程、无安装向导,开箱即用,适用于县域医院、社区卫生服务中心、乡镇卫生院等网络不稳定但需保障发药安全的一线药房。

定位与能力边界

我们明确聚焦三类现实约束:第一是网络不可靠,很多基层药房内网未通外网,或仅在特定时段开放;第二是操作必须极简,药师平均单次发药时间不足90秒,不能接受多步确认、弹窗提示、账号登录;第三是责任可追溯,每笔核验必须留痕,且记录字段需满足《医疗机构处方审核规范》中“审核依据可复现、结论可回溯”的基本要求。

因此,本项目不覆盖静脉配置中心(PIVAS)的多组分复核,不处理中药饮片散装称重场景,不替代HIS系统处方开具环节,也不提供库存预警或采购建议。它的全部价值锚定在“扫码那一刻”:从药师举起扫码枪开始,到语音说出“核验通过”或“规格不匹配,请核查”为止,全程控制在2.5秒内完成本地计算,不等待任何外部响应。

这决定了我们放弃WebSocket长连、放弃React前端、放弃Docker容器化部署,所有技术选型都服务于一个目标:让一台三年前出厂的Windows台式机(i3处理器、4GB内存、无独立声卡)也能稳定运行。

核心功能实现逻辑

功能模块

实现方式

关键约束与设计取舍

双码扫描核验

同时读取处方二维码(含处方ID、患者ID、药品通用名、规格、剂量、频次)与药品EAN-13条码(映射至本地药品库),比对字段包括:EAN码唯一性、规格数值一致性(如“0.25g×12片” vs “250mg×12片”)、单次剂量换算合规性(如处方写“每次1片”,药品标“每片含阿莫西林0.5g”,则需校验是否超限)

不做OCR识别,只接受标准二维码与EAN-13条码;不校验医生手写签名或纸质处方字迹;规格比对采用正则+单位归一化(mg/g/kg、ml/L、片/粒/袋等预置转换表)

离线语音播报

默认启用pyttsx3(Windows平台调用SAPI5,macOS调用NSSpeechSynthesizer,Linux调用espeak-ng),语音内容严格结构化:“处方号AB123,药品阿莫西林胶囊,核验通过” 或 “处方号AB123,药品阿莫西林胶囊,规格不匹配:处方要求0.25g/片,药盒标注250mg/片,数值等效但单位格式不符”

若系统语音引擎初始化失败,自动降级为屏幕文字输出,不中断核验流程;不支持自定义音色或语速调节,确保跨设备行为一致

本地规则引擎

所有核验逻辑固化在SQLite数据库pharmacy_cache.db中,含drugs(药品主数据)、prescriptions(处方快照)、rules(比对规则集,如“规格字段必须数值相等且单位缩写一致”“单次剂量不得超过说明书最大单次用量80%”)三张表

规则不可热更新,需通过--import命令重新载入CSV数据;不支持SQL注入式规则编写,所有逻辑预编译为Python函数调用链

LLM解释生成(可选)

当检测到不匹配且网络可用时,将处方原始字段、药品实测字段、本地规则判定结论打包为prompt,调用OpenAI API(兼容其他兼容OpenAI格式的LLM接口)生成一段通俗中文说明,例如:“您处方中要求每次服用1粒,但该药品说明书注明‘成人每次口服2粒’,当前剂量低于推荐起始剂量,建议与开方医师确认”

LLM仅用于增强解释,不参与核验决策;超时5秒即fallback至本地规则文本;API密钥通过.env文件注入,不硬编码、不存数据库

使用与启动方式

项目以命令行交互为主,无图形界面,所有操作通过python -m src.cli触发。我们提供四种常用模式,按使用频率排序:

python -m src.cli --import --drugs data/sample_drugs.csv --prescriptions data/sample_prescriptions.csv

首次使用必执行此命令,将示例CSV导入本地SQLite。注意:sample_drugs.csv必须含ean(13位纯数字)、generic_namespecmax_dose_per_time等字段;sample_prescriptions.csv必须含prescription_idpatient_iddrug_generic_namedose_per_timefrequency等字段,编码须为UTF-8无BOM。

python -m src.cli --scan

进入实时扫码模式。程序自动调用系统默认摄像头或USB扫码枪,识别成功后立即触发核验并播报。若扫码失败,语音提示“未识别有效条码”,屏幕显示错误类型(如“EAN长度不足13位”“非数字字符”)。

python -m src.cli --manual

无扫码设备时的手动输入模式。依次提示输入处方号、药品EAN码,程序校验格式后执行核验。适合临时调试或设备故障应急。

python -m src.cli --demo

演示模式。加载内置测试数据,自动循环执行10次典型核验案例(含5次通过、3次规格不匹配、2次剂量超限),全程语音播报+屏幕日志,便于新药师快速理解输出含义。

数据与扩展机制

所有业务数据均通过CSV导入,字段定义严格遵循说明文档中的映射表。我们不提供在线编辑器或Excel模板下载,因为真实药房的数据源来自HIS导出,其字段命名已固定。你只需确保导出文件包含以下必要列:

CSV字段名

含义

是否必填

示例值

ean

药品国际商品条码

6921234567890

generic_name

药品通用名称(中文)

阿莫西林胶囊

spec

规格描述(含单位)

0.25g×12片

max_dose_per_time

单次最大允许剂量(数值+单位)

1g

route

给药途径

口服

扩展新规则无需改代码。比如新增一条“儿童用药年龄限制”规则,只需在rules表中插入一行:rule_name="age_restriction"condition="prescription_age < 12 and drug_route == '口服' and drug_max_dose_per_time < '0.5g'"message="该药品说明书未标注儿童用法,建议咨询儿科医师"。下次导入数据时规则即生效。

环境与运行保障

项目最小运行环境为Python 3.8+,无GPU、无CUDA依赖。我们验证过以下组合可开箱运行:

系统平台

Python版本

TTS引擎

备注

Windows 10/11

3.8~3.11

pyttsx3(SAPI5)

需系统已启用“文字转语音”功能,控制面板→轻松使用→讲述人→语音设置中任一语音启用即可

macOS Monterey+

3.9~3.11

pyttsx3(NSSpeechSynthesizer)

无需额外安装语音包,系统自带

Ubuntu 20.04+

3.8~3.11

pyttsx3(espeak-ng)

sudo apt install espeak-ng

后自动识别

若需更高自然度语音,可在config.yaml中将tts_engine: offline改为online,此时启用edge-tts,但需联网且会增加约800ms响应延迟。我们不推荐在发药高峰时段启用。

故障应对与降级策略

我们为每一层依赖都设计了明确的fallback路径,确保“核验不中断”为最高优先级:

  • 无声音?

    先检查系统音频设备是否静音;若pyttsx3初始化失败(如Linux缺少espeak-ng),自动切换为屏幕输出,不报错、不停止;

  • LLM不可用?.env

    中未配置API密钥,或网络超时,或返回HTTP 429,全部触发fallback至本地规则文本,输出内容保持语义一致;

  • 数据库损坏?

    删除data/pharmacy_cache.db后重新--import,程序自动重建表结构;

  • CSV导入失败?

    常见原因为字段缺失或EAN含字母,程序会精确指出第几行、哪个字段异常,不终止后续行导入。

所有fallback行为均不修改用户数据、不丢失历史记录、不改变CLI命令语法,你今天用的参数,三个月后升级版本仍完全兼容。

项目地址:
https://github.com/nexorin9/outpatient-pharmacy-voice-checker

http://www.rkmt.cn/news/1439182.html

相关文章:

  • 【读书笔记】《架构整洁之道》核心观点提炼
  • CANN/ops-blas sspmv算子实现
  • 如何在Stable-Worldmodel中实现warm-start规划?提升求解效率的关键技巧
  • VTK太复杂?试试用C#的ActiViz库:5步搞定三维点云可视化(避坑指南)
  • AI重塑ITSM:从技术顾问到社区构建者的实践与思考
  • 解决常见问题:Qwen3.6-27B-OBLITERATED使用中的10个疑难解答
  • 如何高效自动化下载国家中小学智慧教育平台电子课本?tchMaterial-parser实用指南深度解析
  • 虚拟化浪潮与元宇宙演进:从技术架构到社会影响深度解析
  • 新手避坑指南:用Arduino IDE 2.2.1点亮源地ESP32-S2-MINI-1开发板上的WS2812B灯珠
  • AI时代商业可见性:从SEO到AI优化的范式转移与实战指南
  • LabVIEW UI 逻辑解耦设计
  • 5分钟彻底改造你的音乐播放器:foobox-cn终极美化方案实战
  • Exodia-7B开发者指南:自定义训练与模型微调全攻略
  • MoE架构深度解析:Qwen3.5-122B-A10B-Uncensored-HauhauCS-Aggressive如何用1220亿参数实现高效推理
  • 2026年4月有实力的水分仪厂家推荐,电磁流量传感器/矿用本安型超声波流量计/本安气体流量计,水分仪公司哪家可靠 - 品牌推荐师
  • 反拖延经济崛起:从AI教练到共享空间,如何科学对抗拖延症?
  • 微信聊天记录如何实现永久本地化存储:WeChatMsg开源工具技术解析
  • 告别抖动!用Cinemachine 2.9.7搞定Unity 2D角色移动时的镜头平滑跟随
  • 国家中小学智慧教育平台电子课本下载完整指南:一键获取PDF教材的高效解决方案
  • 如何利用Notus-7B-v1-openmind构建智能聊天应用:从零开始的完整教程
  • AI驱动的社会工程学攻击:大语言模型如何模拟“邪恶双胞胎”实施身份劫持
  • AI SDLC转型:从虚荣指标到能力进化的三层度量模型实践
  • 用Python+Matplotlib分析美国犯罪率:从数据清洗到散点图绘制的保姆级教程
  • distilcamembert-base-sentiment多格式支持:PyTorch、TensorFlow、ONNX全解析
  • 如何用3步永久保存微信聊天记录:开源工具的完整实践指南
  • 三步搞定国家中小学智慧教育平台电子课本下载:免费开源工具终极指南
  • CentOS 8.3虚拟机里装Sentaurus TCAD,我踩过的7个坑和填坑方法(附详细命令)
  • 别再只关触摸板了!Ubuntu 22.04触屏干扰的终极排查与一键关闭脚本
  • CTF新手也能玩转的隐写术:从WUSTCTF2020的alison_likes_jojo题,手把手教你用Kali工具链(binwalk+foremost+outguess)
  • 揭秘WeChatMsg:将数字对话转化为永恒记忆的数据艺术