问题
你有一批敏感文本想让 GPT-4o 分析——日记、客户咨询记录、体检报告。
传统做法是脱敏:把"张三"替换成 [PERSON],把手机号删掉。问题是:
- 不可逆——LLM 输出里的 [PERSON] 你不知道是谁
- 固定映射——如果张三每次都是 PERSON_1,云端可以跨请求画像
- 中文支持差——Presidio 的中文需要自己配 spaCy,没有身份证校验
解决方案:语义加密
我做了 argus-redact,把"脱敏"变成"加密":
from argus_redact import redact, restore
# 加密
redacted, key = redact("王五在协和医院做了体检,手机13812345678")
# "P-037在[医院]做了体检,手机138****5678"
# key = {"P-037": "王五", "[医院]": "协和医院", "138****5678": "13812345678"}
# 发给 LLM
llm_output = call_gpt(redacted)
# 解密
restored = restore(llm_output, key)
# 王五和协和医院回来了
关键区别:
| 传统脱敏 | argus-redact | |
|---|---|---|
| 输出 | 不可读或不可逆 | 可读且可逆 |
| LLM 能处理? | 勉强(语义丢失) | 能(语义保留) |
| key 泄露 | 无 key | 身份暴露(仅该 session) |
| 跨请求关联 | 可能(固定映射) | 不可能(每次新 key) |
三层检测
Layer 1 Regex 手机号、身份证(MOD 11-2)、银行卡(Luhn)、邮箱、车牌、SSN
Layer 2 NER HanLP(中文)、spaCy(英文) — 人名、地名、机构名
Layer 3 语义LLM Ollama 本地模型 — "那个地方"、"老王"等隐含 PII
用户可以按需选层:
mode="fast"仅 regex,亚毫秒,零依赖mode="ner"加上 NERmode="auto"三层全开
Per-Message Key:为什么重要
ETH Zurich 2026年2月论文证明:LLM agent 可以 $1-4/人的成本反匿名化在线用户(67% recall / 90% precision)。
攻击前提是:同一个人在不同请求中使用相同的假名。
argus-redact 每次 redact() 生成完全独立的 key——"王五"这次是 P-037,下次是 P-003。云端看到的是两个毫无关联的人。
性能
Regex 层,无 GPU:
| M1 Max | 树莓派 Zero 2W | |
|---|---|---|
| 短文本 | 0.06ms | 0.98ms |
| 770字 | 0.28ms | 4.29ms |
| 吞吐量 | 42,789 docs/sec | 3,433 docs/sec |
LLM API 调用(500-3000ms)才是管道瓶颈。argus-redact 的开销可以忽略。
安装
pip install argus-redact # 核心(仅 regex)
pip install argus-redact[zh] # + 中文 NER
pip install argus-redact[en] # + 英文 NER
Python 3.10+,纯 CPU,MIT 协议。
CLI
cat journal.txt | argus-redact redact -k key.json > redacted.txt
cat redacted.txt | llm "summarize" > output.txt
cat output.txt | argus-redact restore -k key.json
链接
- GitHub: github.com/wan9yu/argu…
- PyPI: pypi.org/project/arg…
欢迎 Star、Issue、PR。特别欢迎:
- 更多语言包(目前支持中英日韩)
- 更多 PII 类型的 regex
- LangChain / FastAPI 集成反馈