4. 临床数据模型与规则输入接口

规则引擎本身并不“懂”临床,它只认识结构化的事实。CDS 能否给出正确建议,首先取决于患者上下文是否被准确、完整、及时地送进规则引擎。本节聚焦三件事:临床数据标准如何承载患者上下文、规则输入接口如何建模、以及规则引擎与 EMR/HIS 之间用哪种集成方式落地。

一、三种临床数据标准的定位差异

FHIR、CDA、OpenEHR 常被并列讨论,但它们的抽象层次和用途并不相同,选型时不能只看“谁更流行”。

  • FHIR(Fast Healthcare Interoperability Resources):面向资源与 RESTful 交互,资源粒度细(Patient、Observation、MedicationRequest、Condition 等),天然适合作为规则引擎的实时输入接口。规则引擎通常按资源类型订阅或拉取,把 Observation 映射为“检验/体征事实”,把 MedicationRequest 映射为“用药事实”。
  • CDA(Clinical Document Architecture):面向文档交换,一份 CDA 是一个临床文档(如出院小结、会诊记录),带章节(section)和条目(entry)层级。它适合批量、归档、跨机构交换,但实时性弱,规则引擎读取时往往需要先解析文档结构再抽取事实。
  • OpenEHR:以原型(archetype)和模板(template)驱动,强调语义稳定的临床信息模型,适合长期数据治理与多机构语义对齐。它不直接规定传输协议,规则引擎接入时通常通过 OpenEHR CDR 的查询接口(如 AQL)获取组合(Composition)数据。

一个常见的工程判断是:实时规则输入优先 FHIR,历史/文档类输入用 CDA 解析,语义治理层用 OpenEHR 建模。三者不是互斥关系,而是分层协作。

临床数据标准 → 患者上下文 → 规则引擎输入接口 数据源 / 标准层 FHIR R4 Patient / Observation MedicationRequest / Condition CDA R2 文档章节 section 条目 entry / 文本 narrative OpenEHR Archetype / Template Composition / AQL 查询 EMR / HIS 原生表 视图 / 存储过程 / 消息 患者上下文模型(Context) 身份与就诊上下文 patientId · encounterId · 就诊类型 临床事实集合 诊断 · 检验 · 体征 · 用药 · 过敏 时间与时效 effectiveDateTime · 数据新鲜度 术语与编码 LOINC · SNOMED CT · ICD-10 缺失与冲突处理 空值语义 · 单位换算 · 多源冲突 → 决定规则是否可触发 规则引擎输入接口 事实装配 Fact Builder 标准资源 → 规则事实对象 字段映射 + 单位归一 触发与订阅 CDS Hooks / 事件订阅 定时批量 / 手动触发 规则执行 条件匹配 · 优先级 · 冲突消解 输出建议 / 告警 / 提醒 回写与反馈 CDS 建议回传 EMR 医生采纳/忽略记录 审计日志 · 可追溯 关键:标准只负责“表达”,接口负责“装配”,规则引擎只消费装配后的事实

二、患者上下文建模:从资源到事实

规则引擎的输入不是原始 FHIR 资源,而是一组经过装配的“事实”。以一条“血钾偏低”规则为例,输入事实至少需要:患者标识、就诊标识、检验项目编码(LOINC 2823-3 对应血钾)、结果值、单位、参考范围、采样时间。FHIR Observation 中这些字段分散在 code、valueQuantity、referenceRange、effectiveDateTime 中,接口层必须做映射与归一。

建模时建议明确三类语义:

  • 存在性:事实是否存在。缺失不等于阴性,例如“未记录过敏史”不能当作“无过敏”。
  • 时效性:事实是否在有效窗口内。血钾结果超过 24 小时,规则应降级或提示重新检验。
  • 单位与量纲:mmol/L 与 mg/dL 必须统一,否则阈值判断会出错。
建议在接口层维护一张“标准编码 → 规则事实字段”的映射表,把 LOINC、SNOMED CT、ICD-10 的编码统一映射到规则引擎内部字段名,避免规则直接依赖外部编码。

三、集成方式与接口设计

规则引擎与 EMR/HIS 的集成,常见有四类方式,选择取决于实时性、侵入性和运维成本。

集成方式典型协议/技术适用场景注意点
CDS HooksHTTP + JSON,由 EMR 在特定时机调用开医嘱、看诊时实时提醒需 EMR 支持 hook 触发点,返回卡片需符合规范
FHIR 订阅/轮询FHIR Subscription、REST 轮询检验结果回传后触发规则注意去重、延迟与失败重试
消息中间件HL7 v2、Kafka、MQHIS 已有消息总线,批量事件驱动消息顺序与幂等性
数据库视图/存储过程只读视图、定时任务老旧系统无标准接口耦合高,需控制查询频率与权限

接口设计上,建议把“输入接口”和“输出接口”分开定义。输入接口负责把 FHIR/CDA/OpenEHR 数据装配为事实;输出接口负责把规则结果以 CDS Hooks 卡片、FHIR Communication、或 HIS 消息的形式回传。两者之间通过规则引擎内部的事实模型解耦,这样更换数据标准时只需改装配层,不必重写规则。

四、一个可参考的接口字段示例

下面给出规则输入接口中“检验事实”的字段定义示例,用于说明装配层应输出什么。字段为示例设计,实际项目应按机构术语体系调整。

{
  "patientId": "P2024001",
  "encounterId": "E20240520-003",
  "factType": "labResult",
  "code": "LOINC:2823-3",
  "display": "血钾",
  "value": 3.1,
  "unit": "mmol/L",
  "referenceLow": 3.5,
  "referenceHigh": 5.3,
  "effectiveDateTime": "2024-05-20T08:15:00+08:00",
  "source": "FHIR:Observation/obs-8821",
  "freshnessMinutes": 35
}

规则侧只需判断 value < referenceLow 且 freshnessMinutes <= 1440,即可触发“低钾提醒”。若 freshnessMinutes 超窗,则输出“数据过期,建议复查”而非直接告警。这种设计把数据质量判断前置到接口层,规则本身保持简洁。

不要把 EMR 的原始字段名直接暴露给规则。一旦 EMR 升级或字段调整,规则会大面积失效。装配层应作为稳定边界,对外只暴露规则事实模型。

综上,FHIR、CDA、OpenEHR 各自解决不同层次的问题,规则引擎真正需要的是稳定的患者上下文事实模型。集成方式的选择应围绕实时性、侵入性和可维护性权衡,接口设计的关键是把“标准差异”收敛在装配层,让规则引擎专注于临床逻辑本身。