严重度:高(临床安全性 / 危急值静默丢失)
标签建议:bug(clinical)
现象
doctoragent/clinical/integrations/cds_hooks/service.py:230 的守卫把 labs 提取与 vitals 是否已由厂商扩展提供绑死:
if observations and "vitals" not in patient_context:
vitals, labs = _extract_vitals_labs(observations)
if vitals:
patient_context["vitals"] = vitals
if labs and "labs" not in patient_context:
patient_context["labs"] = labs
当 CDS Hooks 请求里 patient_context 已含 vitals(例如 EHR 通过厂商扩展传入 context.vitals)时,守卫为 False,整个 _extract_vitals_labs(observations) 不执行。而 context.labs 并非 CDS Hooks 标准 context 字段,厂商通常在给 context.vitals 时不会同时给 context.labs,于是从 observations(FHIR Bundle)里本应抽出的 labs——含危急钾/钠等——被整体丢弃,规则引擎完全看不到危急值。
证据
复现(来源 /tmp/repro_cds_labs.py):
- 场景 A(无
context.vitals):patient_context["labs"] 含 sodium 118.0(危急),规则引擎命中危急值。
- 场景 B(带
context.vitals):patient_context["labs"] 为 None / 0 条,危急钠被漏掉,规则引擎无任何告警。
影响
真实 EHR 在 patient-view / order-sign 钩子里常通过 context.vitals 提供体征;此时若 labs 仍走 observations 抽取,会被本守卫静默吞掉。结果是危急检验值(高/低钾、低钠等)不触发安全规则,直接危害临床决策——对 iCAN 演示与院内部署都是硬伤。
建议修复
labs 与 vitals 的抽取应解耦:observations 存在且 labs 尚未被显式提供时,应始终抽取 labs;vitals 同理单独判断。即把守卫改为分别判断 labs 与 vitals 是否已提供,而不是用 vitals 的有无去 gate labs。
关联
与 #6 / #7 / #8 同属"危急值评估链路的正确性"一类。
现象
doctoragent/clinical/integrations/cds_hooks/service.py:230的守卫把 labs 提取与 vitals 是否已由厂商扩展提供绑死:当 CDS Hooks 请求里
patient_context已含vitals(例如 EHR 通过厂商扩展传入context.vitals)时,守卫为False,整个_extract_vitals_labs(observations)不执行。而context.labs并非 CDS Hooks 标准context字段,厂商通常在给context.vitals时不会同时给context.labs,于是从observations(FHIR Bundle)里本应抽出的 labs——含危急钾/钠等——被整体丢弃,规则引擎完全看不到危急值。证据
复现(来源
/tmp/repro_cds_labs.py):context.vitals):patient_context["labs"]含sodium 118.0(危急),规则引擎命中危急值。context.vitals):patient_context["labs"]为None/ 0 条,危急钠被漏掉,规则引擎无任何告警。影响
真实 EHR 在
patient-view/order-sign钩子里常通过context.vitals提供体征;此时若 labs 仍走observations抽取,会被本守卫静默吞掉。结果是危急检验值(高/低钾、低钠等)不触发安全规则,直接危害临床决策——对 iCAN 演示与院内部署都是硬伤。建议修复
labs 与 vitals 的抽取应解耦:
observations存在且labs尚未被显式提供时,应始终抽取 labs;vitals 同理单独判断。即把守卫改为分别判断labs与vitals是否已提供,而不是用vitals的有无去 gate labs。关联
与 #6 / #7 / #8 同属"危急值评估链路的正确性"一类。