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 资源,而是一组经过装配的“事实”。以一条“血钾偏低”规则为例,输入事实至少需要:患者标识、就诊标识、检验项目编码(LOINC 2823-3 对应血钾)、结果值、单位、参考范围、采样时间。FHIR Observation 中这些字段分散在 code、valueQuantity、referenceRange、effectiveDateTime 中,接口层必须做映射与归一。
建模时建议明确三类语义:
- 存在性:事实是否存在。缺失不等于阴性,例如“未记录过敏史”不能当作“无过敏”。
- 时效性:事实是否在有效窗口内。血钾结果超过 24 小时,规则应降级或提示重新检验。
- 单位与量纲:mmol/L 与 mg/dL 必须统一,否则阈值判断会出错。
三、集成方式与接口设计
规则引擎与 EMR/HIS 的集成,常见有四类方式,选择取决于实时性、侵入性和运维成本。
| 集成方式 | 典型协议/技术 | 适用场景 | 注意点 |
|---|---|---|---|
| CDS Hooks | HTTP + JSON,由 EMR 在特定时机调用 | 开医嘱、看诊时实时提醒 | 需 EMR 支持 hook 触发点,返回卡片需符合规范 |
| FHIR 订阅/轮询 | FHIR Subscription、REST 轮询 | 检验结果回传后触发规则 | 注意去重、延迟与失败重试 |
| 消息中间件 | HL7 v2、Kafka、MQ | HIS 已有消息总线,批量事件驱动 | 消息顺序与幂等性 |
| 数据库视图/存储过程 | 只读视图、定时任务 | 老旧系统无标准接口 | 耦合高,需控制查询频率与权限 |
接口设计上,建议把“输入接口”和“输出接口”分开定义。输入接口负责把 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 超窗,则输出“数据过期,建议复查”而非直接告警。这种设计把数据质量判断前置到接口层,规则本身保持简洁。
综上,FHIR、CDA、OpenEHR 各自解决不同层次的问题,规则引擎真正需要的是稳定的患者上下文事实模型。集成方式的选择应围绕实时性、侵入性和可维护性权衡,接口设计的关键是把“标准差异”收敛在装配层,让规则引擎专注于临床逻辑本身。