:本地医疗 AI 场景下的不透明关联标识符设计)
OpenMed Agent 事件关联Event Correlation本地医疗 AI 场景下的不透明关联标识符设计【免费下载链接】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.agent.correlation为本地 Agent 运行run与动作action提供不透明关联标识符用于在不嵌入患者、用户、工作流或工具内容的前提下完成事件串联。本文基于 docs/agent/event-correlation.md 展开并结合 openmed/agent/correlation.py 与 tests/unit/agent/test_correlation.py 的源码级实现讲解标识符格式、隐私边界、严格校验语义以及配套的序列化契约。读完本文你将掌握如何在本地医疗 AI 工作流中安全地生成、解析与序列化关联标识符并理解失败关闭fail closed校验在去标识化场景中的关键价值。关联标识符解决什么问题OpenMed 定位为 Local-first 医疗 AI临床 NER 与 HIPAA PII 去标识化全部在设备本地运行患者数据不允许离开网络。在这种场景下Agent 的一次运行可能包含多个动作检索、脱敏、抽取、FHIR 组装等运维与审计需要把分散的动作日志串成一条时间线——但串联手段绝不能泄露临床内容。correlation模块的答案非常明确用随机生成的不透明标识符代替任何业务内容。它只回答哪次运行、哪个动作、父动作是谁而不回答处理了哪个患者、哪个文件、哪段文本。这与仓库中 docs/agent/timing-metadata.md 描述的单调计时元数据只含相对纳秒边界与时长不含墙钟时间与 PHI互为补充计时记录何时发生关联标识符记录属于谁两者都不携带业务负载。标识符格式与生成固定前缀 128 位随机令牌规范格式由两部分组成Run 标识符run_前缀 32 个小写十六进制字符Action 标识符act_前缀 32 个小写十六进制字符十六进制令牌恰好为 16 字节128 位源码中以常量固化CORRELATION_TOKEN_BYTES: Final 16 RUN_ID_PREFIX: Final run_ ACTION_ID_PREFIX: Final act_对应实现见 openmed/agent/correlation.py。128 位随机性为海量本地运行提供了足够的碰撞余量同时标识符本身不含任何可推断业务含义的信息。运行时生成不接收业务内容生成 API 的唯一职责是从随机源取出 16 字节并加上前缀from openmed.agent import ActionCorrelation, ActionId, RunId run_id RunId.generate() parent_id ActionId.generate() action_id ActionId.generate() correlation ActionCorrelation( run_idrun_id, action_idaction_id, parent_action_idparent_id, ) payload correlation.to_json()从实现看generate()默认走secrets.token_bytescorrelation.py这是 Python 标准库的密码学安全随机源保证每次调用结果不可预测。函数签名刻意不接受任何源内容参数——你无法把文件名、提示词或临床文本塞进生成器从接口层面杜绝了误用。token_source仅供确定性离线测试generate()的token_source参数是唯一例外它允许注入一个返回字节序列的可调用对象def fixed_token(token: bytes): def source(size: int) - bytes: assert size CORRELATION_TOKEN_BYTES return token return source run_id RunId.generate(token_sourcefixed_token(RUN_TOKEN))用途仅限于确定性离线测试见 tests/unit/agent/test_correlation.py。如果注入的源不可调用、返回非 bytes、或字节长度不等于 16会抛出CorrelationIdError(invalid_token_source, field_name)且异常消息中不会回显被注入的失败值。生产环境应始终使用默认的secrets.token_bytes。隐私边界不派生、不编码、不持久化这是整个模块的设计核心文档与实现互相印证禁止派生不得通过哈希或编码提示词、临床文本、文件名、用户 ID、工具参数、模型输出等任何工作流内容来生成标识符解析 ≠ 编码parse()仅用于解析此前生成的规范标识符不是把业务数据变成标识符的通道不持久化模块本身不存储事件、不实现分布式追踪、不编码患者或操作者身份。从源码结构看这一边界由三层机制保障生成端generate()只接受随机源无内容入口解析端_validate_identifiercorrelation.py只做纯语法形状校验绝不尝试从字符串中解读任何语义表示端标识符类的__repr__返回RunId(opaque)形式correlation.py即使在日志、调试器或异常追溯中也不会泄露标识符本体更不用说业务内容。测试也验证了这一点test_default_generation_produces_canonical_opaque_ids断言run_id.value not in repr(run_id)test_token_source_exception_is_replaced_with_value_free_error用一段模拟的患者文本作为异常载荷断言该文本不会出现在格式化的异常追溯中test_correlation.py。严格校验失败关闭绝不规整化规范解析语义解析是规范化的canonical大写、缩短、加长、畸形、错类别的标识符一律拒绝而不是被修正。测试覆盖了典型攻击面test_correlation.py输入结果run_ 32 个大写字符invalid_identifierrun_ 31 或 33 个 hex 字符invalid_identifierrun_ 32 个g非 hexinvalid_identifieract_开头的串传给RunId.parse()wrong_identifier_kindrun_开头的串传给ActionId.parse()wrong_identifier_kind布尔值、整数invalid_identifier注意_validate_identifier的实现细节即使令牌部分合法只要前缀与目标类别不符就明确报wrong_identifier_kind而不是静默换类别correlation.py。ActionCorrelation 的结构约束ActionCorrelation是一个不可变数据类frozenTrue, slotsTrue在__post_init__中做四类校验correlation.pyrun_id必须是RunId类型action_id与parent_action_id必须是ActionId类型——类型错误报wrong_identifier_kind动作不能把自己作为父动作——报self_parentschema_version必须精确等于openmed.agent.correlation.v1——否则报invalid_schema_version三个标识符字段类型必须精确匹配type(x) is not RunId而非isinstance防止子类混入。测试test_action_cannot_parent_itself验证了自引用被拒绝且标识符值不会出现在异常消息中test_correlation.py。反序列化的严格入口from_dict与from_json的严格程度值得单独说明非映射对象字符串、列表、整数报not_a_mapping未知字段如混入prompt报unknown_field且不会在异常中回显该字段的值——测试用模拟的Patient John Doe bearer-token验证了这一点test_correlation.py缺少run_id或action_id报missing_fieldJSON 解析使用object_pairs_hook_strict_json_objectcorrelation.py重复键直接报malformed_json防止键覆盖歧义畸形 JSON{、非法字节、整数统一报malformed_json。错误契约稳定错误码 公开字段名CorrelationIdError继承自ValueError携带两个稳定诊断属性class CorrelationIdError(ValueError): def __init__(self, code: str, field_name: str | None None) - None: self.code code self.field_name field_name message code if field_name is None else f{field_name}: {code} super().__init__(message)code机器可读的稳定错误码如wrong_identifier_kind、self_parent、unknown_field、malformed_jsonfield_name公开字段名run_id、action_id、parent_action_id、schema_version。被拒绝的值绝不进入异常消息、参数、属性或对象表示。这保证了日志与错误上报系统永远不会因异常而间接落盘 PHI——与 docs/agent/event-correlation.md 中Rejected values are not included in exception messages or object representations的承诺完全一致。序列化契约与确定性输出ActionCorrelation.to_dict()返回仅含元数据的四字段字典且键序确定correlation.pyschema_version, run_id, action_id, parent_action_id根动作无父动作序列化时parent_action_id显式为Noneis_root_action属性返回True。to_json()输出紧凑 JSONsort_keysTrue, separators(,, :)键序确定性保证同一对象每次序列化字节一致便于做审计指纹与日志去重。测试断言了 round-trip 一致性from_dict(to_dict()) correlation、from_json(to_json()) correlationtest_correlation.py。在 Agent 元数据体系中的位置关联标识符并非孤立设计它是 OpenMed Agent 安全元数据体系的一部分与 docs/agent/governance-identifiers.md 中的治理标识符形成明确分工契约类别来源用途RunId/ActionId不透明随机标识符secrets.token_bytes生成事件关联CapabilityId/PurposeId/PolicyId/WorkflowId/ToolId开发人员命名的稳定名称人工编写policy:org.example/default0.1.0形式治理元数据命名两者在解析器层面完全隔离ToolId.parse()只接受tool:标识符RunId.parse()只接受run_标识符互不重分类。同时计时元数据openmed/agent/timing.py中的correlation_id字段也采用保守不透明字母表 拒绝路径/URL/自由文本的校验策略timing.py与关联标识符的隐私目标一致。整条链路关联 → 计时 → 结果汇总都在贯彻同一原则元数据可以详细但绝不能成为 PHI 的载体。如何验证运行聚焦测试仓库为correlation模块提供了完整的离线测试覆盖生成、解析、失败关闭、序列化与公开 API 契约uv run --frozen --extra dev pytest tests/unit/agent/test_correlation.py -q该测试文件还通过test_correlation_contract_is_exported_from_public_agent_api校验openmed.agent包级导出RunId、ActionId、ActionCorrelation、CorrelationIdError及各常量确保公共 API 面与实现保持一致test_correlation.py。关键设计清单标识符 run_/act_前缀 128 位随机令牌生成过程不接收任何业务内容解析严格规范化大写、畸形、错类别一律拒绝报错带稳定错误码与公开字段名不回显被拒绝值ActionCorrelation强制 run/action 类型分离、禁止自父引用、固定 schema 版本JSON 反序列化拒绝未知字段、重复键与畸形负载模块不持久化、不追踪、不编码身份生产环境请勿注入token_source。【免费下载链接】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),仅供参考