提示词出进程前先脱敏:给一把 key 做发送前的过滤层
讲解如何在把请求发往多个模型后端之前,在本地加一层脱敏过滤:识别密钥、令牌与 PII,用可还原的占位符替换,并在响应返回后按需还原;包含工程实现要点与与聚合 API 协作时的注意事项。
把同一个请求发给不同模型时,最容易忽略的不是模型选择,而是请求里到底带了什么。日志、调试代码、复制的配置片段里经常混入 API key、访问令牌、手机号、邮箱、身份证号。多后端聚合意味着这段内容会被转发到多个上游,脱敏放在客户端发出之前最稳妥。
为什么放在进程内而不是上游
脱敏层的位置决定它能拦住什么。放在上游服务端,你无法确认它拦了什么、日志里是否落了原文;放在本地进程内,请求离开你的机器之前就完成替换,日志、重试、缓存拿到的都是脱敏后的版本。
对聚合 API 来说也有一层现实考虑:你的一把 key 可以调多个后端,但每个后端收到的仍然是同一份文本。只要文本里有不该外发的信息,多后端就等于多份副本。
先分类:要拦什么
按可识别性和替换方式把敏感项分三类:
- 高熵凭证:API key、访问令牌、私钥片段、session token。特征是长度固定或前缀明显、字符集随机。这类只做掩码,不还原。
- 结构化 PII:邮箱、手机号、身份证号、银行卡号、IP。可以用正则加校验(长度、校验位)降低误报。
- 自由文本实体:人名、地址、公司名。规则难覆盖,通常靠模型或词表辅助,允许漏,不追求 100%。
优先级是按确定性从高到低处理,先处理凭证,再处理结构化 PII,最后处理模糊实体。
占位符要可还原
常见做法是替换成 [REDACTED],但这样模型无法理解上下文,回答质量下降,而且你也没法把结果映射回原文。更好的做法是带类型的占位符:
邮箱 -> <EMAIL_1>
手机号 -> <PHONE_1>
内部服务名 -> <SERVICE_1>
要点:
- 占位符本身不能包含原文片段,也不能是可被猜测的哈希(低熵值可暴力枚举)。
- 类型标签让模型知道这里是一个邮箱还是一个标识符,保留语义。
- 编号在同一请求内唯一,跨请求重置,避免跨请求关联。
- 维护一张本次请求内的映射表
placeholder -> 原文,只存在内存,不落盘、不进日志。
还原只在需要时做:把模型返回的文本按占位符替换回原文,用于展示或后续处理。如果返回内容要写日志或再发给第三方,保持占位符状态。
实现骨架
一次请求的处理顺序建议是:
- 收集候选:对消息文本、工具调用参数、系统提示逐字段扫描,不要只扫
content。 - 匹配规则:凭证用前缀加长度的正则;PII 用正则加校验函数;对命中项去重。
- 替换并记录:按出现顺序生成占位符,写入本请求映射表。
- 发送:请求体里只出现占位符。
- 响应处理:需要原文时按映射表还原;不需要时直接丢弃映射表。
伪代码:
def sanitize(text, mapping):
for rule in RULES:
text = rule.sub(lambda m: mapping.put(rule.tag, m.group(0)), text)
return text
mapping.put 对相同原文返回相同占位符,避免同一实体在一个请求里出现多个编号,影响模型理解。
与多模型后端协作的注意点
- 系统提示也要过一遍:很多泄露来自系统提示里粘的示例配置。
- 工具调用参数是盲区:函数名安全,参数不一定,尤其带
url、token、headers的字段。 - 流式响应:还原要按占位符完整匹配再替换,跨 chunk 的占位符需要缓冲,否则会替换失败。
- 多模态:图片、文件名同样可能带信息,至少处理文件名和路径。
- 重试与缓存:重试时复用同一映射表,缓存键基于脱敏后的文本,避免缓存层成为泄露点。
误报与漏报的取舍
规则型脱敏一定有两类错误。误报(把正常文本当敏感项)会让模型回答变差;漏报会泄露。取舍方式:
- 凭证类宁可误报,因为代价不对等。
- 结构化 PII 用校验位和上下文消歧,降低误报。
- 自由文本实体默认不自动处理,改为提示或人工确认。
把命中记录成计数和类型(不含原文),方便观察规则效果,也方便在日志里排查为什么某段文本被替换。
和计费、key 的关系
脱敏层在客户端,和聚合站的计费、key 管理是两条独立路径。你仍然是用一把 key 调多个模型,按官方价 ×1.3 扣费;贡献 key 的返利逻辑也不受影响。区别在于:发出去的每个请求里,敏感字段已经在本地被替换。
如果你的场景涉及把内部 key 贡献出去换返利,脱敏层更必要——先确认请求体和日志里没有其他凭证,再谈共享。
检查清单
上线前至少自查:
- 扫描覆盖消息、系统提示、工具参数、文件名。
- 占位符不可反推原文,映射表不持久化。
- 流式还原做了跨 chunk 缓冲。
- 日志、缓存、重试路径都不含原文。
- 误报有观测手段,规则可迭代。
脱敏不是一次配置,而是请求链路上的一个固定环节。把它放在进程内、发送之前,是唯一能同时覆盖多后端和本地日志的位置。