背景:LLM 数据外泄不止发生在模型回答里
企业把 LLM 接入客服、合同审阅、知识库问答、研发助手、工单总结和销售运营后,最容易被低估的风险不是「模型会不会胡说」,而是请求链路里到底带了多少不必要的敏感数据。
一个用户可能在问题里输入姓名、手机号、身份证号、银行卡后四位、家庭住址、病情描述、合同金额、员工编号或客户编号。业务系统也可能在构造 Prompt 时自动拼接 CRM 字段、订单字段、邮件原文、工单备注和调试上下文。如果这些内容直接进入模型 API、应用日志、Trace、Prompt 回放平台或人工审核队列,就会形成多条外泄路径。
这类问题不能只靠一句系统提示解决。系统提示可以要求模型不要泄露敏感信息,但它无法阻止敏感字段在请求发出前已经进入第三方模型、日志系统或观测平台。更稳妥的方式是在 LLM 调用链路前放置一层隐私脱敏网关,把「能不能发、发多少、怎么代换、哪里可还原、日志保存什么」变成可审计的工程策略。
核心原理:先做数据最小化,再做可控代换
1. 识别:把 PII 从普通文本中定位出来
PII 识别不是一个单一正则问题。不同类别的敏感数据需要不同的识别手段:
| 识别器类型 | 适用场景 | 典型实体 |
|---|---|---|
| 确定性识别器 | 格式稳定的数据 | 邮箱、手机号、URL、IP、银行卡、证件号、密钥片段 |
| 语义识别器 | 上下文敏感实体 | 姓名、地点、组织、岗位、医疗描述、家庭关系 |
| 业务识别器 | 企业内部字段 | 客户号、保单号、订单号、员工工号、合同编号、渠道编码 |
识别阶段不能只输出「命中/未命中」,还应输出实体类型、起止位置、置信度、识别器来源、命中规则版本和是否需要人工复核。这些元数据决定后续是删除、遮蔽、假名化还是保留。
2. 最小化:不是所有字段都应该进入模型
隐私治理的第一原则是数据最小化。在调用模型前,先问一个问题:这个任务真的需要这些敏感字段吗?
- 让模型「总结投诉原因」时,客户姓名、手机号、身份证号通常可以删除
- 让模型「判断用户是否满足某个年龄段规则」时,不一定要传完整生日,可以传年龄段
- 让模型「生成理赔材料清单」时,可能需要险种、事故类型和材料状态,但不需要银行卡号
网关不应默认「识别后全部替换」,而应基于任务类型配置最小化策略:
task_policy: claim_material_summary
allow_entities:
- POLICY_TYPE
- ACCIDENT_TYPE
- MATERIAL_STATUS
transform_entities:
PERSON: pseudonymize
PHONE_NUMBER: redact
ID_CARD: redact
BANK_CARD: redact
log_level: metadata_only
这类配置的价值在于把 Prompt 隐私治理从开发人员个人习惯,转变为可审计、可回放、可灰度的策略。
3. 代换:在不可逆删除和可逆假名化之间做选择
PII 处理常见有四种方式:
| 处理方式 | 适用场景 | 示例 |
|---|---|---|
| 删除 | 完全不需要的字段 | 「手机号:138xxxx」→ 直接移除 |
| 遮蔽 | 需要识别大致形态但不需要完整值 | 138****5678 |
| 固定标签替换 | 模型只需知道实体类别 | 「张三」→ [PERSON] |
| 可逆代换 | 模型需保持上下文一致性 | 「张三」→ PERSON_001,「广州某公司」→ ORG_001 |
可逆代换的关键是映射表不能和 Prompt、日志、Trace 存在同一个安全域。如果把原文、代换后文本和映射表一起写进日志,实际上没有降低风险,只是换了一种泄露格式。
{
"request_id": "req_20260709_0001",
"tenant_id": "tenant_a",
"entity_map_ref": "vault://llm-redaction-map/7f3a...",
"redacted_prompt": "请总结 PERSON_001 的投诉内容,联系电话已省略。",
"entities": [
{"type": "PERSON", "token": "PERSON_001", "confidence": 0.93},
{"type": "PHONE_NUMBER", "token": "[REDACTED]", "confidence": 0.99}
]
}
4. 响应回填:只在必要位置恢复真实值
有些业务场景需要模型生成可直接发给用户的文本,此时可逆代换会带来一个问题:模型输出里可能出现 PERSON_001、ORG_002 这类代称。
生产系统不能让前端随意拿映射表回填。正确做法是把回填放在后处理服务中,由策略决定哪些字段可以恢复、恢复给谁、恢复到哪个渠道:
- 内部客服坐席工作台可以看到真实客户名
- 外部短信模板不能包含完整证件号
- 导出的审核材料只能出现遮蔽手机号
这意味着脱敏网关要管理的不只是请求前处理,还包括响应后处理和渠道级恢复策略。
工程落地:把隐私脱敏网关做成数据平面能力
链路位置
推荐架构是:业务服务先生成结构化 LLM 请求,再进入隐私脱敏网关;网关完成任务识别、PII 检测、策略决策、文本改写、审计记录后,再调用模型网关或模型供应商。
Business Service → LLM Privacy Gateway
→ Task Policy Resolver
→ PII Detector
→ Redaction / Pseudonymization Engine
→ Mapping Vault
→ Minimal Logging Adapter
→ LLM Provider / Model Gateway
→ Response Post-Processor
→ Business Channel
不要把脱敏逻辑散落在各个业务服务里。 分散实现会产生三类问题:规则版本不一致、日志口径不一致、事故发生后无法证明哪些请求被处理过。
请求对象设计
网关最好处理结构化请求,而不是只接收一整段 Prompt 字符串:
{
"tenant_id": "tenant_a",
"app_id": "support_assistant",
"task_type": "ticket_summary",
"messages": [
{"role": "system", "content": "你是客服质检助手。"},
{"role": "user", "content": "客户张三反馈手机号13800000000无法登录。"}
],
"business_context": {
"ticket_id": "T20260709001",
"channel": "internal_console"
},
"privacy_profile": "support_default"
}
结构化请求可以对不同来源采用不同策略:User Input 严格检测,System Instruction 不应携带客户数据,Tool Result 按工具类型处理,Retrieved Context 需先判断是否包含跨租户或越权数据。
策略版本与灰度
PII 检测和脱敏策略会不断演进。新增识别器可能降低漏检,也可能提高误杀。生产系统应把策略当成可发布配置,而非写死在代码里。
推荐至少记录:policy_version、detector_version、model_version、replacement_strategy、decision_trace。当用户反馈「模型回答不完整」或安全团队发现「某类证件号漏检」时,可以回放同一请求,比较新旧策略效果。
日志最小化
很多团队完成了请求脱敏,却在日志里把原始 Prompt 打了出来,这会直接抵消脱敏收益。LLM 链路日志建议分为三层:
| 日志层级 | 内容 | 用途 |
|---|---|---|
| 指标日志 | 请求数、命中 PII 数量、实体类型分布、阻断次数、代换次数、延迟、Token 数量 | 监控与告警 |
| 审计日志 | 请求 ID、租户、应用、策略版本、动作类型、实体类型、是否回填、操作者 | 合规审计 |
| 隔离样本日志 | 少量采样的脱敏前后对照,仅存于安全域 | 识别器质量评估 |
默认应用日志、Trace、错误堆栈和 APM Breadcrumb 不应保存原始 Prompt。
适用场景
隐私脱敏网关适合以下场景:
- 客服、工单、邮件总结和呼叫中心:用户自然语言里经常带有姓名、手机号、地址、订单号和投诉细节
- 合同、保单、理赔、金融审核和医疗问答:文档含有高度敏感字段,模型只需部分业务事实
- 企业内部 Copilot:员工可能粘贴客户资料、代码密钥、数据库连接串和内部链接
- 多供应商模型调用:同一请求可能路由到不同供应商,脱敏网关可把隐私策略稳定在企业侧
常见误区
误区一:只要供应商承诺不训练,就不需要脱敏
供应商的数据使用承诺只能降低一部分风险,不能替代企业自己的最小化义务。请求仍然可能经过代理、日志、调试平台、人工排障和内部数据湖。只要不必要的敏感字段离开业务系统,就增加了暴露面。
误区二:脱敏越彻底越好
过度脱敏会破坏任务质量。例如合同审查中,所有主体都替换成同一个 [ORG],模型可能无法判断责任归属;客服对话中,所有时间、地点、订单状态都删除,模型总结会变得空泛。正确目标不是「删得最多」,而是在满足任务质量的前提下暴露最少数据。
误区三:可逆代换没有风险
可逆代换的风险集中在映射表、密钥、权限和回填链路。映射表一旦和脱敏文本同时泄露,攻击者可以恢复原文。因此映射表必须独立存储、加密、最小授权、短期保留,并记录每次读取。
误区四:只检查请求,不检查响应
模型可能在响应中复述用户输入、组合多个字段、生成疑似个人信息,或把代换 Token 输出给不该看到的人。响应侧同样需要检测、回填控制和渠道过滤。
上线检查清单
| 层面 | 检查项 |
|---|---|
| 识别器 | 是否覆盖业务实体、通用 PII、密钥类信息;是否有置信度阈值;是否支持 Allowlist;是否能输出命中解释 |
| 策略 | 是否按任务类型配置允许字段、代换方式、阻断条件、日志级别和回填权限;是否支持灰度发布和回滚 |
| 链路 | 是否覆盖请求、响应、日志、Trace、错误堆栈、Prompt 回放、人工审核样本和导出任务 |
| 安全 | 映射表是否独立存储;密钥是否托管在 KMS/HSM;是否有租户隔离;是否记录读取审计;是否设置保留期 |
| 质量 | 是否建立漏检集、误杀集和任务质量回归集;是否用真实脱敏样本做人工校准;是否监控 PII 命中率突变 |
| 事故响应 | 是否能按 Request ID 查询原始策略版本;是否能定位使用了有缺陷识别器的请求;是否能快速禁用某类回填 |
是否应该把所有识别器都打开? 不建议。过多 InfoType 或识别器会增加延迟、成本和误杀。更好的做法是按业务场景配置检测范围——登录问题需要手机号、邮箱、账号;合同审查需要主体、地址、银行账号;研发助手需要密钥、Token、URL 和内部主机名。
模型是否可以自己判断哪些信息敏感? 模型可以辅助解释和复核,但不应作为唯一隐私边界。隐私网关要使用确定性规则、NER、业务词典、策略配置和审计系统建立可解释的控制面。模型判断可用于低置信度样本复核,但最终动作应由策略引擎决定。