打开一个日益成熟的 AI 产品的生产环境系统提示词(system prompt),向下滑过角色描述,你几乎总能看到一个标有 # Examples 或 ## Few-shot demonstrations 的部分。这些示例非常出色——它们很具体,具有领域针对性,且精准地匹配了上季度评估集(eval set)中表现不佳的失败模式。但在仔细观察后,你发现它们其实也是真实的客户数据。来自真实账户的真实工单 ID。从支持会话中原封不动摘录的措辞模式。某个租户使用的内部产品代码,而其他客户群从未听说过。
把这些示例放进去的团队并不是粗心大意。这些示例进入提示词的方式与好示例一贯进入提示词的方式相同:有人从生产环境的追踪(traces)中挖掘出模型处理不佳的案例,挑选出最干净的现成示例,将其粘贴到系统消息中,看着评估分数上升,然后发布。这条从生产环境追踪到系统提示词的流水线,是现代 LLM 工程中最可靠的提示词改进闭环。但这也是团队在不知不觉中构建的一个结构性跨租户数据泄露渠道,而系统提示词已悄然变成了一个数据处理协议(DPA)从未涵盖的多租户数据存储库。
导致泄露的挖掘流水线
泄露并非始于粗心的工程师。它始于每个发布 LLM 功能的人最终都会采用的反馈闭环,因为除此之外的替代方案更糟。从零开始编写的合成示例往往平淡无奇;模型会模仿这些模式,产生同样平淡的输出。真实的生产环境追踪携带着用户实际措辞的质感、实际出现的边界情况以及实际需要教学的失败模式。因此,提示词改进周期固定为一种熟悉的模式:查看上周失败的评估案例,寻找三四个通过小示例就能引导模型走上正轨的案例,将它们复制到提示词中,进行 A/B 测试,然后发布。
在“复制示例”和“发布”之间发生的变化,本应是一个清洗(scrubbing)步骤。在实践中,这个步骤通常并不存在,即使存在,也只是编写提示词的工程师进行的单次审查——这位工程师通常不在安全或法律团队,他不知道 “Acme Logistics” 是一个真实客户的名字,不知道工单 ID 的格式可以还原到特定账户,也不知道示例中的措辞模式具有足够的辨识度,以至于原客户一眼就能认出来。
随后,系统提示词会发布给每个租户。无论登录的是哪个客户,每个会话都会将这些少样本(few-shot)示例作为其上下文的一部分进行读取。模型现在在租户 B、租户 C 以及其他所有租户的每个请求中都会接触到租户 A 的数据。这种暴露并非理论上的——它被编码在提示词加载的架构中。唯一的问题在于,模型是否以及何时会将其被展示的内容呈现出来。
为什么模型会复述
从机械角度看,上下文学习(In-context learning)是向模型展示一小组输入/输出对的数据集,并要求其复现该模式。这种模式不仅包括结构形状(问题跟在 User: 前缀后,答案跟在 Assistant: 后),还包括示例本身的词汇内容。当一个新的查询到来,且在结构上与某个示例相似时,模型已经在预训练、指令微调和提示词本身的条件约束中被训练过,去提取示例中的 token 作为最接近的可用参考。
其结果是,少样本示例会通过多个渠道同时泄露,且程度各异:
相似查询下的逐字复述。 如果新租户的问题措辞与示例的输入足够接近,模型通常会给出一个直接从示例中提取命名实体的答案。客户名称、工单编号、本不该出现在新租户会话中的产品 SKU,最终都会出现在回复中。
保留识别信号的“洗白式”改写。 即使模型用新的词汇重写了示例,潜在的事实——异常的行业词汇、特定的工作流形状、仅差一个同义词的命名实体——对于最初产生这些内容的任何人来说都是可识别的。改写不是匿名化;它只是为法律团队提供了合理推诿的借口,而为发现这一情况的客户提供了法证证据。
语气和结构的分布偏移。 租户 A 的沟通风格——正式的语调、列清单的习惯、对破折号的热衷——会渗入到交付给租户 B 的每一个回复中。跨会话泄露研究表明,这是最容易检测到的跨租户信号之一,因为风格的一致性是一个可识别的指纹。
通过精心设计的提示词进行提取。 一个有动机的攻击者,甚至是出于好奇的普通客户,都可以通过提问来探测提示词,旨在直接诱导模型输出少样本内容。KV 缓存共享研究已经证明,即使是侧信道攻击也可以重建提示词内容;上下文复述则是一个更容易的向量,甚至不需要缓存计时分析。
这个架构层面的现实令人不安:系统提示词在功能上是模型处理每个请求时的工作记忆(working memory)的一部分。任何粘贴进去的内容都已被添加到一个共享的底层基质中,而模型在被提示时,会被训练积极地去复现这些内容。
没人提及的法律视角
工程团队通常将泄露视为质量问题——“模型将特定的客户信息泄露到了其他租户的响应中”——并将其作为提示词微调任务进行处理。法律视角的定性则更为严峻。在过去三年签署的大多数数据处理协议(DPA)下,从租户 A 的会话中提取的 few-shot 示例,被视为租户 A 的个人数据为了租户 B 的利益而被处理。这是 GDPR 第 5(1)(b) 条中关于“目的限制”违规的教科书式定义,且在大多数包含“禁止跨租户数据使用”条款的企业级 SaaS 合同中是被明确禁止的。
欧洲数据保护委员会(EDPB)第 28/2024 号意见书强化了这一观点:由于 AI 模型具有记忆和重现能力,在大多数情况下,使用个人数据训练或调节的 AI 模型都受 GDPR 约束。该意见书并未在训练数据和提示词内容之间划出清晰的界限——而从监管者的角度来看,这种区分大多是无关紧要的。模型正在处理租户 A 的数据,作为控制者(SaaS 提供商),对于提示词所触及的每一个租户,该处理行为都需要有合法的依据和记录在案的目的。
合同使 AI 提供商的处境变得更糟。标准的企业 DPA 越来越多地包含一些条款,要求客户数据不得用于训练、改进或调节提供商的模型,以免使其他客户获益。这些条款原本是为了应对微调(fine-tuning)和 RLHF 而编写的,但它同样适用于 few-shot 示例。一场以“我们在另一个客户的对话会话中发现了我们内部的产品代码”开始的客户成功沟通,并不是一场关于质量的对话——而是一场关于违约的对话,并且根据司法管辖区的不同,还可能演变成一场监管通报对话。
这种组织职能的失败是结构性的。提示词作者属于 AI 团队。数据处理协议由法务部门负责。这两个团队都没有一套审核流程,能在生产字符串从租户会话转移到共享提示词时触发。风险最大的时刻对这两个部门来说都是不可见的。
必须建立的纪律 解决方法不是“停止使用 few-shot 示例”。Few-shot 提示词是有效的;精心挑选的示例带来的生产力提升是实实在在的,而发布不带示例的提示词则是在浪费准确性。解决方法是像对待代码提交中的机密信息(secrets)一样,严谨地对待示例挖掘流水线。以下几项实践结合在一起,可以弥合这一差距:
默认采用合成示例流水线。 在任何示例跨越租户边界之前,生产追踪记录(traces)都会进入脱敏步骤,剔除命名实体、工单 ID、产品代码和具有客户特征的措辞。这种脱敏是确定性的——相同的输入始终产生相同的脱敏输出——这样示例就能保持连贯性,模型仍能从结构中学习。在这里,伪匿名化(Pseudonymization)比掩码(masking)更有效:将“Acme Logistics 订单 #A1234”替换为“Company-1 订单 #ORDER-1”,而不是“[已脱敏]”,因为占位符保留了模型需要学习的结构化角色,同时抹去了识别性内容。
将 few-shot 审核视为代码安全审核。 添加到共享提示词中的每个示例都要经过一份清单审查,类似于源代码管理中对机密信息的审查。这个字符串是否包含客户名称?是否包含可逆的标识符?是否包含某个租户特有的措辞模式?是否包含任何源自 AI 团队自身文档之外的内部词汇?审核由提示词作者以外的人负责,因为作者有尽快上线的动力。
针对部署的提示词进行契约测试。 测试套件通过生产提示词运行一组合成查询样本,并断言 few-shot 示例中的任何字段都不会出现在输出中。测试失败不仅是因为完全匹配,还包括特征 token 的子字符串匹配。当测试在一个看似正常的查询上失败时,你就在客户发现之前拦截了一次泄露。
为每个示例记录溯源日志。 当一个示例被添加到提示词中时,日志会记录它来自哪个追踪记录、哪个租户生成了该记录、何时进行的脱敏以及谁批准了它。这是一条审计踪迹,让你能在源租户退出或撤销数据使用许可时收回特定示例,也是在监管机构询问某条个人数据如何进入共享提示词时,能够令其满意的凭证。将提示词作为产物进行版本管理的提示词管理工具使这变得可行;而临时的文本文件则做不到。
像对待数据库一样对提示词进行红队测试。 定期运行模拟攻击查询,旨在诱导模型逐字复述 few-shot 内容。任何泄露都被视为 P0 级事件,其响应姿态与 SQL 注入相同:回滚提示词、审计受影响的时间窗口,如果泄露超过通报阈值则进行通报。将提示词泄露视为质量问题的团队会从客户那里学到法律视角的教训;而将其视为安全问题的团队则会从红队报告中学习。
架构层面的启示 系统提示词(System Prompt)一直在稳步吸收那些本非为其设计的职责。它最初只是一个角色定义,后来逐渐积累了示例、工具描述、领域术语表,以及特定于客户的上下文片段。在这种增长过程中,它跨越了一个团队未曾察觉的阈值:它变成了一个数据存储(Data Store)。像所有数据存储一样,它也有向其中存入数据的租户和从中读取数据的租户。与团队运营的其他所有数据存储不同,它没有 Schema、没有访问控制、没有行级安全、没有审计日志,也没有保留策略。
尽早意识到这一点的团队会直面提示词的本质——一个参与每次推理请求的、共享的、仅限追加的(Append-only)多租户文档——并对其应用与生产数据库相同的规范。边界处的脱敏、写入前的审核、针对读取路径的测试、每一条目来源的追踪,以及模拟攻击者查询的红队探测。而那些没有察觉到这一点的团队,可能会发布一个 few-shot 示例,结果却发现离一次合同中未曾预料到的违约行为仅隔了一个客户支持工单。他们是从不得不重新协商的合同条款中吸取教训,而不是从自己运行的审计中学习。
这种规范的成本是实实在在的——脱敏流水线、审核流程、来源日志、测试套件——但这个成本是有界的(Bounded)。而在 GDPR 框架下未经披露的跨租户泄露或客户合同违约的成本则是无界的。权衡这两者的代价非常简单;难点在于如何说服团队,让他们意识到过去一年里一直在随意编辑的提示词,其实是一个需要像对待基础设施一样去对待的系统。这种态度的转变本身就是一项核心工作。率先完成这一转变的团队能够继续像往常一样发布提示词——只不过现在他们可以确信,自己发布的提示词不再是一个潜伏的违约风险。
会员专享
余下内容仅对会员开放。 会员可读完整内容 —— 每一个公开发布的观点背后,那些框架、决策与推理的全貌。
— 完整文章,包含未公开存档的部分 — 可落地的工作框架,附带权衡与决策依据 — 新文章抢先看,先于公开发布 登录以继续阅读→ 随时取消 · 一次订阅,畅读全部