跳到主要内容

多租户 Prompt 难题:当一个系统提示词要服务多个主人时

· 阅读需 10 分钟
Tian Pan
Software Engineer

你发布了一个新的平台级防护栏 (guardrail) —— 一条防止 AI 讨论竞争对手价格的规则。它在周一早上上线。到了周三,你最大的企业客户提交了一个支持工单:他们的销售助手 (他们曾精心调整该助手,以便为采购团队比较供应商选项) 停止工作了。他们没有更改任何东西。你更改了一些东西,而其影响范围 (blast radius) 在无形中波及了他们。

这就是多租户提示词问题 (multi-tenant prompt problem)。允许客户定制的 B2B AI 产品实际上是在运行一个分层指令系统,但大多数团队并没有将其视为一个系统。他们将其视为字符串拼接:获取平台提示词,附加客户的指令,也许再附加用户偏好,然后调用 LLM。模型会处理剩下的事情。

模型并不能处理好。它会默默地挑选一个赢家,而你直到有人投诉才会发现是哪一个。

四个委托方,零仲裁

一个典型的 B2B AI 产品至少有四个指令来源:

  1. 平台安全规则 —— 无论客户如何配置,AI 都绝不能做的事情(法律、合规、品牌)
  2. 客户(运营商)配置 —— 特定租户如何针对其用例调整 AI
  3. 用户偏好 —— 终端用户在客户授予的范围内的调整
  4. 单次请求上下文 —— 在调用时注入的动态指令(检索到的文档、工作流状态、功能标志)

每一层都是合理的。问题在于大多数系统对于发生冲突时的情况没有明确的政策。平台说“对于账单问题,始终建议联系支持人员”。客户说“直接回答账单问题,我们已经在我们的价格文档上训练了 AI”。这些是不兼容的。其中一个会胜出。哪一个?取决于模型在特定调用中恰好对哪个赋予了更高的权重。

这就是 OpenAI 的研究人员正式提出的指令层次结构问题 (instruction hierarchy problem):目前的 LLM 将所有文本视为具有同等权威,无论是由哪个委托方提供的。一条用户消息可以推翻系统提示词。通过 RAG 检索到的文档可以覆盖两者。这里没有内核模式 (kernel mode) 与用户模式 (user mode) 之分 —— 所有内容都在同一特权级别运行。

对于 B2B 产品来说,实际后果是客户配置实际上并没有被强制执行。它们只是建议。而平台安全规则实际上也无法得到保证。它们只是默认值,任何在较低层级中足够强势的指令都可以将其取代。

为什么“仅仅拼接”是错误的默认做法

多租户提示词定制的主流实现模式是拼接。平台构建一个基础提示词。客户上传他们的定制块。在请求时,系统按顺序组装它们,并将组合后的文本发送给模型。

这种方法有三种在生产环境中会复合产生的失效模式。

隐性优先级反转 (Silent priority inversion)。 当客户的指令与平台的指令冲突时,模型通常会遵循在上下文窗口中出现较晚或措辞更具体的指令。不会抛出错误。没有日志条目。平台所有者无法审计其客户群中究竟遵循了哪些指令。

通过共享提示词产生的跨客户污染。 通过单个系统提示词为多个客户提供服务的平台,距离跨租户边界泄露配置仅差一条混乱的指令。如果模型被平台告知要“乐于助人”,而被客户告知要“对 Acme Corp 员工的所有回复保密”,那么在足够聪明的用户查询下,其行为是未定义的。

平台更新带来的影响范围。 当平台团队修改基础提示词 —— 添加安全规则、更改语气或重命名功能 —— 他们无法轻易预测哪些客户配置会损坏。没有依赖图。没有将平台更改映射到客户层回归的测试套件。发现问题的唯一方法就是发布并等待。

这三种失效都有相同的根源:系统没有明确的指令权威模型。将文本附加到提示词并不等同于授予该文本权威。

构建明确的指令层次结构

解决办法是使权威明确化,并通过结构化方式强制执行,而不是寄希望于模型能猜对。

定义层级及其优先级。 将其写下来,写在代码里,而不是散文中。例如:

平台安全约束 → 始终执行,不可覆盖
客户运营商规则 → 在平台约束内执行
用户偏好 → 在运营商授予的范围内应用
单次请求上下文 → 最后应用,范围最窄
加载中…
References:Let's stay in touch and Follow me for more thoughts and updates