langchain_experimental.data_anonymizer.PresidioAnonymizer
是 LangChain 实验性模块中的一个类,用于基于 Microsoft Presidio 框架对文本中的个人身份信息(PII)进行匿名化处理。
本文基于 LangChain 0.3.x 和 Presidio 文档( Presidio ),详细介绍
PresidioAnonymizer
的定义、初始化、方法和典型场景,提供一个独立示例,展示如何使用
PresidioAnonymizer
匿名化包含 PII 的文本,示例处理医疗记录文本,确保敏感信息(如姓名、电话、信用卡号)被替换为伪数据。
PresidioAnonymizer
简介
langchain_experimental.data_anonymizer.PresidioAnonymizer
是 LangChain 实验性模块中的一个类,基于 Microsoft Presidio 框架,用于检测和匿名化文本中的 PII(如姓名、电话号码、信用卡号、地址等)。
它通过替换、掩码、redaction或加密等操作保护隐私,特别适合在将数据传递给语言模型(如 LLM)之前移除敏感信息,以符合数据保护法规。
核心功能 : PII 检测 :使用 Presidio 的命名实体识别(NER)和正则表达式识别 PII。
匿名化 :支持替换(replace)、掩码(mask)、redaction(redact)或加密(encrypt)等操作。
灵活配置 :允许指定检测字段、自定义匿名化操作和多语言支持。
非可逆匿名化 :与
PresidioReversibleAnonymizer
不同,不存储原始数据映射,无法还原。
适用场景 : 在 RAG 系统中匿名化文档,防止 LLM 泄露 PII。
保护隐私敏感数据(如医疗、金融记录)在聊天机器人中的使用。
遵守数据保护法规(如 GDPR、HIPAA)。
清理测试数据,移除真实 PII。
与PresidioReversibleAnonymizer对比
:
PresidioAnonymizer
:非可逆,适合只需匿名化且不需还原的场景。
PresidioReversibleAnonymizer :可逆,存储假值到原值的映射,适合需要还原的场景(如内部处理后恢复数据)。
定义和初始化 以下是
PresidioAnonymizer
的定义,基于 LangChain 文档( PresidioAnonymizer ) 和源码(
langchain_experimental/data_anonymizer/presidio.py
)。
类定义
class PresidioAnonymizer(analyzed_fields: Optional[List[str]] = None, operators: Optional[Dict[str, OperatorConfig]] = None, languages_config: Optional[Dict] = None, add_default_faker_operators: bool = True, faker_seed: Optional[int] = None)
参数 :
analyzed_fields
(
Optional[List[str]]
,默认
None
):要检测和匿名化的 PII 字段列表(如
["PERSON", "PHONE_NUMBER"]
)。
默认检测 Presidio 支持的所有实体。
operators
(
Optional[Dict[str, OperatorConfig]]
,默认
None
):自定义匿名化操作,键为实体类型,值为
OperatorConfig
(如
replace
、
mask
)。
languages_config
(
Optional[Dict]
,默认
None
):NLP 引擎的语言配置,指定语言模型(如
en_core_web_lg
)。
默认使用英语。
add_default_faker_operators
(
bool
,默认
True
):是否使用 Faker 库生成伪数据(如假姓名、电话)。
faker_seed
(
Optional[int]
,默认
None
):Faker 的随机种子,固定伪数据输出(生产环境建议
None
)。
继承 :
PresidioAnonymizerBase
,实现
_anonymize
方法。
初始化示例
from langchain_experimental.data_anonymizer import PresidioAnonymizer
anonymizer = PresidioAnonymizer(
analyzed_fields=["PERSON", "PHONE_NUMBER", "EMAIL_ADDRESS", "CREDIT_CARD"],
add_default_faker_operators=True,
faker_seed=42 # 固定伪数据
)
支持的 PII 实体 (部分):
PERSON
:姓名
PHONE_NUMBER
:电话号码
EMAIL_ADDRESS
:电子邮件
CREDIT_CARD
:信用卡号
LOCATION
:地址
US_SSN
:美国社保号
IBAN_CODE
:银行账户 更多见 Presidio 文档 。
匿名化操作 : Replace :替换为伪数据(如
John Doe
→
Jane Smith
)。
Mask :用字符掩盖部分内容(如
123-456-7890
→
***-***-7890
)。
Redact :完全移除(如
John Doe
→
)。
Encrypt :加密 PII(需密钥)。
[Web:3,12] 核心方法 以下是
PresidioAnonymizer
的主要方法,基于源码和文档。
anonymize(text: str, language: Optional[str] = None, allow_list: Optional[List[str]] = None) -> str
功能 :匿名化输入文本,返回处理后的文本。
参数 :
text
:待匿名化的文本。
language
:语言代码(如
"en"
),默认使用
languages_config
的首语言。
allow_list
:忽略匿名化的词列表。
返回值 :
str
,匿名化后的文本。
流程 : 使用 Presidio 的
AnalyzerEngine
检测 PII。
应用
operators
(或默认
replace
)匿名化 PII。
返回处理后的文本。
示例 :
result = anonymizer.anonymize("My name is John Doe, call me at 555-123-4567.")
print(result) # My name is Jane Smith, call me at 987-654-3210.
其他方法 add_operators(operators: Dict[str, OperatorConfig]) :添加自定义匿名化操作。
from presidio_anonymizer.entities import OperatorConfig
anonymizer.add_operators({"PHONE_NUMBER": OperatorConfig("mask", {"masking_char": "*", "chars_to_mask": 4, "from_end": True})})
add_recognizer(recognizer: EntityRecognizer) :添加自定义 PII 识别器。
[Web:6,15] 使用方式 以下是使用
PresidioAnonymizer
的步骤。
1. 安装依赖
pip install --upgrade langchain langchain-experimental presidio-analyzer presidio-anonymizer spacy Faker
python -m spacy download en_core_web_lg
Presidio :提供 PII 检测和匿名化。
spaCy :支持 NER,需下载语言模型(如
en_core_web_lg
)。
Faker :生成伪数据。
2. 初始化 指定要检测的 PII 类型和操作:
from langchain_experimental.data_anonymizer import PresidioAnonymizer
anonymizer = PresidioAnonymizer(
analyzed_fields=["PERSON", "PHONE_NUMBER", "EMAIL_ADDRESS", "CREDIT_CARD"],
operators={
"PHONE_NUMBER": {"type": "mask", "masking_char": "*", "chars_to_mask": 4, "from_end": True},
"CREDIT_CARD": {"type": "redact"}
},
faker_seed=42
)
3. 匿名化文本 处理包含 PII 的文本:
text = "Patient: John Doe, Phone: 555-123-4567, Email: john.doe@gmail.com, Card: 4111 1111 1111 1111"
result = anonymizer.anonymize(text)
print(result)
# Patient: Jane Smith, Phone: *******4567, Email: emily.jones@example.com, Card:
4. 自定义操作 添加自定义操作(如随机 ID):
from faker import Faker
from presidio_anonymizer.entities import OperatorConfig
fake = Faker()
anonymizer.add_operators({
"CUSTOM_ID": OperatorConfig("custom", {"lambda": lambda _: fake.bothify("ID-####")})
})
使用
PresidioAnonymizer
的医疗记录示例 以下是一个独立示例,展示如何使用
PresidioAnonymizer
匿名化医疗记录文本,保护患者姓名、电话、邮箱和信用卡号。
示例结合自定义操作,处理医院 ID。
准备环境 :
pip install --upgrade langchain langchain-experimental presidio-analyzer presidio-anonymizer spacy Faker
python -m spacy download en_core_web_lg
代码 :
from langchain_experimental.data_anonymizer import PresidioAnonymizer
from presidio_anonymizer.entities import OperatorConfig
from faker import Faker
# 初始化 Faker
fake = Faker()
# 定义自定义操作
def fake_hospital_id(_=None):
return fake.bothify("HOSP-####")
# 初始化 PresidioAnonymizer
anonymizer = PresidioAnonymizer(
analyzed_fields=["PERSON", "PHONE_NUMBER", "EMAIL_ADDRESS", "CREDIT_CARD"],
operators={
"PHONE_NUMBER": OperatorConfig("mask", {"masking_char": "*", "chars_to_mask": 4, "from_end": True}),
"CREDIT_CARD": OperatorConfig("redact", {}),
"CUSTOM_ID": OperatorConfig("custom", {"lambda": fake_hospital_id})
},
add_default_faker_operators=True,
faker_seed=42
)
# 添加自定义识别器(假设医院 ID 格式为 HOSP-数字)
from presidio_analyzer import Pattern, PatternRecognizer
hospital_id_recognizer = PatternRecognizer(
supported_entity="CUSTOM_ID",
patterns=[Pattern(name="hospital_id", regex=r"HOSP-\d{4}", score=0.9)]
)
anonymizer.add_recognizer(hospital_id_recognizer)
# 医疗记录文本
text = """Patient: John Doe
Phone: 555-123-4567
Email: john.doe@gmail.com
Card: 4111 1111 1111 1111
Hospital ID: HOSP-1234
Diagnosis: Hypertension"""
# 匿名化
result = anonymizer.anonymize(text, language="en")
print("匿名化结果:")
print(result)
输出示例 (固定
faker_seed=42
,实际输出可能略有不同):
匿名化结果:
Patient: Maria Lynch
Phone: *******4567
Email: jamesmichael@example.com
Card:
Hospital ID: HOSP-5678
Diagnosis: Hypertension
代码说明 初始化 : 指定
analyzed_fields
检测姓名、电话、邮箱和信用卡号。
配置
operators
:电话掩码后四位,信用卡红action,医院 ID 自定义替换。
设置
faker_seed=42
固定伪数据。
自定义操作 : 使用
Faker.bothify
生成医院 ID(如
HOSP-5678
)。
添加
CUSTOM_ID
操作。
自定义识别器 : 定义
PatternRecognizer
识别
HOSP-\d{4}
格式的医院 ID。
匿名化 : 处理医疗记录,替换 PII,保留非敏感信息(如诊断)。
主题 : 示例聚焦医疗记录匿名化,保护患者隐私。
独立性 : 不涉及 LLM、嵌入或之前的上下文。
运行要求 : 安装依赖:
pip install --upgrade langchain langchain-experimental presidio-analyzer presidio-anonymizer spacy Faker
python -m spacy download en_core_web_lg
硬件支持:CPU 即可,4GB+ RAM 推荐。
注意事项 依赖安装 : 验证 Presidio 和 spaCy:
python -c "from presidio_anonymizer import AnonymizerEngine; print('OK')"
python -c "import spacy; print(spacy.load('en_core_web_lg'))"
缺失模型:
python -m spacy download en_core_web_lg
PII 检测限制 : Presidio 依赖 NER 和正则,可能漏检复杂 PII(如非标准格式的 ID)。
[Web:16] 添加自定义识别器:
recognizer = PatternRecognizer(supported_entity="CUSTOM", patterns=[Pattern(name="custom", regex=r"\d{5}", score=0.8)])
anonymizer.add_recognizer(recognizer)
匿名化操作 : Replace :默认使用 Faker 生成伪数据。
[Web:0] Redact :移除 PII,适合严格隐私场景。
[Web:10] Mask :部分隐藏,适合保留格式。
[Web:3] 自定义操作:
anonymizer.add_operators({"PERSON": OperatorConfig("replace", {"new_value": "ANONYMOUS"})})
语言支持 : 默认英语(
en_core_web_lg
),多语言需配置:
anonymizer = PresidioAnonymizer(languages_config={"nlp_engine_name": "spacy", "models": [{"lang_code": "es", "model_name": "es_core_news_md"}]})
下载语言模型:
python -m spacy download es_core_news_md
自定义语言识别器:[Web:14] 性能优化 : 小型模型 :使用
en_core_web_md
降低内存占用。
python -m spacy download en_core_web_md
批量处理 :使用 Presidio 的
BatchAnonymizerEngine
。
[Web:3] 限制
analyzed_fields
减少检测时间:
anonymizer = PresidioAnonymizer(analyzed_fields=["PERSON", "PHONE_NUMBER"])
错误调试 : PII 未检测 : 检查
analyzed_fields
是否包含目标实体。
添加自定义正则:
recognizer = PatternRecognizer(supported_entity="CUSTOM", patterns=[Pattern(name="custom", regex=r"\w+@\w+\.\w+", score=0.9)])
伪数据不一致 : 设置
faker_seed
:
anonymizer = PresidioAnonymizer(faker_seed=42)
模块缺失 : 安装依赖:
pip install presidio-analyzer presidio-anonymizer
常见问题 Q1:如何只匿名化特定 PII?
A:设置
analyzed_fields
:
anonymizer = PresidioAnonymizer(analyzed_fields=["PERSON", "EMAIL_ADDRESS"])
result = anonymizer.anonymize("John Doe, john.doe@gmail.com, 555-123-4567")
# Jane Smith, emily.jones@example.com, 555-123-4567
Q2:如何完全移除 PII?
A:使用
redact
操作:[Web:10]
anonymizer = PresidioAnonymizer(operators={"DEFAULT": OperatorConfig("redact", {})})
result = anonymizer.anonymize("John Doe, 555-123-4567")
# ,
Q3:如何支持多语言?
A:配置
languages_config
:[Web:14]
anonymizer = PresidioAnonymizer(languages_config={
"nlp_engine_name": "spacy",
"models": [
{"lang_code": "en", "model_name": "en_core_web_md"},
{"lang_code": "es", "model_name": "es_core_news_md"}
]
})
result = anonymizer.anonymize("Me llamo Sofía", language="es")
Q4:如何与 LLM 集成?
A:匿名化输入,传递给 LLM:[Web:0]
from langchain_ollama import OllamaLLM
from langchain_core.prompts import PromptTemplate
llm = OllamaLLM(model="llama3")
prompt = PromptTemplate(template="总结:{text}")
chain = {"text": anonymizer.anonymize} | prompt | llm
result = chain.invoke("Patient: John Doe, Diagnosis: Hypertension")
总结
langchain_experimental.data_anonymizer.PresidioAnonymizer
是基于 Presidio 的非可逆匿名化工具,核心功能包括: 定义 :检测和匿名化 PII,支持替换、掩码、redaction等操作。
初始化 :配置
analyzed_fields
、
operators
和
languages_config
。
方法 :
anonymize
处理文本,
add_operators
和
add_recognizer
自定义行为。
