ARTICLE DETAIL

资讯详情

深耕网站建设与运营推广的一线实战洞察。

OpenMed FHIR ValueSet 与 ECL 展开实战:本地扩展展开、术语服务器委托与可审计缓存

OpenMed FHIR ValueSet 与 ECL 展开实战:本地扩展展开、术语服务器委托与可审计缓存 OpenMed FHIR ValueSet 与 ECL 展开实战本地扩展展开、术语服务器委托与可审计缓存【免费下载链接】openmedLocal-first healthcare AI: clinical NER HIPAA PII de-identification that runs 100% on-device. 2,200 medical models, 21 languages, Apple MLX Python, no cloud, no patient data leaving your network. Apache-2.0项目地址: https://gitcode.com/GitHub_Trending/ope/openmedOpenMed 提供了一套 local-first 的 FHIRValueSet展开expansion能力既可以在本机对 extensional外延式ValueSet 直接展开成员码也可以把 canonical ValueSet URL 或 SNOMED CT 的 ECLExpression Constraint Language表达式约束语言表达式显式委托给你指定的术语服务器。整个模块不捆绑任何默认词汇与端点导入或使用本地路径时不会创建网络客户端。读完本文你将掌握本地展开与远程委托的完整用法、展开结果的溯源契约provenance以及如何安全地启用可选缓存。展开的本质从 intension 到确定性的 extensionFHIR 的ValueSet可以只描述如何选码compose中的 intension/intensional 规则例如整码系统、过滤器、is-a层级而消费方通常需要一份具体的成员码列表extension/extensional 展开结果。OpenMed 的展开器把这件事收敛成两个清晰的分支本地展开基于调用方自行加载的自由词汇free vocabulary在内存中完成 extensional 展开全程离线远程委托只有当你显式传入endpoint时才会把 canonical URL 或 ECL 发送给外部 FHIR 术语服务器求值。无论走哪条路径结果都是同一个ValueSetExpansion一个不可变成员码集合附带 system 感知的codings与确定性provenance。溯源记录包含 ValueSet 或响应版本、展开方法、词汇发布版本 pin 以及请求/响应 SHA-256 摘要并且不会把原始 ECL 复制进报告或缓存元数据。从源码结构看这一能力由 openmed/clinical/grounding/valueset.py约 1700 行实现模块 docstring 明确声明The engine expands extensional FHIR ValueSet resources entirely in memory over caller-loaded, redistributable vocabularies即不在引擎内部捆绑任何术语内容除非调用方提供缓存否则绝不持久化展开成员。执行入口与输入类型判定推荐入口是模块级函数expand_valueset它内部构造ValueSetExpansionEngine后调用engine.expand_valueset(...)。引擎公开的构造参数如下valueset.py参数默认值说明endpointNone调用方提供的 FHIR 术语服务基地址省略时不创建网络客户端、不发任何请求vocabulariesNone按 canonical system URI 键控的自由词汇值可为TerminologySnapshot、VocabularyIndex、loader 对象或 term→concept 映射vocabulary_registryNone可选的自由词汇 loader 注册表用于兜底加载vocabularies中缺失的 systemcache/cache_dirNone可选缓存两者不能同时传入allow_restricted_cacheFalse是否允许把受限制restricted成员码写入cache_dirbearer_tokenNone调用方提供的 Bearer Token绝不进入对象表示与错误信息timeout30.0远程请求超时秒page_size/max_pages/max_members1000/100/1_000_000远程分页大小、最大页数与最大唯一成员数ecl_system_uriSNOMED CT 系统 URI构造 ECL 隐式 ValueSet URL 时使用的 SNOMED 版本基地址expand_valueset的第一个参数url_or_ecl的类型决定了走哪条路径valueset.pyMappingFHIR JSON 字典或PathLike本地路径→ 本地展开以{/[开头或指向真实文件的字符串 → 按本地 JSON 展开匹配 URI scheme 的绝对 URL → 远程ValueSet/$expand其他非路径字符串 → 先做保守的 ECL 语法校验再远程委托。注意当字符串同时携带|version后缀且显式传入的version不一致时会直接抛ValueErrorcanonical and requested ValueSet versions differ。本地展开 extensional ValueSet最小可用示例把调用方加载的自由词汇这里用合成数据演示与TerminologySnapshot一起传给expand_valuesetfrom openmed.clinical.grounding import ( TerminologySnapshot, VocabConcept, VocabularyIndex, expand_valueset, ) system http://human-phenotype-ontology.org index VocabularyIndex( hpo, [ VocabConcept(hpo, HP:0001250, Synthetic example one), VocabConcept(hpo, HP:0001263, Synthetic example two), ], ) snapshot TerminologySnapshot( indexindex, system_urisystem, release_version2026.09, content_hashindex.content_hash, ) value_set { resourceType: ValueSet, url: https://example.org/fhir/ValueSet/synthetic-example, version: 1.0.0, compose: {include: [{system: system, version: 2026.09}]}, } expanded expand_valueset(value_set, vocabularies{system: snapshot}) assert expanded.members frozenset({HP:0001250, HP:0001263}) assert expanded.version 1.0.0这里的关键在于compose.include中的system必须能在vocabularies中找到对应的已加载词汇。VocabularyIndex是对单一词汇系统做别名索引的映射式容器vocab.pyVocabConcept则携带system、code、preferred_term以及可选synonyms与多语言别名vocab.py。TerminologySnapshot会把VocabularyIndex与system_uri、release_version、content_hash绑定并在构造时校验content_hash与索引一致snapshot_cache.py。本地支持与明确拒绝的边界本地展开是刻意地 extensional其支持面由 valueset.py 的_local_members/_expand_local_clause决定支持的 include 形式显式compose.include.concept条目code 可选display并会跳过abstract: true的概念整码系统或 code/display 过滤器子句但必须加载对应的自由词汇完整的expansion.contains条目要求offset为空或 0且total不大于条目数否则视为分页/不完整而拒绝compose.exclude排除子句与 include 取差集。明确拒绝并抛出ValueSetExpansionUnsupportedError的情况嵌套 ValueSet 引用clause.valueSet、is-a/descendent-of等层级运算符、术语专属属性过滤器。文档与源码的一致态度是不要猜测显式把这些定义送到术语服务器。本地过滤器的安全子集仅支持code/concept、system、display这几个属性运算符仅支持/、regex与exists见_local_filters_matchvalueset.py其他运算符一律抛ValueSetExpansionUnsupportedError。还有一个值得注意的策略边界如果某个 include/filter 子句指向受限制系统restricted system本地路径会直接抛ValueSetExpansionPolicyError提示必须走配置好的进程外术语端点valueset.py。受限制系统的判定见_is_restrictedvalueset.py基于RESTRICTED_SYSTEM_URIS归一化后做精确匹配并对包含cpt的系统 URI 额外敏感。委托 FHIR$expand或 ECL 表达式一旦提供endpoint输入就被视为远程委托请求canonical URL→ 调用ValueSet/$expand携带 FHIR 的url参数源码中同时以valueSetVersion传版本任何非路径字符串→ 先做 ECL 语法校验再包装为 SNOMED CT 隐式 ValueSet URLhttp://snomed.info/sct?fhir_vsecl/exprcanonical 可以带标准的|version后缀对 ECL版本通过system-version参数发送格式为ecl_system_uri|version当端点使用特定 SNOMED 版本基地址时用ecl_system_uri显式指定。from openmed.clinical.grounding import expand_valueset expanded expand_valueset( https://example.org/fhir/ValueSet/findings|2026.09, endpointhttps://terminology.example/fhir, bearer_tokencaller-owned-secret, ) descendants expand_valueset( *, # Replace with an ECL expression licensed for your endpoint. version2026.09, endpointhttps://terminology.example/fhir, bearer_tokencaller-owned-secret, )远程展开的底层细节与安全约束从 valueset.py 的_expand_remote可以看到完整链路端点拼接规则_expand_operation_url以/结尾会先剥离已以/$expand结尾则原样使用否则追加/ValueSet/$expand请求头固定携带Accept: application/fhirjson, application/json可叠加调用方headersBearer Token 通过Authorization头注入且绝不落入对象表示与异常信息分页首请求带count后续页携带offset每次响应都要通过_validate_remote_payloadvalueset.py——OperationOutcome直接失败resourceType必须为ValueSet必须存在expansion跨页一致性校验响应 ValueSeturl、version、expansion.identifier、expansion.total必须逐页一致返回的offset必须与请求的next_offset一致分页必须前进candidate_offset next_offset累计成员不得超过声明的total任何不一致都抛ValueSetExpansionResponseError上限控制单响应读取上限_MAX_RESPONSE_BYTES 16 MiB超过max_pages默认 100 页或max_members默认 100 万即失败重定向被拒绝标准库传输使用禁掉重定向的 opener_open_without_redirectsvalueset.py防止凭据被带到其他主机远程结果中含受限制术语时会被标记restrictedTrue默认不落盘。许可证边界务必知悉ECL 通常面向 SNOMED CT 或其他需要许可的术语体系。OpenMed 不随附、不安装、不许可这类内容也不会静默回退到未许可内容。端点运营与术语授权需由你自己完成——这正是模块刻意不配置默认端点的原因。ECL 语法校验器本身也是 fail-closed 的它只校验约束外壳并询问你提供的ECLResolverecl.py模块内不含任何术语内容与网络客户端。可选展开缓存默认关闭按需开启OpenMed默认没有任何展开缓存。只有显式提供缓存路径或复用配置好的TerminologySnapshotCache持久化才会发生from openmed.clinical.grounding import ( ValueSetExpansionCache, ValueSetExpansionEngine, ) cache ValueSetExpansionCache(/caller/controlled/terminology-cache) engine ValueSetExpansionEngine( vocabularies{system: snapshot}, cachecache, ) expanded engine.expand_valueset(value_set)缓存实现的要点valueset.py命名空间条目位于缓存根目录的expansions/子命名空间下每项由manifest.jsonexpansion.json组成缓存键是对「source kind canonical URL 或 ECL 解析版本」整体哈希得到的 64 位十六进制目录名_cache_key内容净化产物只包含 system/version/code 成员与不含原始查询的 provenance不包含 display、凭据或 ECL读取时会用 manifest 中的artifact_sha256校验产物摘要sha256:前缀 64 位十六进制任何不一致都视为未命中大小上限产物上限 64 MiB、manifest 上限 64 KiB_MAX_CACHE_ARTIFACT_BYTES/_MAX_CACHE_MANIFEST_BYTES受限制成员默认不写入默认策略下store遇到 restricted 展开会抛ValueSetExpansionPolicyError引擎也会静默跳过受限结果的落盘因此远程受限结果只驻留内存重复调用会再次请求端点。只有显式控制缓存并额外开启策略时才会持久化restricted_cache ValueSetExpansionCache( /caller/controlled/restricted-cache, allow_restrictedTrue, )缓存的生命周期、访问控制、加密、许可与删除始终是调用方的责任可用ValueSetExpansionCache.from_snapshot_cache(cache)复用术语快照缓存的根目录与受限内容策略或者直接给引擎传TerminologySnapshotCache引擎会自动转换。结果契约与溯源字段ValueSetExpansion实现为collections.abc.Set[str]的子类valueset.py迭代与成员判断都作用于纯码集合同时保留 system 信息members/codes/member_codes不可变纯码集合frozenset[str]codings稳定的ValueSetMember(system, code, version)元组支持跨码系统场景ValueSetMember还提供key不含版本的稳定码身份与to_dict()确定性 FHIR Coding 子集version请求版本或服务端声明版本两者都不存在时使用确定性的 SHA-256 内容戳sha256:前缀provenanceExpansionProvenancevalueset.pysource_kindlocal/valueset-url/eclmethodlocal-extensional、remote-fhir-expand或remote-ecl-delegationversion解析后的版本request_sha256绑定输入canonical URL、本地 ValueSet JSON 或 ECL 的摘要而不暴露原始 ECLresponse_sha256绑定排序后的成员与它们的版本_members_digestvocabulary_versions成员涉及的 (system, version) pin 元组restricted/cache_hit是否含受限成员、是否为缓存命中。两条值得一提的绑定语义本地缓存身份同时绑定「提供的 ValueSet 定义」与「解析出的成员」——重新加载词汇或修改定义后即使 URL 和 version 相同也无法复用陈旧条目本地路径的 source 身份是urn:openmed:valueset:{payload_hash}:{response_hash}valueset.py远程缓存身份额外绑定配置的 endpoint 与 ECL systemValueSet 版本与码系统版本 pin 相互独立。错误体系与 fail-closed 原则展开模块的异常层次valueset.py异常触发场景ValueSetExpansionError基类ValueSetExpansionConfigurationError远程展开缺少安全配置未提供端点、端点非绝对 HTTP(S) URL、端点 URL 携带凭据/query/fragment、非法请求头等ValueSetExpansionResponseError响应非 FHIR JSON、OperationOutcome、缺expansion、页间不一致、超页/超成员上限、分页未前进、响应过大ValueSetExpansionUnsupportedError本地遇到嵌套 ValueSet 引用、层级/术语属性运算符、需要词汇而未加载、本地展开分页或不完整ValueSetExpansionPolicyError受限术语跨越不允许的边界如未经allow_restricted就持久化受限成员、本地展开受限系统远程委托的整体策略是fail-closed任何不满足条件的响应OperationOutcome、不完整本地页、不一致远程页、超限都直接失败绝不部分接受。工程佐证测试与相邻能力单元测试 tests/unit/clinical/grounding/test_valueset.py 覆盖了本地展开、include/exclude、restricted 策略ValueSetExpansionPolicyError、远程客户端注入HTTPX 兼容 client等路径并验证展开结果对词汇加载顺序不敏感reversed_order快照断言佐证确定性契约本地load_valueset载荷解析复用 openmed/clinical/exporters/valueset.py离线 FHIR R4 ValueSet 成员校验模块它同样遵循不接触术语服务器、不捆绑词汇的原则引擎的定位是为 grounding概念锚定与导出工作流约束术语——它不做任何临床决策也不替代术语治理与许可审查。落地建议能用本地就不发远程显式concept条目、code/display 过滤器与完整expansion.contains都可以离线展开先评估你的 ValueSet 是否落入这些形态层级与嵌套显式委托is-a、descendent-of、嵌套 ValueSet 引用必须走术语端点OpenMed 不会替你猜缓存按需且自控默认无缓存是最安全的默认值开启缓存后自行负责生命周期、访问控制、加密与删除受限内容务必配合allow_restrictedTrue并独立管控凭据零落盘Bearer Token 与自定义头只存在于本次请求不进表示、不进错误、不进缓存产物ECL 内容合规先行确认你的 ECL 表达式与端点授权再把它写进生产代码。【免费下载链接】openmedLocal-first healthcare AI: clinical NER HIPAA PII de-identification that runs 100% on-device. 2,200 medical models, 21 languages, Apple MLX Python, no cloud, no patient data leaving your network. Apache-2.0项目地址: https://gitcode.com/GitHub_Trending/ope/openmed创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考
返回列表