大模型调用前应统一设计敏感数据脱敏
文章建议在所有模型调用前设置统一的敏感信息检测与替换服务,避免各业务功能重复实现。它强调检测存在漏报,应使用自身流量的标注样本评估,并通过模型抽象层降低供应商切换成本。
AI 深度解读
选模型可以反复试,客户数据一旦发出去,却很难收回。作者因此提出一个判断:处理企业业务数据的 AI 系统,应该把更多设计精力放在模型调用前的敏感信息遮蔽层,而不是模型选型上。
这篇文章的价值,在于把「注意隐私」拆成了工程问题:哪些字段直接替换,自由文本怎么检测,所有调用如何统一收口,以及检测一定会漏时怎么办。对正在接入客服工单、内部助手或业务查询的开发者,这些问题比模型排行榜更接近上线门槛。
为什么遮蔽层应该排在模型选型前面
作者的理由是,两种决策的可逆程度不同。
模型藏在统一接口后面,后续可以换供应商,也可以迁到本地部署。客户姓名、地址和订单历史一旦传到不该接收它们的地方,后续换架构无法撤回这次传输。数据还可能进入日志、缓存或其他处理环节,具体取决于接收方的政策和配置。
作者以 GDPR 为例,强调数据保护负责人关心的是「哪些数据离开了基础设施」。这里讨论的是系统设计方向,不能据此推导出「加了遮蔽层就满足合规要求」。
还有一个现实差异:供应商会持续更新模型,却没人替团队弄清楚,自家哪个备注字段经常混入手机号,哪些订单信息组合起来能够识别客户。这部分知识只能靠团队积累。
遮蔽层具体做三件事:找出敏感片段,用占位符替换,再在响应返回后恢复真实值。占位符与原值的映射始终留在内部,恢复过程沿用业务系统原有的访问权限。
这也是遮蔽与匿名化的区别。匿名化要求无法恢复原值,适合公开数据集;遮蔽保留受控恢复能力,适合需要操作真实订单、服务真实客户的助手。
遮蔽层的目标,是让模型只接触完成任务所需的信息,同时把恢复真实身份的能力留在可信边界内。
同一个客户要用同一个代号,但别让代号永久有效
检测要先区分结构化字段和自由文本。
数据库已经标明某列是姓名、银行账号,就可以按 schema 直接遮蔽,不必再让模型猜。格式严格的标识符适合用 regex,规则快,也容易审查。
难点在客服工单、发票描述和备注。姓名可能有多种语言写法,地址可能没有完整格式,数字是不是身份证号还要看上下文。这类问题需要命名实体识别(NER),即找出文本中哪些片段属于姓名、地址等类别。
作者推荐分层处理:先按 schema 遮蔽,再用 regex 识别格式化标识符,最后让 NER 补充自由文本检测。
替换时,同一次请求里的同一个人应当稳定对应 CUSTOMER_1。模型才能知道,下单和投诉的是同一个客户。订单也可以用 ORDER_17 这样的代号关联。
但稳定代号仍可能被上下文反推出身份。因此,映射范围应当尽量小,能限制在一次请求里,就不要默认跨会话永久复用。
遮蔽规则也不能一刀切。询问配送路线时,城市名可能就是推理所需信息,全部替换会损害答案。作者认为一致占位符通常只带来较小质量损失,但没有给出对照实验,不能把这个判断套到所有任务。
架构上,作者主张所有模型调用经过同一个遮蔽网关,代码库里其他部分不持有模型供应商的 API key。这样可以统一测试、更新规则,并审计实际发送的内容,避免几个功能各写一套规则后逐渐分叉。
本地模型也需要这层控制。即使没有外部供应商,原始 prompt 仍可能进入日志、追踪记录和评估数据集。
小模型可以做检测,但分数不能替生产流量担保
作者引用了两组研究结果。
第一组是 2026 年 5 月发布的 GLiNER2-PII:参数量为 0.3 billion,即 3 亿,支持跨语言提取 42 类个人身份信息(PII)。训练使用约束生成的合成语料,共 4,910 条已标注文本,而非真实个人文本。
按照原文转述,它在 SPY 基准上的片段级 F1,高于参与比较的 OpenAI Privacy Filter 和三个基于 GLiNER 的检测器。作者据此认为,检测任务不必依赖大型生成模型,小模型可以在内部硬件上运行。但原文没有提供吞吐、延迟和资源占用,实际部署仍要测。
第二组来自 PIIBench。这个经过修正、汇集多个来源的数据集覆盖 82 类实体。在包含 100,002 条记录的测试集上,直接进行 token classification 微调的 DeBERTa 达到 F1 0.6455,超过同一研究中的来源条件化层级模型和课程学习变体。
它支持的结论是:在这组比较里,多样且贴近任务的数据,比增加架构复杂度更有效。它不能证明所有检测任务都适用这个排序。
F1 0.6455 也不能解读成「漏掉了 35.45%」。F1 综合了精确率和召回率,不能直接换算漏检比例。原文借这个数字强调检测仍会出错,这个方向成立。
作者自己的数据还包含保加利亚姓名、西里尔字母及多种拉丁转写、格式容易与普通数字冲突的国家标识符,以及藏在备注里的地址。公共基准很难覆盖这套组合。作者提到,后续公开数据测试暴露了 GLiNER2-PII 对姓氏的弱点,但本文没有提供具体数值。
真正可操作的办法,是从自己的流量中取几百条样本,人工标注敏感片段,再按实体类型统计召回率。
这里应优先关注漏掉了多少敏感信息,而不是只追求一个好看的综合分数。
误报会多遮蔽一些内容,可能损失答案质量;漏报则可能把个人数据发出去。作者因此建议偏向多遮蔽。对不能接受漏检的类别,应直接排除相关字段,或把请求限制在本地模型路径中。
此外,泄露可能来自组合信息:城镇、配送时段和少见姓氏,单独看都不醒目,放在一起却可能识别某个人。逐类召回率也覆盖不了全部风险。
我的判断
我认同作者把遮蔽放在统一边界上的做法。对多个业务功能共用模型能力的团队,这比每个 prompt builder 各自补规则更容易维护。作者也交代了实际使用场景:文本请求处理、文档对账,以及供同事助手查询公司数据的内部服务。
但「遮蔽层比模型更重要」有适用前提。接触客户、订单和内部数据时,这个排序很有说服力;只处理公开资料的工具,优先级可能不同。
原文也有几处需要保留问号。作者没有提供团队实施前后的泄露率、维护成本,或遮蔽对回答质量影响的对照数据。因此,统一网关的收益和「质量损失较小」仍主要是经验判断。两篇研究的数据,也不能直接作为作者生产系统的效果证明。
统一网关还必须真正覆盖调用路径。如果应用能够绕过它直连供应商,或者日志提前记录了原始输入,架构图上的集中控制就不完整。审计记录本身也要控制内容和权限,避免形成新的敏感数据副本。
最值得保留的是作者承认「没有零泄露方法」。遮蔽需要与字段最小化、权限控制、本地处理配合使用。把原始敏感文本先发给托管大模型检测,也只是提前发生了原本想避免的数据传输。
能拿来做什么
- 给现有 Node 模型调用封装增加统一入口,把供应商 API key 和发送逻辑集中管理,并检查业务模块是否仍有直接调用路径。
- 为客服工单、订单备注等真实输入整理几百条标注样本,分别统计姓名、电话、地址和业务标识符的召回率,先确认最容易漏的是哪一类。
- 在单次请求内维护稳定占位符映射,让
CUSTOMER_1和ORDER_17保留业务关联;恢复结果时继续按当前用户权限判断可见范围。 - 按任务裁剪输入字段。路线问题保留必要地理信息,对不能接受外发漏检的数据,直接排除或转入本地处理路径。