OpenMed Python API 完全参考:PII 提取、去标识化、可逆重标识与结构化错误体系
2026/9/17 17:06:02 网站建设 项目流程

OpenMed Python API 完全参考:PII 提取、去标识化、可逆重标识与结构化错误体系

【免费下载链接】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

导读

本文以 OpenMed 官方 API 参考(docs/api-reference.md)为主线,结合仓库源码(openmed/core/pii.py、openmed/core/errors.py、openmed/init.py 等)逐项解读顶层公开 API。你将掌握extract_piideidentifyreidentify三大 PII 核心函数及analyze_textlist_modelsBatchProcessor等配套能力的完整签名、参数语义与实战用法,理解从检测到脱敏、再到可审计重标识的全链路编程模型,并学会用统一的OpenMedError错误树(含 REST/MCP 映射)安全地处理失败。所有结论均可回溯到当前仓库源码,适用于在本地构建 HIPAA 合规的临床文本处理管线。

1. 快速上手与公共 API 表面

OpenMed 的顶层包openmed采用**惰性导入(lazy import)**机制:openmed/init.py 中的__getattr__会在首次访问符号时才从对应子模块加载,__dir__()则暴露全部可发现的顶层导出。这意味着import openmed本身开销极低,且只有真正用到的能力才会被加载——对端侧部署与冷启动敏感场景友好。

顶层 API 分组(见 openmed/init.py 的__all__)大致包括:

  • PII 检测与去标识化extract_piideidentifyreidentifyPIIEntityDeidentificationResult
  • 通用 NER 分析analyze_textAnalyzeResult
  • 模型发现list_modelsget_model_infoget_models_by_categorysearch_modelsget_default_pii_model等;
  • 批处理与文档流BatchProcessorprocess_batchredact_datasetdeidentify_document_stream
  • 结构化错误OpenMedError及其十个子类、ERROR_CODESredact_detail
  • PDF 处理openmed.multimodal下的render_redacted_pdfverify_redacted_pdfverify_redacted_text_removedmeasure_pdf_layout_fidelity
  • 可观测性openmed.core.telemetry.PipelineTelemetryStageTelemetry

一个最简的端到端示例(与源码 docstring 中reidentify的用法一致):

import openmed # 1) 检测 result = openmed.extract_pii( "Patient Casey Example called from 555-0100 on 01/15/1970.", confidence_threshold=0.5, ) # 2) 脱敏(mask 策略,默认即保留映射以支持逆向) d = openmed.deidentify( "Patient Casey Example called from 555-0100 on 01/15/1970.", method="mask", keep_mapping=True, ) print(d.deidentified_text) # 形如 'Patient [NAME] called from [PHONE] on [DATE]' # 3) 依据映射恢复 restored = openmed.reidentify(d.deidentified_text, d.mapping) print(restored) # 还原原始文本

2.extract_pii:检测临床文本中的 PII 实体

定义位于 openmed/core/pii.py。它使用 token 分类模型检测姓名、邮箱、电话、地址及其他受 HIPAA 保护的标识符(模块 docstring 声称支持 18+ 实体类型),并通过**智能实体合并(smart merging)**把被模型切碎的片段(如日期01/15/1970)依据正则语义单元重新合并为完整实体(01/15/1970),再以主导标签(dominant label)归类。

2.1 函数签名

extract_pii( text: str | bytes | bytearray | memoryview, model_name: str = "OpenMed/OpenMed-PII-SuperClinical-Small-44M-v1", confidence_threshold: float = 0.5, config: Optional[OpenMedConfig] = None, use_smart_merging: bool = True, lang: str = "en", cache_results: bool = False, max_cache_entries: int = 128, normalize_accents: Optional[bool] = None, *, preserve_whitespace: bool = False, locale: Optional[str] = None, loader: Optional[ModelLoader] = None, batch_size: Optional[int] = None, num_workers: Optional[int] = None, custom_recognizer: Any = None, abdm: Optional[bool] = None, code_mixed: bool = False, token_language_tags: Optional[Sequence[Any]] = None, lid_model: Optional[TokenLIDHook] = None, transliterated_name_config: Any = None, budget: Optional[RequestBudget] = None, ) -> PredictionResult

2.2 核心参数语义

参数默认值说明
text支持strbytes/bytearray/memoryview,入口先经validate_pii_input校验
model_nameOpenMed/OpenMed-PII-SuperClinical-Small-44M-v1PII 模型标识:注册表键、Hugging Face 仓库 ID 或本地路径;当lang != "en"时自动切换到对应语言的默认模型
confidence_threshold0.5置信度下限(0–1),低于阈值的结果被过滤
use_smart_mergingTrue是否启用基于正则的语义单元合并(官方推荐保持开启)
lang"en"ISO 639-1 语言码(en、fr、de、it、es、nl、hi、te、pt、ar、ja、tr 等),控制默认模型、正则模式与替换假数据;hi/te的拉丁/天城文、拉丁/泰卢固文混合文本会自动走脚本感知的印度临床路由
normalize_accentsNone推理前是否去除变音符号;None表示对_ACCENT_NORMALIZE_LANGS(当前为西班牙语es)自动开启。结果中的实体偏移始终指向原始(带重音)文本
preserve_whitespaceFalse保留首尾空白,使返回偏移精确对应输入串
custom_recognizerNone自定义识别器:CustomRecognizer实例或 JSON/YAML 配置路径;deny-list 命中以custom:deny溯源加入,allow-list 命中抑制任何检测器的重叠跨度
abdmNone印度 ABDM 标识符包开关;None对印地语/泰卢固语及印度 locale 自动开启,False显式关闭
code_mixedFalse显式英语/印地语混合路径,需配合token_language_tagsen/hi/ne/univ/other标签流)
budgetNone每次请求的墙钟时间与输入字符预算;超长输入在模型推理前即被拒绝
cache_results/max_cache_entriesFalse/128进程内 LRU 结果缓存;缓存可能含 PHI,但永不落盘

2.3 底层流程与返回结构

从源码调用链看,extract_pii依次完成:输入校验与预算检查 → 缓存查找 → 构造_extract_pii_batch单元素批 →(可选)Unicode 归一化与变音去除、印度临床脚本窗口路由、隐私过滤模型分发 → 智能合并 → 确定性safety_sweep补充结构化标识符(SSN/身份证等)→ 实体跨度校验(validate_entity_spans)→ 返回PredictionResult

返回的PredictionResulttextentitiesmodel_nametimestamp;每条实体为PIIEntity(见第 3 节)。若lang指定的语言没有捆绑模型,会抛出带明确指引的ModelLoadError(例如提示设置INDIC_NER_MODEL_ENV或显式传model_name)。

3. 核心数据结构:PIIEntityDeidentificationResult

3.1PIIEntity

定义于 openmed/core/pii.py,继承自EntityPrediction,除基础text/label/start/end/confidence外,还包含 PII 专属字段:

  • entity_type:PII 类别(与label相同,构造时自动回填);
  • redacted_text/original_text:脱敏后替换文本与脱敏前原文;
  • hash_value:用于实体关联的一致性哈希;
  • reversible_id:可选的可逆假名化句柄;
  • canonical_label:规范化类别标签(用于跨模型的标签归一);
  • sources/evidence:实体来源(如mllocale_rulesafety_sweepcustom:deny)与证据;
  • action/surrogate:脱敏动作与代理值。

3.2DeidentificationResult

定义于 openmed/core/pii.py,字段包括:

  • original_text:输入原文;
  • deidentified_text:脱敏后文本;
  • pii_entities:检测并脱敏的实体列表;
  • method:所用脱敏方法;
  • timestamp:执行时间;
  • mapping:可选的可逆映射(keep_mapping=True时返回)。当多个原文拼写映射到同一替换面时,使用私有 occurrence key 区分,使不同的源拼写在脱敏文本不变的前提下仍可逐条恢复
  • audit_report:审计报告(audit=True时附带)。

三个实用方法:

  • to_dict():序列化为字典,含num_entities_redactedaudit_report
  • _repr_html_():在 Jupyter/IPython 中自动渲染高亮 PII 跨度视图(置信度默认隐藏,避免隐式展示敏感置信信息);
  • to_dataframe():转为 pandas DataFrame(每实体一行,列含textlabelentity_typestartendconfidenceactionresult_id;未安装 pandas 时抛MissingExtraError)。

4.deidentify:七种脱敏策略与可逆映射

定义位于 openmed/core/pii.py,是 OpenMed 的脱敏主入口,内部构造 openmed/core/pipeline.py 的Pipeline并执行完整管线。

4.1 支持的脱敏方法(method

方法行为
mask(默认)替换为占位符,如[NAME][EMAIL]
aadhaar_mask合法的印度 Aadhaar 号渲染为XXXX XXXX NNNN,其余实体用普通占位符
remove完全移除(替换为空串)
replace替换为逼真的假数据(基于 Faker 与语言 locale)
hash替换为一致性哈希值用于实体关联(如NAME_a1b2c3d4
format_preserve保持结构标识符的形状与分隔符生成合成值,不支持的标签回退为掩码
shift_dates按随机偏移平移日期且保持日期区间关系

兼容性:shift_dates=Truemethod="shift_dates"的弃用别名;若shift_dates=Falsemethod="shift_dates"冲突、或date_shift_days/patient_key等日期参数在非日期方法下使用,都会抛出带明确修复指引的InputError

4.2 关键参数

参数默认值说明
confidence_threshold0.7脱敏置信度下限;默认高于extract_pii0.5,体现"检测可宽、脱敏从严"的安全设计
keep_yearFalse日期脱敏时保留年份不变
date_shift_daysNone未提供patient_key时的固定偏移天数;提供patient_key时作为历史最大绝对偏移上限(除非同时给出date_shift_max_days
patient_keyNone稳定患者标识,仅用于派生确定性 HMAC 日期偏移;原始键不记录、不持久化、不返回
date_shift_max_daysNone最大绝对偏移;提供patient_key/seed且二者均未设置时默认365
date_shift_secretNoneHMAC 密钥材料;跨会话复用同一值可保持偏移稳定;与patient_key成对使用
keep_mappingFalse是否保留用于reidentify的映射
consistentFalsereplace/format_preserve下生成稳定代理(同输入→同输出,跨调用内一致)
seedNone请求级整数种子,实现替换与自动日期平移的跨运行可复现;对替换方法隐含consistent=True
localeNoneFaker locale 覆盖(如pt_BRen_GB);未指定时由lang推导
surrogate_vaultNone跨文档代理保险库;只存储 HMAC 源哈希,Indic 姓名以语音折叠的 HMAC 复用身份并按输入文字渲染,折叠本身永不持久化或审计
policyNone策略配置名,控制仲裁、动作选择、强制安全扫描与可逆映射
calibration_thresholds_pathNonethresholds.json工件路径;提供后按标签的校准阈值过滤检测并进入审计输出
use_safety_sweepTrue模型检测后、脱敏前执行确定性结构化标识符扫描
auditFalseTrue时返回AuditReport而非DeidentificationResult
budgetNone请求级墙钟/字符预算

其余参数(configuse_smart_merginglangnormalize_accentsloadercustom_recognizerabdmcode_mixedtoken_language_tagslid_modeltransliterated_name_configcache_results)语义与extract_pii一致。

4.3 返回与审计

默认返回DeidentificationResultaudit=True时返回确定性AuditReport(由 openmed/core/audit.py 提供),包含DetectorInfo列表(每个检测器的来源、模型 ID、格式ml/rules、commit 等)以及经_sanitize_audit_evidence清洗的证据——所有文本类键(textwordsurfacereplacementoriginal_textdeidentified_text等)一律从审计证据中剔除,确保 PHI 安全。

5.reidentify:基于映射的逆向恢复

定义位于 openmed/core/pii.py。要求脱敏时使用了keep_mapping=True

reidentify(deidentified_text: str, mapping: Mapping[str, str]) -> str

实现要点:

  • 入参严格校验:deidentified_text必须是strmapping必须是字符串键值映射,否则抛InputError并给出修复指引;
  • 支持occurrence-aware 映射:当不同原文拼写碰撞到同一替换面时,映射键以__openmed_occurrence_v1__:<ordinal>:<surface>形式记录,reidentify先按出现顺序恢复这些条目,再用普通映射做全局替换;
  • 源码模块 docstring 给出简洁示例:
from openmed import reidentify reidentify( "Patient [NAME] called [PHONE]", {"[NAME]": "Casey Example", "[PHONE]": "555-0100"}, ) # 'Patient Casey Example called 555-0100'

生产环境注意:源码 docstring 明确提示重标识需要适当的授权与审计日志,属于高敏感操作。

6.analyze_text:通用临床 NER 分析

定义于 openmed/init.py,运行 token 分类模型并格式化预测结果。与extract_pii的差异在于它是通用 NER(默认模型disease_detection_superclinical),不绑定 PII 语义,可用于疾病、症状等临床概念抽取。

主要参数:

  • model_name/model_id:注册表键、HF 模型 ID 或本地路径(二者只能传其一);
  • aggregation_strategy:HF 聚合策略,默认"simple"None时返回原始 token 输出;
  • output_format"dict"(默认)、"json""html""csv"
  • include_confidence/confidence_threshold:置信度输出与过滤;
  • group_entities:格式化输出中合并相邻同标签实体;
  • sentence_detection(默认True)/sentence_language/sentence_backend:句子级分块推理,sentence_backend可为"auto"(默认路由)或"yasbd"(实验特性,需openmed[yasbd]extra);
  • assert_context:为每个实体附加确定性否定、不确定性、体验者与时间性标签(存于metadata["clinical_context"]),默认关闭;
  • cache_results/max_cache_entries:进程内 LRU 缓存(可能含 PHI,不落盘)。

底层实现会先按句子分段(sentence_utils.segment_text),以「最多 6 个句子 /max(480, max_length*4)字符」为界构造推理分块,随后将各块预测偏移回填到原文坐标,并在硬换行与句界处切分跨度、跳过占位符片段。若OpenMedConfig.use_medical_tokenizer=True,还会把模型跨度重映射到医学友好 token(openmed/processing/tokenization.py 的remap_predictions_to_tokens)。

7.list_models与模型发现

定义于 openmed/init.py:

list_models(*, include_registry: bool = True, include_remote: bool = True, config: Optional[OpenMedConfig] = None) -> List[str]
  • include_registry:是否在提交的 manifest 之外并入捆绑注册表中的条目;
  • include_remote:为兼容保留,不会执行实时远程发现(离线优先设计);
  • 返回可用模型标识符列表。

配套发现能力还包括get_model_infoget_models_by_categoryget_default_pii_modelget_pii_models_by_languagesearch_modelsModelQuery)以及 HF Hub 拉取助手prefetch_modellist_cached_modelsclear_cached_modelresolve_repo_id(openmed/core/hf_hub.py)。

8.BatchProcessor:批量处理

BatchProcessor定义于 openmed/processing/batch.py,配套数据结构包括BatchItemBatchItemResultBatchResultBatchProgressDatasetRedactionResult等(顶层从 openmed/processing 导出)。

典型用法是把多条文本组装为BatchItem列表(每项含文本与自定义元数据),提交后逐条执行检测/脱敏,结果通过BatchResult汇总,并可在BatchProgress中观察进度。仓库还提供更高层的process_batch函数与redact_dataset(数据集级脱敏,返回DatasetRedactionResult/DatasetRedactionSummary),以及流式能力deidentify_streamdeidentify_document_stream。异步变体见 openmed/aio.py(abatchaextract_piiadeidentifyaanalyze_text)。

9. 结构化错误体系:一个根、十个叶

OpenMed 在 Python、REST 与 MCP 三端暴露同一棵错误契约(详见 docs/api/errors.md)。所有期望内的公开失败都继承自OpenMedError(openmed/core/errors.py),并具备四个稳定能力:

  • code:稳定的小写机器可读错误码(ClassVar);
  • message:可操作的、不含 PHI的人类可读信息;
  • details:非敏感结构化上下文(计数、偏移、标签、哈希等);
  • to_dict(include_details=True):返回{"code", "message", "details"}JSON 就绪对象。

9.1 错误类层级与传输映射

Python 异常稳定 code兼容内建基类REST 状态MCP code
OpenMedErroropenmed_errorException500openmed_error
InputErrorinput_errorValueError,TypeError400input_error
ConfigurationErrorconfiguration_errorValueError,TypeError,KeyError400configuration_error
CapabilityErrorcapability_errorImportError503capability_error
MissingExtraErrormissing_extraImportError503missing_extra
ModelLoadErrormodel_load_errorImportError,ValueError503model_load_error
PolicyErrorpolicy_errorValueError,TypeError400policy_error
BudgetExceededErrorbudget_exceededRuntimeError503budget_exceeded
InternalErrorinternal_errorRuntimeError500internal_error
InferenceErrorinference_errorRuntimeError500inference_error

继承关系:MissingExtraErrorModelLoadError继承自CapabilityErrorInferenceError继承自InternalError。兼容内建基类的设计让存量except ValueError/except ImportError/except RuntimeError处理器在迁移期间继续工作。

共享输入校验还保留更细的稳定叶码:text_requiredtext_typeinvalid_encodingempty_textmin_charsmax_charsmax_byteslanguage_requiredlanguage_typeunsupported_languagesuspicious_content(这些仍是InputError实例)。openmed.ERROR_CODES是类名→code 的机器可读注册表(openmed/core/errors.py),code 永不复用,变更或删除已发布 code 属于兼容性破坏。

9.2 推荐捕获模式

import openmed try: result = openmed.deidentify(payload, method="mask") except openmed.InputError as error: # 修正请求:按 code 分支,而不是匹配 message 文本 print(error.code, error.details) except openmed.CapabilityError as error: # 先安装/配置所请求的本地能力再重试 print(error.code) except openmed.OpenMedError as error: # 其余可预期失败都扎根于此 print(error.code)

9.3 PHI 安全的诊断:redact_detail

错误消息绝不包含临床原文、检测到的标识符表面、可逆映射、凭据或密钥材料。当需要在本地关联不可信文本时,使用redact_detail(openmed/core/errors.py):

from openmed import redact_detail descriptor = redact_detail(untrusted_value) # <redacted bytes=... sha256=...>

描述符只含 UTF-8 字节长度与完整 SHA-256 摘要;不要把原始值塞进自定义错误消息或details

9.4 REST 与 MCP 行为

REST 侧使用标准错误信封:{"error": {"code": ..., "message": ..., "details": ...}};可纠正的输入/配置/策略失败返回 HTTP 400,能力缺失与预算超限返回 503,内部与推理失败返回 500;服务端响应将details置为null以避免暴露内部上下文。MCP 工具在结构化内容中返回同样的 code 与 message,并同时置协议错误标志与is_error: true

10. PDF 脱敏与保真验证

openmed.multimodal提供四个面向 PDF 的公开函数,可用于「渲染红action 版 PDF + 验证脱敏完整性」的闭环:

  • render_redacted_pdf(...)(openmed/multimodal/render_pdf.py):依据检测/脱敏结果渲染红action(涂黑)版 PDF;
  • measure_pdf_layout_fidelity(...)(openmed/multimodal/render_pdf.py):度量红action 后版面保真度,用于评估脱敏对布局的影响;
  • verify_redacted_pdf(...)(openmed/multimodal/verify_pdf.py):校验输出 PDF 的脱敏状态;
  • verify_redacted_text_removed(...)(openmed/multimodal/verify_pdf.py):验证指定文本确实已从 PDF 中移除。

这些函数与仓库中 docs/multimodal/pdf-redaction-fidelity.md、docs/multimodal/pdf-reading-order.md 描述的能力对应,适合构建"先脱敏、再验证、后发布"的文档管线。

11. 可观测性:PipelineTelemetryStageTelemetry

定义于 openmed/core/telemetry.py:

  • PipelineTelemetry默认关闭(opt-in)的 OpenTelemetry spans 与指标记录器。可传入调用方自有的 tracer/meter;OpenMed 本身从不配置 provider、从不创建 exporter 或任何网络出口,因此启用遥测不会把数据发送到任何目的地。
  • StageTelemetry:单个管线阶段的 No-PHI 记录器,由PipelineTelemetry.stage_span创建。setter 只接受聚合值,全部 span 属性经safe_stage_attributes过滤。

StageTelemetry提供的方法(全部记录聚合值、绝不落实体原文):

  • set_span_count(count)/set_entity_count(count):本阶段产生的规范跨度数与实体数(openmed.stage.span_count/openmed.stage.entity_count);
  • set_labels(labels):记录规范化类别标签集合(永远不是实体文本);
  • set_input_length(length)/set_redacted_length(length):输入字符数与输出脱敏字符数;
  • set_offset_range(start, end):聚合输出边界(openmed.stage.offset.start_min/end_max),不存储检测表面;
  • mark_failed():标记失败阶段,不记录异常或消息;
  • finish(duration_ms):结束阶段并记录时长与聚合直方图。

环境变量OPENMED_TELEMETRY可控制默认开关(见parse_telemetry_enabled/telemetry_enabled_from_env)。该设计呼应 docs/operations/no-phi-telemetry.md 的 no-PHI 遥测原则。

12. 组合实战:一条合规的端到端管线

把上述 API 串联成一个典型工作流:

import openmed note = ( "Ms. Casey Example, DOB 01/15/1970, SSN 123-45-6789, " "was seen at 555-0100 for asthma follow-up on 03/12/2026." ) # 1) 先提取,观察检测结果(阈值可放宽到 0.5) found = openmed.extract_pii(note, confidence_threshold=0.5) for entity in found.entities: print(entity.label, entity.text, round(entity.confidence, 2)) # 2) 生产脱敏:更高阈值 + replace 假名 + 保留映射 + 一致性代理 masked = openmed.deidentify( note, method="replace", # 或用 mask / hash / format_preserve confidence_threshold=0.7, keep_mapping=True, consistent=True, use_safety_sweep=True, # 覆盖 SSN 等结构化标识符 ) print(masked.deidentified_text) # 3) 受控场景下按映射还原(需授权与审计) restored = openmed.reidentify(masked.deidentified_text, masked.mapping) assert restored == note

如需错误处理,在deidentify外围包裹第 9.2 节的try/except,并可按需传入budgetRequestBudget)防止超大请求拖垮本地推理。全部处理在本机完成,患者数据不出网络边界。

延伸阅读

  • 结构化错误契约全文:docs/api/errors.md
  • PII 实体合并与语义单元:openmed/core/pii_entity_merger.py
  • 脱敏器与假数据生成:openmed/core/anonymizer
  • 预算控制:openmed/core/budget.py
  • 批量处理与数据集脱敏:openmed/processing/batch.py
  • REST 服务形态:docs/rest-service.md 与 docs/api-reference.md 配套的 docs/api/openapi.json
  • 端到端示例脚本:examples/first_five_minutes_redact_extract_fhir.py、examples/pii_batch_processing.py

【免费下载链接】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),仅供参考

需要专业的网站建设服务?

联系我们获取免费的网站建设咨询和方案报价,让我们帮助您实现业务目标

立即咨询