共享 LLM 基础设施中的“吵闹邻居”问题:AI 功能的租户模型
告警在凌晨 2:47 响起。面向客户的聊天助手正为一半的付费用户返回 429 错误。工程师们在仪表板中忙乱寻找,试图找到那天下午发布的 Bug。他们一无所获 —— 代码没问题。真正的罪魁祸首是另一个团队在当晚启动的批量摘要任务,它共享了同一个供应商 API 密钥,耗尽了该账户接下来四小时的每分钟 Token 预算。没有人拥有这个共享密钥,也没有人负责这个限制。
这就是“喧闹邻居”(noisy-neighbor)问题。与经典的 API 配额事故不同,它在 LLM 系统中表现出一种独特的残酷性。一个达到速率上限的 REST 端点会迅速失败并进行重试;而 LLM 的“每分钟 Token”(TPM)桶是根据请求内容非对称消耗的。因此,一个生成 8K Token 的功能可能会使一个进行低成本 200 Token 分类调用的功能陷入饥饿,而这一切在请求计数图表中甚至都不会显现。流量在你所测量的维度上并不“喧闹”。
大多数团队发现这一点的方式正如上文提到的团队:一个无关团队的任务与付费用户的会话发生冲突,而两者唯一的共同点只是环境变量中的一个字符串。
为什么 LLM 的速率限制有所不同
供应商的速率限制通常同时体现在两个维度:每分钟请求数(RPM)和每分钟 Token 数(TPM),Anthropic 甚至将 Token 进一步细分为输入和输出桶。这些桶采用的是令牌桶算法 —— 它们会持续填充,因此瞬时突发流量会被部分吸收,但持续的压力会迅速耗尽容量。一次 70B 级别的模型调用可以在单个请求中消耗数千个 Token,而智能体(agent)中的单个工具调用循环可以在几秒钟内消耗数万个 Token。
这种与传统容量规划的不匹配正是难点所在。在典型的 Web 服务中,你根据每秒请求数(RPS)进行扩缩容,且每个请求的成本大致固定。在 LLM 服务中,由于 Prompt 大小、输出长度、重试次数以及是否启用推理(reasoning)的不同,两个请求的实际成本可能相差 100 倍。如果用户恰好使用了具有长上下文的功能,那么 1% 的用户增长可能会转化为 30% 的 Token 消耗增长。
供应商端并没有原生概念来规定“此功能拥有账户 40% 的 TPM,其余功能平分剩余配额”。OpenAI 和 Anthropic 提供的都是账户级别或工作区级别的限制,而非功能级别的分配。如果你每个供应商只有一个 API 密钥,且其后挂载了三个功能,那么你实际上已经默许了流量最大的功能有权让其他两个功能陷入饥饿。
