中文EN

dsh-medical-anonymizer

securitynpmMIT

在 DeepSeek Harness 中批量匿名化病历文本、CSV、JSON 与 XLSX:先跑确定性标识符规则,可选 OpenAI 兼容模型做发现与复核;按精确区间替换以保持文件结构,同一值保持同一假名,并输出审计报告与映射库。DICOM 影像按 PS3.15 附录 E 只处理头部元数据,像素数据逐字节保留。

下载量 / Downloads
328

安装

dsh plugin --profile web add dsh-medical-anonymizer

沙箱测试

这个插件还没测过。提交测试 →

README

dsh-medical-anonymizer

简体中文 | [English](README.en.md)

DeepSeek Harness(Cordis)插件,

用于批量匿名化病历文本和表格。它发现直接标识符,用稳定假名替换,保持文件结构不变,

并输出审计报告和可还原的映射库。

这是数据处理工具,不是合规认证。发布任何输出之前,请对照适用法律和本机构的政策进行审查。

<p align="center"><img src="https://raw.githubusercontent.com/wld007/dsh-medical-anonymizer/main/assets/pipeline.gif" alt="处理流程实时动画" width="820"></p>

<sub>截图使用合成数据,不含真实患者信息。</sub>

特点

  • 结构天然保持。 模型只负责标注文本;插件定位精确片段,只替换这些片段。

行数、CSV 列、JSON 键和 Excel 非文本单元格都不会变动。

  • 规则优先,模型可选。 身份证校验位、电话/邮箱模式、带标签字段、列名/键名策略

无需模型即可运行。模型轮次用于提高自由文本的召回率,并复核结果。

  • 有界修复循环。 复核轮次的发现会回到发现阶段,受轮次上限约束。未解决的条目

标记为人工复核,而不是被静默接受。

  • 本地优先。 无遥测。插件只访问你配置的 OpenAI 兼容端点;指向本机运行时,

数据就不会离开本机。

  • 输出可审计。 每个文件的实体统计、结构校验、残留问题、人工复核清单,以及唯一

保存原值的映射库。报告不打印标识符原值。

功能

方面 · 说明

格式 · .txt、.md、.csv、.json、.xlsx;.zip 压缩包(含嵌套,见 [压缩包](#压缩包));DICOM 影像(只处理元数据,见 [DICOM 影像](#dicom-影像))

文件名与目录名 · 路径中的姓名、身份证号、手机号、patient_<编号>、zyh_<住院号>、mzh_<门诊号> 换成与正文一致的假名,见 [文件名与目录名](#文件名与目录名)

直接标识符 · 姓名、医生/职工姓名、身份证号、电话、邮箱、地址、病历号、住院号、就诊号、社保号、银行卡号、医院名称

列名/键名策略 · 姓名、身份证号、电话、住址 等表头,以及 PTT_NM、ID_CRD_NO、CTCT_TEL_NO、CURR_ADDR、_DCT_NM、MDC_ORG_NM、PID、INHOS_NO 等键整体替换为假名;PRM_KEY/RCD_NO 等记录键按记录标识符遮盖

假名 · 按值和类型稳定生成,如 化名-9F3A2C、证件-1F0B67;共用同一输出根的文件和批次中,同一个值得到同一个假名

可配置规则 · 按标识符类型选择:稳定假名(默认)、部分遮盖、类型标签或保留;可选处理准标识符(日期、年龄、性别、邮编):平移、泛化或标签——见[匿名化规则](#匿名化规则)

校验 · 模型复核、规则复扫、原值残留检查、结构比对

运行 · 直接写出匿名化副本,源文件只读;模型调用不设上限;多文件并发;文件多时自动分组;可取消;可撤销某批新增映射

报告 · Markdown + JSON,按文件和批次汇总,附人工复核清单

安装

要求 DSH >= 0.2.1(在 0.2.1-rc.5 上测试)和 Node.js >= 20。

dsh plugin --profile <profile> add github:wld007/dsh-medical-anonymizer
# 或在发布到 npm 之后:
dsh plugin --profile <profile> add dsh-medical-anonymizer

安装后重启 DSH:插件层在启动时组装。

设置页位于 设置 → 医疗数据匿名化。主机端激活后即可使用 /anonymize 命令和

Agent 工具。

模型配置

插件从不调用内置的云端模型,只使用你配置的 OpenAI 兼容端点。

运行时 · Base URL · 说明

Ollama · http://127.0.0.1:11434/v1 · 推荐本地使用

LM Studio · http://127.0.0.1:1234/v1 · 需开启本地服务器

vLLM / llama.cpp · 你的 /v1 端点 · 任意 OpenAI 兼容的 chat 服务

模型名称留空则只运行确定性的规则层。配置模型后,插件会把每批文本发送到该端点进行

发现和复核;如果端点在远程,文本就会离开本机。处理患者数据请使用本机或机构可控的端点。

推理模型(Qwen3 等)可能把全部 token 预算花在隐藏推理上。关闭思考模式默认开启;

保持勾选,或给 /anonymize 加 --no-think。只有模型确实需要推理时才取消勾选

(或传 --think)。不接受这些可选请求字段的服务器会自动去掉字段重试一次。

使用

设置 → 医疗数据匿名化(配置)

只放配置,分为 模型连接、匿名化规则、批次与界面、使用说明 几个标签页:

  • 本地模型:端点、模型、API Key、关闭思考模式、单次调用超时、温度、测试连接(端点上没有该模型名时会提示)。
  • 批次默认值:输出根目录、最大轮次、每组文件数、同时处理的文件数、单批 DICOM 上限。
  • 映射库加密:设置/修改/清除 vaultPassphrase(两次输入确认,保存后不再显示)。改口令或取消加密后,用旧口令加密的映射库将无法读取。
  • 匿名化规则:每类标识符的处理方式、准标识符开关、每类准标识符的处理方式,均附实时示例;不匹配的值与不处理的字段。
  • 界面:在左侧栏显示或隐藏 医疗数据匿名化 入口。隐藏后 /anonymize 和 Agent 工具仍可使用。
  • 保存栏列出未保存的字段;保存 会写入该 profile 自己的配置层,重启和插件更新后依然保留。

API Key 只在你输入或清除时保存,之后不再显示,存放在 profile 配置文件中(权限 600)。

批次运行期间不允许保存,因为保存会重新加载插件。

左侧栏 → 医疗数据匿名化(处理流水线看板)

一屏展示整批处理过程,左侧输入、中间流程、右侧监控与参数:

区域 · 内容

A1 数据输入 · 选文件夹或文件 / .zip(macOS 原生选择框,可按住 ⌘ 多选同一目录下的多项,作为一个批次、分别交付);可覆盖输出根目录

A2 批次记录 · 历史批次、状态与来源(面板 / /anonymize / Agent 会话,可跳回会话);可删除记录,可选同时删除交付数据

B1 处理流程 · 8 个环节的产线示意图:预扫描 → 解析 → 识别 → 核验 → 修正 → 批次复扫 → DICOM → 输出;处理中的环节高亮,文件在传送带上移动;下方文件队列逐个文件着色

B2 / B3 · 按类型的标识符替换统计;核验结果比例(通过 / 待复核 / 失败)与交付数据路径

底部标签页 · 文件、日志(自动滚动)、模型调用(耗时分布条 + 逐次记录,只记元数据)、提示、报告(Markdown 渲染,可全屏)

C1 运行监控 · 完成度、处理速率曲线、剩余文件与预计剩余时间、替换标识符、模型调用、待复核、Token 消耗、内存

C2 处理参数 · 轮次、并发、分组、超时、温度、思考模式、准标识符开关;运行中锁定;其余配置在「全部设置」弹框

C3 改进建议 · 批次结束后按统计给出可一键采纳的参数建议;参数解决不了的问题生成不含原值的插件改进草稿

点击左上角标题可打开「处理说明」:处理范围、当前标识符处理方式、流程图与各环节方法、处理原则、输出结构和结果判定。

<p align="center"><img src="https://raw.githubusercontent.com/wld007/dsh-medical-anonymizer/main/assets/help.png" alt="处理说明" width="640"></p>

/anonymize 命令

/anonymize /path/to/records --model qwen2.5:14b --endpoint http://127.0.0.1:11434/v1

直接写出匿名化文件(源文件只读,不会被修改)。

输入也可以是单个文件,例如 /anonymize /path/to/note.txt 或 /anonymize /path/to/记录.zip:只处理该文件,

交付数据为输出根目录下的 note.txt,默认输出根目录在该文件旁边的 _medical-anonymizer。

选项:--rounds N、--output DIR、--no-think、--think。

Agent 工具

工具 · 用途

anonymize_start · 启动批次并返回 runId

anonymize_cancel · 取消正在运行的批次;已写出的文件保留

anonymize_status · 进度、实体统计、未解决问题

anonymize_report · 读取 Markdown 报告

anonymize_runs · 列出最近的批次

anonymize_undo_mappings · 撤销某批新增到映射库的对应关系(不删除输出文件)

anonymize_start 参数:inputDir(目录、单个文件或 .zip)、outputRoot、maxRounds。

Agent 工具不能选择模型端点、模型、API Key 或思考模式:这些始终取自用户已保存的设置,

因此 Agent 无法把患者文本转发到其他服务。工具描述中写明了插件名和这一数据边界,

有助于 Agent 在名称相近的工具中选中它。只有人工输入的 /anonymize 命令接受

--endpoint 和 --model 覆盖。

工作原理

1. 规则预扫描。 身份证号(校验位验证)、手机/座机、邮箱、银行卡(Luhn)、

病历号/住院号/就诊号,以及带标签的姓名/地址/医院/医生;也识别病历模板中

F=[引用值:姓名]…[<isele 0>值<isele 1>] 这类被标记隔开的字段。

2. 列名与键名策略。 专用字段整体替换为假名,包括常见医院导出键,如 PTT_NM、

ID_CRD_NO、CTCT_TEL_NO、_ADDR、_DCT_NM、_STFF_NM、MDC_ORG_NM、

PID、INHOS_NO、_DCT_CD/_NUS_CD(工号)、*_SGNT(签名),以及区域卫生平台

导出中的 SLF_NM(本人姓名)、*_PSN_NM(采样/审核等人员)、WRK_UNT_NM(工作单位)、

可串联同一患者或就诊的 USER_ID、VST_UNQ_ID、OTPT_EMG_NO、RGST_NO,和机构代码

*_ORG_CD。{"ITM_NM": "姓名", "ITM_VLU": "…"} 这类“项目名-项目值”记录按项目名判断。

描述标识符的列(ID_CRD_CGY_CD 证件类型、_TP_、*_FLG 等)不算标识符列。

3. 可选的模型发现。 文本分批发送到配置的端点(附带字段名)。相同文本只发送一次;

纯数字/日期值和已脱敏的值不发送。模型返回 {segment, type, text};

插件在原文中定位精确文本。从不信任模型给出的坐标。

格式校验: 不像该类型的结果不替换,列入报告提示——如按字段名得到的证件号 01、

模型把科室名“内一科(肾脏病科)(11病区)”判为医院。

全文扩展: 识别出的值会在全文其他位置一并替换,但匹配不能嵌在更长的字母/数字串中

(01 不会命中 2001017),少于 6 位的短编码只替换识别到的位置,不扩展。

“区属医院”“综合医院”“中医院”和单独的“医院”是机构类别或通用词,不当作医院名。

跨文件: 处理前先用字段名和规则扫一遍全部文件,建立批次词典;某个文件里识别出的

姓名、证件号、住址等也会在其他文件中替换。全部文件处理完后再做一次批次复扫,补上

靠后的文件(含模型)才识别出的值,报告中记为“批次复扫”。省、市、县等行政区划名不跨文件扩展。

文件超过 maxFiles(默认 200)时自动分组:组内处理完即复扫并释放内存,最后对前面各组的

输出再做一次跨组复扫;同时处理 concurrency(默认 4)个文件。

JSON 里单独的 name 键只有在所

…(truncated)

以上内容来自 npm 上的 README,我们只做格式化,不改内容。

版本

npm 上共发布:3,最后更新 2026-11-06

链接

GitHub · Homepage · npm

同类插件