大模型应用怎么防止敏感信息泄露?
一句话回答
泄露主要有四条路:系统提示被套出、回答里带出其他用户或内部的数据、日志、发给第三方模型供应商。对应的做法:系统提示里不放密钥和敏感配置,默认它会被公开;RAG 检索和工具调用按当前用户的权限过滤,让无权访问的数据根本进不了上下文;多租户数据在每一层都隔离;发送前对个人信息脱敏;日志脱敏并控制访问;了解供应商的数据使用和留存政策,高敏感场景考虑私有化部署。
详细解析
泄露途径和对策
| 途径 | 例子 | 对策 |
|---|---|---|
| 系统提示被套出 | 用户诱导模型复述系统提示,里面写着内部接口地址和数据库密码 | 系统提示只写行为规则,密钥放在服务端配置里由代码使用 |
| 回答带出无权查看的数据 | 普通员工问出了知识库里的薪资文件;工具返回了完整的用户记录,模型照着念了出来 | 检索和工具调用按用户权限过滤;工具只返回任务需要的字段 |
| 跨用户、跨租户 | 缓存、长期记忆、向量索引没有按用户隔离,A 的数据出现在 B 的回答里 | 存储和缓存的 key 都带上租户和用户;查询强制带隔离条件 |
| 日志和可观测平台 | 完整的对话写进日志,开发、运维、外包人员都能看到 | 写入前脱敏;按角色控制访问;设置保留期限 |
| 第三方模型供应商 | 用户的身份证号、病历原样发给了云端模型 | 发送前脱敏;了解供应商政策;高敏感数据用私有化模型 |
| 分享和导出 | 对话的分享链接被搜索引擎收录 | 分享的是快照、可以撤销,分享页禁止搜索引擎收录 |
系统提示:假设它会被公开
OWASP 的大模型风险清单明确指出,系统提示不应被当作秘密,也不应被当作安全控制手段,因为提示注入总有办法让模型复述它。所以:
- 不放密钥、连接串、内部地址
- 权限规则(如"普通用户不能查看他人订单")不能只写在提示里,要由代码执行
- 可以在系统提示里放一个随机的"金丝雀"字符串,输出中出现它,就说明提示正在被原样复述,拦截并告警。它发现不了换个说法的复述,只是一个监控信号
权限控制要在数据进入上下文之前
模型无法可靠地判断"这段内容不该告诉这个人"。无权访问的数据一旦进入上下文,就可能出现在回答里。所以:
- RAG 检索时带上权限过滤条件(部门、用户组、租户),不要检索出来再让模型筛选,见知识库问答系统
- 工具用当前用户的身份调用下游接口,而不是用一个能看所有数据的服务账号
- 工具的返回值做字段裁剪:查订单状态不需要返回收货人的身份证号
发给供应商之前
- 了解供应商的数据政策:接口数据是否用于训练、保留多久、能否申请不留存、存储在哪个地区
- 满足所在地区个人信息保护和数据出境的要求
- 医疗、金融、政务等高敏感场景,考虑私有化部署,见云端 API 还是私有化部署
代码示例
发送前把身份证号、手机号、邮箱替换成占位符,收到回答后再还原。总结、改写、分类这类任务并不需要真实值:
const RULES: [string, RegExp][] = [
['ID', /(?<!\d)\d{17}[\dXx](?!\d)/g], // 18 位身份证号,要在手机号之前匹配
['PHONE', /(?<!\d)1[3-9]\d{9}(?!\d)/g], // 大陆手机号
['EMAIL', /[\w.+-]+@[\w-]+(\.[\w-]+)+/g],
]
export function mask(text: string) {
const map = new Map<string, string>()
let n = 0
for (const [type, re] of RULES) {
text = text.replace(re, (value) => {
const key = `[${type}_${++n}]`
map.set(key, value)
return key
})
}
return { text, map }
}
// 把回答里的占位符换回真实值,再展示给用户
export function unmask(text: string, map: Map<string, string>) {
for (const [key, value] of map) text = text.replaceAll(key, value)
return text
}
正则只能处理格式固定的信息,有漏也有误伤:写成 138-1234-5678、或者紧跟在 +86 后面的手机号会漏掉;18 位纯数字的订单号会被当成身份证号,可以再用身份证的校验位过滤一遍。姓名、地址这类信息需要命名实体识别模型或专门的脱敏服务。Prompt 里要说明"方括号里的占位符原样保留",还原前检查占位符有没有被模型改写。
面试官可能追问
怎么防止 A 用户的数据出现在 B 用户的回答里?
检查每一个"共享"的地方:结果缓存和语义缓存的 key 要带用户或租户,长期记忆按用户存取,向量检索强制带租户过滤条件,对隔离要求高的租户在物理上分开(独立的索引或库)。再写专门的跨租户测试:用 A 的身份提问,断言结果里不出现 B 的数据。语义缓存的风险见语义缓存。
用用户的对话数据微调模型,有什么风险?
模型可能记住训练数据,在别的对话里原样输出,已经有研究能从模型中提取出训练数据。数据一旦进入权重就很难删除,用户要求删除个人信息时难以响应。所以要事先取得用户同意,训练前去标识化、去重;需要模型"知道"的业务知识,优先用 RAG 而不是微调。
系统提示已经被套出来了,要怎么处理?
先看里面有没有敏感信息。如果有密钥、内部地址,立即轮换密钥、评估暴露的接口,并把这些内容移出提示。如果只有业务规则和话术,影响通常有限,不必花大力气阻止复述,重点检查有没有安全控制依赖了提示本身,把它们改成由代码执行。
易错点
- 在系统提示里写"不要泄露以下信息",再把信息写在后面,等于直接交给了模型
- 先检索、再让模型判断用户有没有权限:数据已经进了上下文
- 只给发往模型的请求脱敏,日志里却保存着原文;可观测平台、标注平台也是第三方
AI 模拟面试官
用自己的话回答,AI 对照参考答案打分、指出遗漏,再追问,最多 3 轮
这道题你掌握了吗?
选一个最接近的状态,没掌握的题会出现在"我的进度 · 待复习"里。
学习记录暂存在本机浏览器。登录后自动同步到账号,换设备也能看到。