本项目是专为科研样本外送检测流程设计的轻量级全链路追踪系统覆盖「申请→寄出→送达→检测→结果返回」五个确定性状态节点服务于科研协调员、检验科管理员及科研处负责人三类核心角色。我们不替代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_time、result_pdf_url所有Web页面、CLI命令、CSV导出都读写这张表。没有中间缓存没有异步队列SQLite就是单一真相源。核心功能五节点状态机与三重数据注入系统围绕“五节点状态机”构建主干逻辑applied → in_transit → received → testing → reported。每个状态有明确定义和进入条件例如in_transit必须填写leave_timereceived必须填写return_time而reported则依赖PDF解析成功并填入至少一个检测字段。这五个状态不是静态标签而是驱动后续动作的开关。比如当状态为testing且return_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并导入demopython -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_urlPDF文件本地路径或HTTP链接Web上传后自动生成状态为reported时必填linked_apply_id关联的原始申请单号如OA流水号可选用于跨系统追溯是status当前所处状态节点仅限五值之一由时间戳填写自动推导或手动切换否特别说明status不是独立维护字段而是由各时间戳存在与否自动计算得出。例如当apply_time存在但leave_time为空状态即为applied当leave_time和return_time均存在但result_received_time为空状态即为received。这种设计避免状态与时间戳人为不一致。工程结构模块职责清晰扩展成本可控整个项目按能力切分为六个主模块每个目录对应单一职责无交叉引用目录路径职责说明典型文件src/data/数据解析与入库CSV读取、字段校验、SQLite写入csv_parser.py,db.pysrc/llm/PDF语义解析调用大模型API、定义prompt模板、清洗提取结果pdf_extractor.py,prompts.yamlsrc/rules/告警规则引擎DSL解析器、条件求值器、动作执行器dsl_parser.py,engine.pysrc/output/web/Web界面FastAPI路由、Jinja2模板、状态渲染逻辑main.py,templates/samples.htmlsrc/output/cli/命令行界面Argparse参数定义、交互逻辑、输出格式化__main__.py,commands.pysrc/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
[开源] 科研样本外送检测全链路追踪系统:面向科研协调与检验管理的五节点时间轴工具
发布时间:2026/6/3 6:32:19
本项目是专为科研样本外送检测流程设计的轻量级全链路追踪系统覆盖「申请→寄出→送达→检测→结果返回」五个确定性状态节点服务于科研协调员、检验科管理员及科研处负责人三类核心角色。我们不替代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_time、result_pdf_url所有Web页面、CLI命令、CSV导出都读写这张表。没有中间缓存没有异步队列SQLite就是单一真相源。核心功能五节点状态机与三重数据注入系统围绕“五节点状态机”构建主干逻辑applied → in_transit → received → testing → reported。每个状态有明确定义和进入条件例如in_transit必须填写leave_timereceived必须填写return_time而reported则依赖PDF解析成功并填入至少一个检测字段。这五个状态不是静态标签而是驱动后续动作的开关。比如当状态为testing且return_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并导入demopython -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_urlPDF文件本地路径或HTTP链接Web上传后自动生成状态为reported时必填linked_apply_id关联的原始申请单号如OA流水号可选用于跨系统追溯是status当前所处状态节点仅限五值之一由时间戳填写自动推导或手动切换否特别说明status不是独立维护字段而是由各时间戳存在与否自动计算得出。例如当apply_time存在但leave_time为空状态即为applied当leave_time和return_time均存在但result_received_time为空状态即为received。这种设计避免状态与时间戳人为不一致。工程结构模块职责清晰扩展成本可控整个项目按能力切分为六个主模块每个目录对应单一职责无交叉引用目录路径职责说明典型文件src/data/数据解析与入库CSV读取、字段校验、SQLite写入csv_parser.py,db.pysrc/llm/PDF语义解析调用大模型API、定义prompt模板、清洗提取结果pdf_extractor.py,prompts.yamlsrc/rules/告警规则引擎DSL解析器、条件求值器、动作执行器dsl_parser.py,engine.pysrc/output/web/Web界面FastAPI路由、Jinja2模板、状态渲染逻辑main.py,templates/samples.htmlsrc/output/cli/命令行界面Argparse参数定义、交互逻辑、输出格式化__main__.py,commands.pysrc/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