LLM API 账号限流容量估算:从 RPM/TPM 配额到业务容量

LLM API 账号限流容量估算:从 RPM/TPM 配额到业务容量

导读:本文解决"服务商只给 RPM/TPM 限流配额,业务却想知道能支撑多少用户与对话"的容量估算问题。核心方法是先用观测数据统计每轮对话的平均调用次数与 token 消耗,再按"容量 = min(RPM/每轮调用数, TPM/每轮token)"两个维度各除一次、取较小者;关键结论是长 prompt 场景下 token 维度几乎总是先撞墙(示意示例中 token 上限约 250 轮/分 vs 请求上限 2,500 轮/分),只看 RPM 会严重高估容量、上线后提早吃到 429。适合所有接入第三方 LLM API、需要做配额容量规划或排查 429 的后端与应用工程师。

分类:性能测试 | 标签:LLM、API限流、容量估算、性能测试

一、背景:为什么 API 账号会有限流

接入第三方 LLM API 时,服务商不会让一个账号无限调用:推理集群是共享的,必须防止单个账号把算力打爆、影响其他租户。于是每个账号都带一组限流配额,超出后直接返回 429(Too Many Requests),业务侧只能等待重试或眼睁睁看着请求失败。

常见的问题是:服务商只告诉你"这个账号每分钟多少请求、多少 token",但业务方真正关心的是"能支撑多少用户、多少对话、多少并发"。把配额翻译成业务容量,是上线前必做的一道估算题。本文记录一套可复用的估算方法:从配额的两个维度出发,用观测数据把"每分钟请求数/每分钟 token 数"换算成"每分钟能完成的对话轮数",并给出一个完整的计算示例(示例数据均为示意)。

二、配额的两个维度:RPM 与 TPM

LLM API 的账号配额通常有两个相互独立的维度:

  • RPM(Requests Per Minute,每分钟请求数):账号每分钟最多发起的 API 调用次数。一次调用对应一次 HTTP 请求,无论 prompt 长短都只占一次额度。
  • TPM(Tokens Per Minute,每分钟 token 数):账号每分钟消耗的总 token 量,等于所有调用(prompt 输入 token + completion 输出 token)之和。

两个维度独立限流,哪个先撞墙,哪个就是真实瓶颈。只盯其中一个维度,很容易得出过于乐观的结论。

这里还隐含了两层"放大",是估算时最容易漏掉的:

  1. 一次对话 ≠ 一次 API 调用。Agent 场景下,一次对话往往包含多轮工具调用、多次生成(先规划、再调工具、再总结),常见 2~4 次调用;
  2. 一次调用 ≠ 少量 token。prompt 里塞入的上下文越多、回答越长,单次消耗的 token 越大;RAG 场景下 prompt 尤其膨胀。

把这两层放大算清楚,配额才能正确换算成业务容量。

三、容量估算公式与示例

3.1 公式

设账号配额为 RPM(次/分)与 TPM(token/分),从观测数据得到每轮对话平均调用次数 C 与每轮平均 token 数 T(prompt + completion 全链路合计):

容量_请求 = RPM / C           // 按请求数维度,单位:轮/分
容量_Token = TPM / T          // 按 Token 维度,单位:轮/分
实际容量 = min(容量_请求, 容量_Token)

3.2 计算示例(数据为示意)

假设某业务通过 Agent 完成日常咨询,模型服务商账号配额如下:

维度 配额(示意值)
账号限流(请求) 10,000 次/分
账号限流(Token) 8,000,000 token/分

第一步,由业务量反推峰值吞吐。 假设该业务日均对话 2 万轮,集中在白天 8 小时(约 480 分钟),高峰时段按均值 2.5 倍估算:

  • 平均吞吐 = 20000 / 480 ≈ 42 轮/分
  • 峰值吞吐 ≈ 42 × 2.5 ≈ 105 轮/分

第二步,估算每轮对话的实际用量。 参考观测平台近 7 日抽样(见 3.3 与第五节):Agent 单轮对话平均约 4 次调用;每次调用 prompt 平均约 5,000 token、completion 平均约 3,000 token,合计每轮约 4 × 8,000 ≈ 32,000 token(示意值)。长上下文场景(RAG 注入大量检索片段)单轮会明显高于这个数。

第三步,代入公式:

  • 按请求数:10,000 / 4 = 2,500 轮/分
  • 按 token:8,000,000 / 32,000 = 250 轮/分
  • 取较小者:≈ 250 轮/分

结论:峰值需求约 105 轮/分,配额理论上撑得住——但真正卡住业务的是 token 维度(250 轮/分),请求维度(2,500 轮/分)绰绰有余。如果只按 RPM 把容量估成 2,500 轮/分,上线后会在 250 轮/分附近就开始吃到 429。

3.3 不同口径下的容量对照

同一配额,采用不同的每轮用量假设,结论差异很大(示意值):

场景 调用/轮 Token/轮 请求上限(轮/分) Token 上限(轮/分) 实际容量
中位日常 2 2.3 万 5,000 348 ≈348 轮/分
4 次调用 + 3 万 token 4 3.0 万 2,500 267 ≈267 轮/分
4 次调用 + 压测口径 4 3.35 万 2,500 239 ≈239 轮/分
近期均值(含长对话) 3.4 6.1 万 2,941 131 ≈131 轮/分

单看中位日常能承约 350 轮/分,含长对话的均值口径只剩约 130 轮/分——用哪个口径做规划,直接决定上线后的表现。稳妥做法是用均值口径(偏保守)留余量,而不是拿状态最好的中位口径当承诺值。

另外要区分两个概念:上表算的是峰值吞吐(轮次/分钟),不是同时在线人头数。如果"人"指挂着会话、隔几分钟才问一句的在线用户,可承载人数会比轮次上限高得多——不要用吞吐上限去反推"最多能开多少会话"。

四、Token 先撞墙的坑

这是整篇最值得记住的洞察:长 prompt 场景下,token 配额几乎总是先被打满。

原因很直白:一次调用无论多少 token 都只占 1 次 RPM,但 token 消耗与 prompt 长度线性相关。当业务形态是"长 prompt"时——比如 RAG 把检索到的整段文档塞进上下文、多轮对话把历史消息全部带上、大文件摘要一次性读入——单次调用的 token 迅速膨胀,TPM 在请求量远未到上限时就触顶了。

经验教训:

  • 排查限流时,第一反应不该是"请求量超了",而是看 429 响应里给出的 quota 类型:如果是 token 超限,说明问题在 prompt 太长或输出太多,而不是请求太频繁;
  • 问题判定不同,优化方向完全不同:token 触顶走"精简 prompt、控制上下文窗口、限制输出长度",而不是简单地降 QPS;
  • 请求配额看着很宽裕时尤其要警惕——宽裕的 RPM 恰恰说明瓶颈大概率在 TPM 一侧。

五、扩容量怎么做

算清瓶颈后,扩容思路按成本从低到高排列:

1. 优化单轮用量(最便宜)

  • 精简 prompt:裁剪无关上下文、按需注入 RAG 片段,而不是整段全文塞入;
  • 控制历史轮数:多轮对话只携带必要的历史摘要;
  • 约束输出:设置合理的 max_tokens,避免生成过长文本。
  • 收益直接体现在 TPM 上,很多时候比加账号更划算。

2. 用真实数据校准,而不是拍脑袋

  • 基于观测平台(如 Langfuse 这类开源的 LLM 可观测工具)抽样近 7 日数据,统计每轮对话的调用次数分布与 token 分布——中位与均值要分开看,长对话会把均值拉得很高;
  • 用"全量汇总 ÷ 调用链总数"得到整体加权均值,最接近真实负荷;
  • 切换模型档位后一定要复测:观测数据可能来自经济档模型,旗舰档模型的单次用量往往明显不同,要把公式里的 C、T 换成新模型的实测值重算一遍再定规划。

3. 由调用量换算自建算力投入

把配额换算出的容量再折回业务量,还能顺带估算自建推理服务的算力量级:例如近 7 日全量约消耗 2.9 亿 token(示意值),折合日均约 4,000 万 token,峰值小时还要再留 2~3 倍余量——这个数字就是自建服务要准备的显存与吞吐预算,也是评估"租 API 还是自建"的输入之一。

4. 多账号扩容

单账号打满后,可以申请多个账号分摊流量:

  • 账号轮询:网关层做轮询(round-robin)路由,把请求均匀分布到多个账号,避免所有流量集中在同一账号、同一分钟打满配额;
  • 配额分配:按业务/按模块划分账号,把重上下文业务与轻对话业务隔离,防止一个长 prompt 业务把一个共享账号的 token 额度吃光;
  • 兜底重试:无论怎么分,429 仍会出现,调用层要做带退避的重试与熔断,避免重试风暴把配额放大打穿;
  • 权衡:多账号带来管理与成本翻倍,且仍受服务商整体风控约束——优先做前两条,把账号数量当作最后手段。

5. 留余量上线并持续迭代

容量规划永远别贴着上限排:按均值/长对话口径的 120~180 并发轮次/分钟区间来规划(示意值),把突发流量和重试放大都算进去;上线后持续看观测平台的 429 率与 token 曲线,用实测值替换估算公式里的参数,滚动校准。

一句话总结:配额给的是 RPM 和 TPM 两个数字,业务要的是"每分钟能干几轮活"。用观测数据把"每轮几次调用、每轮多少 token"算出来,两个维度各除一次、取较小者,得到的就是真实容量——而在长 prompt 场景下,答案几乎总是被 TPM 卡着。