发送给托管模型的每一个提示词都会离开你的环境。如果其中包含 API 密钥、密码或客户的个人数据,这些信息就已经在别人的系统里,还可能出现在双方的日志中。敏感信息检测,就是在提示词发送之前发现这类内容的做法。
敏感数据如何进入提示词
很少是故意的。常见途径:
- 粘贴的日志和堆栈跟踪,其中包含 token、连接字符串或会话 Cookie。
- 为调试而共享的配置文件:
.env、YAML、Terraform。 - 硬编码了凭据的代码。
- 工单、邮件和聊天记录中的客户记录。
- 检索到的文档,包含的内容超出了问题所需。
- 仓库中的提示词文件,有人曾用真实密钥做过测试。
- 智能体循环中的工具结果,未经过滤就被转发给模型。
两类数据,两种风险
密钥授予访问权限:API 密钥、token、密码、私钥、连接字符串。泄露的密钥可以被立即利用。应对办法是吊销并轮换。
**个人数据(PII)**可识别个人:姓名、电子邮件地址、电话号码、邮寄地址、支付卡号、国民身份证号。发送这些数据可能违反你的隐私承诺或法律,而且它们无法轮换。
检测如何工作
检测器会组合多种方法,因为每种方法都有盲区。
已知格式。 许多提供商签发的密钥带有可识别的前缀和长度。可以高置信度地匹配这些密钥。
上下文模式。 像 password = "..." 或 api_key: ... 这样的赋值,会把该值标记为凭据,无论它是什么格式。
熵。 随机字符串的香农熵很高。紧挨着“token”或“secret”这类词的、较长且熵很高的值,很可能是凭据,即便格式未知。
结构化标识符。 电子邮件地址、电话号码和卡号都遵循一定模式。卡号还可以通过校验和确认。
命名实体识别。 统计模型可以找出没有固定模式的姓名、组织和地点。覆盖面更广,但误报更多,并且需要一个模型。
PromptFlowEngine 提示词安全扫描器使用前四种。它是确定性的,并在本地运行,所以被检查是否含有密钥的文本,不会为了检查而被发送到任何地方。
报告位置,而不是值
打印出所发现密钥的检测器,会在日志或终端里制造出该密钥的第二份副本。行为良好的扫描器只返回类别和位置:
{
"hasSensitiveData": true,
"countsByCategory": { "api_key": 1, "email": 1 },
"matches": [
{ "category": "api_key", "start": 118, "end": 164 },
{ "category": "email", "start": 176, "end": 196 }
]
}
这就是 PromptFlowEngine 在所有界面中返回的结构。完整示例见敏感数据规则。
脱敏
脱敏用占位符替换每个检测到的值,同时保留周围文本的含义。
Before: Connect with postgres://admin:hunter2@db.internal:5432/app
After: Connect with [REDACTED_CONNECTION_STRING]
像 [REDACTED_API_KEY] 这样带类型的占位符,比一排星号更好,因为模型仍然知道那里原本是什么类型的东西,可以在看不到它的情况下对其推理(“这个连接字符串看起来格式有误”)。
对于任务需要引用的个人数据,在同一次请求内使用一致的化名:同一个电子邮件的每次出现都变成 [EMAIL_1],下一个地址是 [EMAIL_2]。这样模型可以区分不同的人,而你的应用也可以在响应之后把占位符映射回去。
检查应放在哪里
尽早检测,并且在不止一个地方检测。
| 位置 | 能拦截什么 |
|---|---|
| 编辑器或聊天框中 | 一次粘贴,在发送之前 |
| 应用代码中,API 调用之前 | 来自用户、记录和检索的数据 |
| 智能体各步骤之间 | 即将进入上下文的工具结果 |
| CI 中,针对提示词文件 | 提交到仓库的凭据 |
| 记录日志之前 | 即将被存储的内容 |
Chrome 扩展会在 ChatGPT、Claude 或 Gemini 中的草稿含有密钥时发出警告,并可以在你的设备上对其脱敏。VS Code 扩展会在提示词发送到聊天之前运行隐私防护,提供严格、脱敏和警告三种模式。在 CI 中,检查门禁默认在出现任何严重级别的发现时失败,所以已提交的密钥会让构建停止。
策略选择:拦截、脱敏还是警告
- 拦截:密钥绝不应被发送时。最安全,也最具干扰性。
- 脱敏:作为默认选项。提示词在去掉敏感值之后通过。
- 警告:需要由人来决定时,例如代码中可能的误报。
无论你选哪一种,都请在本地执行密钥检测。为了弄清文本发送是否安全,却把文本发送到远程服务的检查,违背了初衷。
你应当了解的局限
- 漏报。 格式不寻常的密钥,或者像对某人的描述这样没有固定模式的个人数据,可能会漏过。检测可以降低风险,却不能证明提示词是干净的。
- 误报。 哈希、UUID 和测试固件可能看起来像密钥。请把已知安全的值加入允许名单,而不是禁用检查。
- 图片与文件。 文本扫描器不会读取截图或 PDF,除非先进行转换。
- 上下文。 一个名字在某种场合是公开的,在另一种场合却是机密。只有你的策略才能做出判断。
超越检测:少发送
最可靠的控制是根本不包含这些数据。
- 传递一个 ID,让工具去查找该记录,这样模型永远看不到它不需要的字段。
- 在构建提示词之前去掉相关字段。
- 把凭据保留在你的应用中,直接交给工具。模型永远不需要你的 API 密钥来请求某个工具调用 API。
- 在示例和提示词文件中使用测试数据。
如果密钥已经被发送
- 立即吊销并轮换。把它视为已被泄露。
- 检查访问日志,看是否被使用过。
- 从仓库历史和提示词文件中删除它。
- 添加一项检查,让下次能拦截同样的途径。