跳到主要内容

9 篇博文 含有标签「rate-limiting」

查看所有标签

对话感知的速率限制:为什么逐请求限流会破坏多轮 AI

· 阅读需 11 分钟
Tian Pan
Software Engineer

你的 AI 功能在测试中运行完美。单轮问答,毫无问题。但在生产环境中,当真实用户进行一场 10 轮调试对话时,它却失败了——不是因为模型出了问题,而是因为你的速率限制器是为一个完全不同的世界设计的。

标准 API 速率限制是专为无状态 REST 调用设计的粗糙工具。每个请求被视为一个独立的、大致等量的消耗单元。对于 CRUD 端点而言,这种模型运行良好,因为每次调用确实具有可比性。但对于多轮对话,这种模型就行不通了——每一个后续轮次的成本都在递增,一次用户交互可能触发数十次内部模型调用,而会话中途被切断造成的损害,远比一次失败的单次查询严重得多。

智能体流量不等同于人类流量:为两类调用者设计 API

· 阅读需 13 分钟
Tian Pan
Software Engineer

你两年前发布的 API 是为单一类别的调用者设计的:浏览器或移动客户端背后的人,点击一次,然后等待响应。现在,大约一半的关键端点上,这个假设都是错误的。另一半流量是智能体(Agents)——你自己的、你客户的,或者是将你的端点作为工具使用的第三方集成——它们具有不同的运行逻辑。它们会产生爆发式流量。它们会无限重试。它们会并行处理。它们会逐字解析错误字符串。它们代表人类行事,而当出现问题时,人类无法即时提供意图说明。

今年出现在复盘报告(postmortems)中的大多数生产环境异常,都可以追溯到一个架构错误:将这两类调用者视为同一种类别。为人类步调设置的频率限制(Rate limits)会被智能体的并行扇出瞬间击穿。为人类可读而设计的错误消息,会被一个在 400 错误上无限重试的智能体解析错误。人类默认会满足的幂等性假设,在智能体从恢复的检查点重试相同的负载时会被打破。身份验证日志失去了区分“用户执行了此操作”与“用户的智能体代表用户执行了此操作”的能力。

解决方法不是更智能的 WAF 或更大的频率限制桶。而是一种深思熟虑的 API 设计,它定义了两类调用者,将它们的流量视为不同的形态,并记录委托链,以便在间接层级中保持可追溯性。

负载降级是为人类设计的,而 Agent 会放大你正在抵御的风暴

· 阅读需 13 分钟
Tian Pan
Software Engineer

对人类来说,503 意味着一个“稍后再试”的页面和一段咖啡休息时间。对 Agent 来说,503 只是在七次重试中的第一次尝试前那 250 毫秒的挫折,而且规划器(planner)已经开始询问 LLM 是否有其他工具可以绕过这个失效的依赖项。第一种行为为过载的服务提供了恢复空间。第二种行为则是过载服务的噩梦:数以千计的关联重试,每一次都比人类的操作更廉价、更快速,其中一半还会扩散(fan out)到下一个依赖项,因为规划器认为那是一个富有创意的变通方案。

负载脱落(Load shedding)—— 即通过丢弃低优先级任务来维持高优先级路径可用的准则 —— 是在流量发送主体主要是键盘前的人类,或者是具有手动调优重试策略且行为良好的服务的时代设计的。当 Agent 集群出现时,这两个假设都会瞬间崩塌。Agent 重试速度更快,能同时从更多地方发起重试,绕过故障重新规划,并把你返回的 503 视为负载均衡的暗示,而不是你本意中希望达成的协作式背压(back-pressure)信号。

本文将探讨为什么标准的负载脱落策略在面对 Agent 客户端时会失效,上游服务需要什么样的原语才能真正卸载 Agent 流量,以及 Agent 本身在工具层和规划层必须做些什么,才能不再成为别人事故报告中的恶意流量。

速率限制层级崩溃:当你的智能体循环产生自我 DoS 时

· 阅读需 14 分钟
Tian Pan
Software Engineer

错误报告显示服务很慢。仪表板显示服务很健康。每分钟 Token 使用量处于层级上限的 62%,稳稳处于绿色安全范围内。然后你打开追踪(traces)查看形态:一个用户请求生成了一个规划步骤,该步骤发出了 11 个并行工具调用,其中 4 个是搜索扇出,每个都触发了子智能体,而这些子智能体又分别并行调用了 3 个工具——那个单一的“请求”现在正同时从 47 个不同的工作线程猛击你自己的 Token 桶。产品的其他 99 名用户被堵在它后面,收到了他们本不该得到的 429 错误。你的智能体正在对自己发起 DoS 攻击,而速率限制器(rate limiter)正在忠实执行你给它的指令。

这就是速率限制层级崩塌。你购买了为 HTTP API 设计的边界防御系统,在那样的系统中,一个请求等于一个工作单元;然后你把它连接到一个请求意味着深度未知且分支因子无界的树形系统前端。单一桶模型不仅无法提供保护,而且它的失败是隐形的,因为你的聚合数据从未突破任何限制。损害发生在尾部、相关的爆发中,以及那些恰好在时间上紧邻重度请求的专注用户身上。

LLM 速率限制是一个分布式系统问题

· 阅读需 14 分钟
Tian Pan
Software Engineer

你的 AI 产品有两个功能面:一个面向用户的聊天功能和一个后台报告生成任务。两者在同一个 Key 下调用同一个 LLM API。一个下午,你收到了一张工单:“聊天回复在中途被截断了。”没有触发任何警报。日志中也没有 429 错误。API 在整个过程中一直返回 HTTP 200。

发生了什么:报告生成任务逐渐消耗了你大部分的共享 Token 配额。聊天请求虽然能完成,但仅达到了你的 max_tokens 限制——在语义上被截断,在语法上有效,却在无声无息中出错了。你的标准监控从未察觉到这一点,因为在 HTTP 层面上没有任何异常。

这并不是一种边缘情况。当工程师将 LLM 速率限制视为简单的节流问题,而不是意识到它们实际上属于分布式系统失效类别时,就会发生这种情况。

多租户 LLM 问题:规模化部署中的嘈杂邻居、隔离与公平性

· 阅读需 13 分钟
Tian Pan
Software Engineer

你的 SaaS 产品以十个设计客户的规模上线,一切运转完美。随后你陆续接入了一百个租户,其中一个——一位在复杂研究工作流中使用 20 万 token 上下文窗口的重度用户——导致了所有其他客户的延迟飙升。支持工单开始涌来。你查看监控面板,却看不到任何明显异常:模型健康,API 返回 200,p50 延迟看起来正常。而你的 p95 已经悄悄翻了三倍。

这就是嘈杂邻居问题,它对 LLM 基础设施的冲击比几乎任何其他共享系统都要剧烈。以下是它为何比数据库场景更难解决——以及真正有效的应对方案。

LLM 流水线中的背压:排队论在基于 Token 的服务中的应用

· 阅读需 13 分钟
Tian Pan
Software Engineer

凌晨 3 点的重试风暴通常以同样的方式开始:提供商的一次短暂抖动导致少数请求超过了速率限制,你的客户端库对此进行了重试,而这些重试落在了尚未恢复的端点上,导致更多请求失败;在 90 秒内,你的队列深度迅速飙升,而你的提供商仪表板显示你已经用满了 100% 的每分钟 Token 配额(TPM),由此产生的积压工作甚至可以用五位数的美元来衡量。事后分析会将其归结为“惊群效应(thundering herd)”。但诚实的回答是,你在一个容量多变的下游服务之上构建了一个固定吞吐量的重试策略,却忘记了排队论对此早有定论。

大多数知名的服务韧性模式是为那些吞吐量像一堵墙一样固定的下游服务设计的:例如带有连接池的数据库,或者具有已知并发限制的微服务。但 LLM 提供商并非如此。你的有效吞吐量是一个动态目标,受到你的服务层级、所选模型、Prompt 大小、响应大小、一天中的时间,以及同一提供商的其他用户是否正在微调前沿模型的影响。将它视为一根固定的管道,是我今年看到的多数 LLM 故障的根本原因。

共享 LLM 基础设施中的“吵闹邻居”问题:AI 功能的租户模型

· 阅读需 13 分钟
Tian Pan
Software Engineer

告警在凌晨 2:47 响起。面向客户的聊天助手正为一半的付费用户返回 429 错误。工程师们在仪表板中忙乱寻找,试图找到那天下午发布的 Bug。他们一无所获 —— 代码没问题。真正的罪魁祸首是另一个团队在当晚启动的批量摘要任务,它共享了同一个供应商 API 密钥,耗尽了该账户接下来四小时的每分钟 Token 预算。没有人拥有这个共享密钥,也没有人负责这个限制。

这就是“喧闹邻居”(noisy-neighbor)问题。与经典的 API 配额事故不同,它在 LLM 系统中表现出一种独特的残酷性。一个达到速率上限的 REST 端点会迅速失败并进行重试;而 LLM 的“每分钟 Token”(TPM)桶是根据请求内容非对称消耗的。因此,一个生成 8K Token 的功能可能会使一个进行低成本 200 Token 分类调用的功能陷入饥饿,而这一切在请求计数图表中甚至都不会显现。流量在你所测量的维度上并不“喧闹”。

大多数团队发现这一点的方式正如上文提到的团队:一个无关团队的任务与付费用户的会话发生冲突,而两者唯一的共同点只是环境变量中的一个字符串。

LLM 流水线的背压模式:为何指数退避还不够

· 阅读需 11 分钟
Tian Pan
Software Engineer

在峰值流量期间,部分 LLM 提供商的失败率超过 20%。当系统撞上这堵墙,并通过加倍等待时间和重试来应对时,你解决的是一个错误的问题。指数退避处理的是单次调用的韧性,对整个系统毫无作用——无法减少浪费的 token,无法解决连接池耗尽,也无法照顾到排在刚收到 429 响应那个请求后面的 50 个请求。

冲击 LLM API 的流量模式也发生了根本性变化。2023 年到 2025 年间,100 token 以下的简单查询从占流量的 80% 骤降至约 20%,而超过 500 token 的请求则成为持续的多数。Agentic 工作流在短时间内串联 10-20 个顺序调用,产生的流量模式在传统的每分钟请求数(RPM)限速下,与 DDoS 攻击别无二致。为负载可预测的 REST API 构建的基础设施,并不是 LLM 流水线所需要的基础设施。