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

[开源] 科研样本外送检测全链路追踪系统:面向科研协调与检验管理的五节点时间轴工具

本项目是专为科研样本外送检测流程设计的轻量级全链路追踪系统,覆盖「申请→寄出→送达→检测→结果返回」五个确定性状态节点,服务于科研协调员、检验科管理员及科研处负责人三类核心角色。我们不替代LIMS或HIS,而是补足其在跨机构样本流转中缺失的时间轴显性化、PDF结果结构化、超时响应自动化三个关键断点。系统以CSV双通道采集(申请单+快递单)为起点,用LLM驱动PDF字段提取为终点,输出Web页面、CSV台账和CLI交互三种形态;技术栈采用Python 3.11+、SQLite本地持久化、FastAPI提供Web服务,并通过OpenAI/Anthropic API完成检测报告PDF的语义解析。

定位与能力边界

我们明确不做三件事:不接入物流厂商实时API(依赖人工导入快递单CSV),不对接医院内部检验仪器(仅处理已生成的PDF结果文件),不承担样本质量判定(所有状态变更由人工确认或规则触发)。
真正做好的只有一件事:把原本散落在邮件、微信、Excel、PDF里的五段关键时间,锚定到一个唯一sample_id下,形成可排序、可筛选、可告警、可导出的时间轴事实库。
这个“事实库”不是抽象概念,它直接对应数据库里一张表,每一行是一个样本,每一列是一个时间戳或结构化字段(如apply_timeresult_pdf_url),所有Web页面、CLI命令、CSV导出都读写这张表。没有中间缓存,没有异步队列,SQLite就是单一真相源。

核心功能:五节点状态机与三重数据注入

系统围绕“五节点状态机”构建主干逻辑:applied → in_transit → received → testing → reported。每个状态有明确定义和进入条件,例如in_transit必须填写leave_timereceived必须填写return_time,而reported则依赖PDF解析成功并填入至少一个检测字段。
这五个状态不是静态标签,而是驱动后续动作的开关。比如当状态为testingreturn_time距今超48小时未更新result_received_time,即触发超时告警;当状态为received且上传了PDF,则自动调用LLM解析接口提取字段。

数据注入共三条通路,互不干扰又可叠加:

通路类型

输入形式

自动化程度

典型使用者

CSV申请单导入

data/demo_samples.csv

sample_id,apply_time等字段

全自动解析+入库

科研协调员批量建样

快递单CSV关联

同一sample_id的快递单含leave_time,return_time

自动匹配+时间戳填充

检验科管理员补寄送信息

PDF结果上传

上传检测报告PDF,点击「关联PDF」按钮

LLM自动提取test_name,result_value,unit等字段

科研处负责人归档结果

注意:三条通路均不修改原始文件,所有解析结果写入SQLite,原始CSV和PDF保留在本地路径供审计回溯。

超时告警规则:用DSL定义催办逻辑

我们不预设“检测应在5个工作日内完成”这类刚性规则,而是提供一套轻量DSL(领域特定语言),让管理员按需配置。规则写在config/alert_rules.yaml中,示例:

- name: "寄出超时" condition: "status == 'applied' and (now() - apply_time).hours > 24" action: "send_wechat('请尽快寄出样本S{sample_id}')" - name: "结果滞留" condition: "status == 'received' and (now() - return_time).hours > 48" action: "escalate_to('检验科主任')"

每条规则含三部分:名称(仅用于日志)、condition(基于当前样本字段和内置函数的布尔表达式)、action(触发通知或升级动作)。所有规则在CLI执行check-alerts或Web页面刷新时实时求值,不依赖定时任务。DSL语法严格限制在安全子集内,无法执行任意代码,保障运行时隔离。

使用与配置:从零启动只需三步

你不需要部署服务器、不需配置Nginx、不需申请API密钥(默认使用免费层配额)。只要本地有Python 3.11环境,三步即可跑通全流程:

第一步:安装依赖

pip install -r requirements.txt

第二步:初始化示例数据(自动创建SQLite并导入demo)

python -m src.data.csv_parser data/demo_samples.csv

第三步:启动Web服务(开发模式,带热重载)

uvicorn src.output.web:app --reload --port 8000

启动后访问 http://127.0.0.1:8000/samples,即可看到带时间轴卡片的样本列表页。每个卡片显示sample_id、当前状态色块、各节点时间戳(空值显示“待填写”)、操作按钮(关联PDF、编辑、标记完成)。

CLI作为补充界面,适合批量操作与脚本集成:
-python -m src.output.cli add:交互式录入新样本(提示输入sample_id,apply_time等)
-python -m src.output.cli list --status testing:按状态过滤列出所有检测中样本
-python -m src.output.cli view S20260516001:打印该样本完整时间轴与PDF提取字段
-python -m src.output.cli check-alerts:运行全部告警规则并输出触发项

所有CLI命令均支持--help查看参数说明。

数据字段与业务含义对齐

系统暴露的每个字段都对应真实业务动作,无冗余、无抽象建模。我们坚持“字段即动作”,例如:

字段名

业务含义

填写时机

是否可为空

sample_id

样本唯一编号,由科研协调员在申请时生成

录入首步必填

apply_time

科研人员提交送检申请的时间点

CSV导入或CLI录入时填写

leave_time

样本实际交寄快递的时间(非面单打印时间)

快递单CSV导入或Web手动编辑

状态为in_transit时必填

return_time

检测机构签收样本的时间(以快递物流记录为准)

快递单CSV导入或Web手动编辑

状态为received时必填

result_received_time

科研方收到PDF检测报告的时间

上传PDF后自动填充(或手动补)

状态为reported时必填

result_pdf_url

PDF文件本地路径或HTTP链接

Web上传后自动生成

状态为reported时必填

linked_apply_id

关联的原始申请单号(如OA流水号)

可选,用于跨系统追溯

status

当前所处状态节点,仅限五值之一

由时间戳填写自动推导或手动切换

特别说明:status不是独立维护字段,而是由各时间戳存在与否自动计算得出。例如当apply_time存在但leave_time为空,状态即为applied;当leave_timereturn_time均存在但result_received_time为空,状态即为received。这种设计避免状态与时间戳人为不一致。

工程结构:模块职责清晰,扩展成本可控

整个项目按能力切分为六个主模块,每个目录对应单一职责,无交叉引用:

目录路径

职责说明

典型文件

src/data/

数据解析与入库:CSV读取、字段校验、SQLite写入

csv_parser.py

,db.py

src/llm/

PDF语义解析:调用大模型API、定义prompt模板、清洗提取结果

pdf_extractor.py

,prompts.yaml

src/rules/

告警规则引擎:DSL解析器、条件求值器、动作执行器

dsl_parser.py

,engine.py

src/output/web/

Web界面:FastAPI路由、Jinja2模板、状态渲染逻辑

main.py

,templates/samples.html

src/output/cli/

命令行界面:Argparse参数定义、交互逻辑、输出格式化

__main__.py

,commands.py

src/utils/

通用工具:时间格式转换、ID生成、日志封装

time_utils.py

,id_gen.py

新增一种数据源(如对接某快递API)只需在src/data/下新增一个解析器类,不改动其他模块;更换LLM供应商只需修改src/llm/pdf_extractor.py中的客户端初始化逻辑。所有模块通过src/__init__.py统一暴露接口,无隐式依赖。

限制与说明

本系统当前版本明确存在以下限制,均已在设计阶段权衡取舍:
-PDF解析依赖网络API:需自行配置OpenAI或Anthropic密钥(写入.env),离线不可用;但解析失败不影响时间轴主体功能,仅PDF字段为空。
-SQLite单机存储:不支持多用户并发写入,适用于单人管理或小团队共享一台电脑的场景;若需协同,建议通过Git同步SQLite文件(二进制diff友好)。
-中文PDF支持有限:LLM prompt针对中英文混合检测报告优化,纯中文PDF(尤其表格密集型)可能漏提字段;建议优先使用带标准字段命名的PDF模板。
-无用户权限体系:Web界面默认开放读写,生产环境如需多角色控制,需在Nginx层加基础认证,或自行扩展FastAPI的Auth中间件。

这些限制不是缺陷,而是我们为保持轻量、可审计、易迁移所做的主动选择。如果你的场景需要集群部署、RBAC或OCR本地化,欢迎提交Issue讨论演进路径。

项目地址:
https://github.com/nexorin9/research-sample-timeline-tracker

http://www.gsyq.cn/news/1451998.html

相关文章:

  • Spring Boot项目里@Async注解不生效?别急,先检查这5个配置(附线程池调优建议)
  • 家庭创客指南:用Arduino与树莓派复刻互动科技展
  • 避坑指南:在Ubuntu 20.04服务器上为CARLA 0.9.13手动寻找并安装正确的Python 3.8客户端whl文件
  • 鸣潮自动化工具终极指南:3步配置解放双手的游戏助手
  • Dev Containers与CI/CD实战:构建自动化开发环境与高效研发流程
  • 告别重复输入密码:用SSH-Agent管理你的GitHub、GitLab和Hugging Face密钥
  • 微软新方案:软硬协同让可穿戴设备续航倍增
  • 麒麟系统上打包Electron+Vue应用,从AppImage到deb的保姆级踩坑实录
  • VS2022安装Resharper C++插件踩坑实录:从市场下载慢到激活成功的完整指南
  • 基于Arduino与DHT11的智能温湿度监测站:从硬件搭建到代码调试全解析
  • 从零基础到AI工程师:我的大模型学习路线,小白也能收藏学!
  • Phi-2小模型解析:27亿参数如何实现高效AI部署与微调实战
  • 手把手教你用Xilinx GT Wizard搭建8B10B高速收发器(附完整代码与避坑指南)
  • 告别多视图数据打架:用Multi-VAE手把手分离公共特征与视图专属特征(附PyTorch代码)
  • STM32CUBEMX项目实战:用广和通L610 Cat.1模块,把路灯数据上报到腾讯云IoT
  • 异构计算、存算一体与云原生:前沿计算技术实践与演进
  • 别再乱切了!3DsMax展UV新手必看:用‘边颜色’和‘松弛’搞定贴图拉伸
  • 3个简单方法让普通鼠标在Mac上超越触控板体验
  • STM32F103ZET6驱动TFTLCD保姆级教程:从CubeMX配置到点亮第一抹蓝
  • “我经历过最糟糕的一次求职面试”
  • Mina Meeting Assistant 新手极速上手指南
  • 缅甸工业园实地现荒弃地块,低价承租厂房暗藏千万规模诈骗陷阱
  • YOLOv8模型瘦身与加速:用CSPStage和四检测头优化推理速度,兼顾GC10-DET精度
  • 联想领像M100/M100W打印机加粉后,手机APP和按键清零到底怎么选?保姆级图文教程
  • 云赋能移动应用开发:Project Hawaii挑战赛实战指南
  • TEE与机密LLM推理:硬件级安全与性能优化
  • 别只抄数据手册!STM32电源设计中的0欧电阻、磁珠与电容布局实战心得
  • 手把手教你用STM32CubeMX和HAL库驱动0.91寸OLED(SSD1306),从点亮到画图全流程
  • MIMO-OFDM神经集成感知与通信框架解析
  • AI驱动的日志异常检测落地全路径(从ELK+LangChain到生产级AIOps闭环)