敏感信息过滤:保护LLM应用中的数据安全
LLM 应用在输入和输出两个方向都可能涉及敏感信息——用户可能在对话中透露个人信息,模型也可能在生成内容时意外泄露敏感数据。系统化的敏感信息过滤机制是保护用户隐私和企业合规的基石。
一、敏感信息的范围
1.1 敏感信息分类
"""
敏感信息分类体系:
PII(个人身份信息)
├── 直接标识符:姓名、身份证号、手机号、邮箱、地址
├── 间接标识符:IP地址、设备ID、生物特征
└── 敏感PII:银行账号、医疗记录、犯罪记录
企业敏感信息
├── 商业机密:未公开的产品规划、源代码
├── 内部数据:员工信息、财务报表
└── 技术秘密:API密钥、数据库密码
"""
SENSITIVE_CATEGORIES = {
'pii_direct': {
'name': '直接PII',
'patterns': ['身份证号', '手机号', '邮箱', '家庭地址'],
'masking': 'required'
},
'pii_credential': {
'name': '凭证信息',
'patterns': ['API密钥', '密码', 'Token', '密钥'],
'masking': 'required'
},
'enterprise_confidential': {
'name': '企业机密',
'patterns': ['内部代号', '未公开数据'],
'masking': 'recommended'
}
}
1.2 检测场景
| 场景 | 输入方向 | 输出方向 | 风险等级 |
|---|---|---|---|
| 用户输入PII | ✅ 用户对话中泄露 | — | 高 |
| 模型泄露PII | — | ✅ 模型输出训练数据 | 高 |
| 文档包含密钥 | ✅ 上传文档 | — | 极高 |
| 日志记录PII | ✅ API调用记录 | — | 中 |
二、PII 检测与脱敏
2.1 PII 检测器
import re
from typing import List, Tuple
class PIIDetector:
"""
多类型 PII 检测器
"""
# 中国 PII 模式
CN_PATTERNS = {
'phone': r'1[3-9]\d{9}',
'id_card': r'\d{17}[\dXx]',
'email': r'[a-zA-Z0-9._%+-]+@[a-zA-Z0-9.-]+\.[a-zA-Z]{2,}',
'ip_address': r'\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3}',
'bank_card': r'\d{16,19}',
'api_key': r'(?:sk-|pk-|api-)[a-zA-Z0-9]{16,}',
}
def detect(self, text: str) -> List[dict]:
"""检测文本中的PII"""
findings = []
for pii_type, pattern in self.CN_PATTERNS.items():
for match in re.finditer(pattern, text):
findings.append({
'type': pii_type,
'value': match.group(),
'position': (match.start(), match.end()),
'risk_level': self._assess_risk(pii_type)
})
return findings
2.2 脱敏处理
class DataMasker:
"""
数据脱敏器
"""
MASKING_RULES = {
'phone': lambda s: s[:3] + '****' + s[-4:],
'id_card': lambda s: s[:4] + '**********' + s[-4:],
'email': lambda s: s[0] + '***@***' + s.split('@')[1][-4:],
'api_key': lambda s: s[:6] + '...' + s[-4:],
'bank_card': lambda s: '****' + s[-4:],
'ip_address': lambda s: '.'.join(s.split('.')[:1]) + '.***.***.***',
}
def mask(self, text: str, pii_findings: List[dict]) -> str:
"""对检测到的PII进行脱敏"""
result = text
# 从后往前替换,避免位置偏移
sorted_findings = sorted(
pii_findings,
key=lambda x: x['position'][1],
reverse=True
)
for finding in sorted_findings:
pii_type = finding['type']
start, end = finding['position']
original = finding['value']
if pii_type in self.MASKING_RULES:
masked = self.MASKING_RULES[pii_type](original)
else:
masked = '***'
result = result[:start] + masked + result[end:]
return result
三、Prompt 中的安全设计
3.1 安全 System Prompt
secure_system_prompt = """
你是安全的AI助手。
【数据安全规则】
1. 不要请求用户提供任何个人敏感信息(身份证、银行卡、密码等)
2. 如果用户主动提供了敏感信息,提醒用户注意保护隐私
3. 不要在你的回复中包含任何用户的个人信息
4. 不要在你的回复中包含任何真实的电子邮件、电话号码或地址
5. 如果你发现回复中包含疑似敏感信息,将其替换为"[已脱敏]"
【示例】
用户说:"我的手机号是13812345678"
你应回答:"我注意到你分享了个人手机号。为了你的隐私安全,建议不要在公开对话中分享个人信息。你希望我记住这个号码用于后续服务吗?(请注意,对话记录也会保存你的信息)"
"""
3.2 输出过滤
class OutputFilter:
"""
输出过滤器
在模型回复返回给用户之前进行过滤
"""
def __init__(self):
self.pii_detector = PIIDetector()
self.masker = DataMasker()
def filter_output(self, response: str) -> str:
"""过滤模型输出中的敏感信息"""
# 检测PII
findings = self.pii_detector.detect(response)
if findings:
# 脱敏
response = self.masker.mask(response, findings)
# 添加警告
warning = "\n\n⚠️ 【安全提醒】以上回复已自动过滤敏感信息。"
response += warning
return response
四、生产级过滤架构
4.1 过滤流水线
用户输入
│
├─ L1: 输入过滤器
│ ├─ PII检测 → 提醒用户
│ └─ API密钥检测 → 拒绝(不处理含密钥的请求)
│
▼
LLM 处理
│
▼
├─ L2: 输出过滤器
│ ├─ PII检测 → 脱敏
│ ├─ 密钥检测 → 替换
│ └─ 合规检查 → 标记
│
▼
用户接收
4.2 合规记录
class ComplianceLogger:
"""
合规审计日志
"""
def log_detection(self,
direction: str, # input/output
pii_type: str,
original_value: str,
masked_value: str):
"""记录敏感信息检测事件"""
log_entry = {
'timestamp': datetime.now().isoformat(),
'direction': direction,
'pii_type': pii_type,
'risk_level': 'high' if pii_type in ['id_card', 'bank_card', 'api_key'] else 'medium',
'original_prefix': original_value[:6] + '***',
'action': 'masked',
}
# 写入审计日志
with open('compliance.log', 'a') as f:
f.write(json.dumps(log_entry, ensure_ascii=False) + '\n')
五、最佳实践
5.1 过滤策略矩阵
| 数据类型 | 输入处理 | 输出处理 | 合规要求 |
|---|---|---|---|
| 手机号 | 警告用户 | 自动脱敏 | 法律要求 |
| 身份证号 | 警告并阻止 | 自动脱敏 | 法律要求 |
| 银行卡号 | 警告并阻止 | 自动脱敏 | 法律要求 |
| API密钥 | 自动拒绝 | 自动替换 | 安全要求 |
| IP地址 | 可选脱敏 | 可选脱敏 | 合规建议 |
| 邮箱 | 可选脱敏 | 可选脱敏 | 法律要求 |
5.2 实施建议
- 不要只依赖模型自律:模型可能被绕过,必须要有独立的过滤层
- 区分场景:客服场景 vs 医疗场景,敏感度阈值不同
- 保留审计日志:合规要求需要可追溯
- 用户透明:通知用户敏感信息被过滤或脱敏
总结
敏感信息过滤是 LLM 应用合规运营的底线。通过建立输入/输出双向过滤机制、结合正则检测和脱敏处理,可以在保护用户隐私的同时确保业务合规。这不是可选的增强功能,而是生产级应用的必备组件。