限额与速率限制
BigModel.io 的并发、每分钟请求数、Key 额度、5 小时 / 1 天 / 7 天消费窗口和套餐限额,各自返回的 429 错误,以及如何退避重试。
BigModel.io 有几种相互独立的限制。每种都会返回 HTTP 429(账户消费上限为 402,余额不足为 403),错误信息会指明是哪一种,重试前先看错误码。
| 限制 | 作用范围 | 由谁设置 | 错误 | Retry-After |
|---|---|---|---|---|
| 并发 | 用户 | BigModel.io(按账户) | 429 rate_limit_error“Concurrency limit exceeded for user”或“Too many pending requests” |
无 |
| 每分钟请求数(RPM) | 分组和用户 | BigModel.io(按分组 / 账户) | 429 rate_limit_exceeded |
有 |
| Key 额度 | Key | 你自己 | 429 API_KEY_QUOTA_EXHAUSTED |
无 |
| 消费窗口 5h / 1d / 7d | Key | 你自己 | 429 rate_limit_exceeded“api key 5小时限额已用完”(或日 / 7天) |
无 |
| 套餐限额(日 / 周 / 月) | 套餐 | 套餐定义 | 429 USAGE_LIMIT_EXCEEDED |
无 |
| 账户消费上限(周 / 月) | 账户 | 你自己 | 402 spend_cap_reached |
有,指向重置时间 |
| 余额为 0 时的免费模型调用 | 用户 | BigModel.io | 429 rate_limit_exceeded |
有 |
| 余额 | 账户 | 你的充值 | 403 INSUFFICIENT_BALANCE |
无 |
| 上游供应商限制 | 模型供应商 | 供应商 | 429 rate_limit_error |
供应商返回时透传 |
没有按 Key 设置的 RPM 或并发;RPM 和并发作用于你的账户和 Key 所在分组。
#并发
每个用户同时进行中的请求数有上限,按账户设置。所有并发位都被占用时,后续请求会短暂进入等待队列:
- 队列已满时,请求立即被拒绝:429“Too many pending requests, please retry later”。
- 排队请求等待并发位超时时,返回 429“Concurrency limit exceeded for user, please retry later”。
流式请求在流结束前一直占用并发位,所以长时间的 Agent 会话会更久地占用并发。如果要并行发出大量请求,请在客户端限制并行数,并对这类 429 退避重试。
#每分钟请求数
分组和用户都可以有 RPM 上限,由 BigModel.io 按分组和账户设置。超过后返回 429 rate_limit_exceeded,并带 Retry-After 响应头,值为当前这一分钟剩余的秒数。等待相应时间后重试即可。
余额为 0 时,调用标价 $0 的模型另有每分钟次数限制,返回方式相同。充值后限制解除。见 试用额度与免费模型。
#账户消费上限
在 余额与账单 中可以设置每周和每月的余额消费上限(美元)。每周从周一 00:00(UTC)开始,每月从 1 日 00:00(UTC)开始。达到上限后,请求返回 402 spend_cap_reached,Retry-After 为距离重置的秒数。标价 $0 的模型仍可使用。不要循环重试 402:等待重置,或调整上限。
#Key 额度与消费窗口
这两项由你在 API Keys 中按 Key 设置:
- 额度限制 Key 的美元总消费(0 表示不限)。用完后返回 429
API_KEY_QUOTA_EXHAUSTED,可以提高额度或重置已用金额。 - 消费窗口限制每 5 小时、1 天和 7 天的美元消费(0 表示不限)。
窗口是固定窗口,不是滚动窗口:从 Key 首次使用时开始计时,时长到期后重置。这类 429 不带 Retry-After,请查看 reset_at:
curl https://bigmodel.io/v1/usage \
-H "Authorization: Bearer $BIGMODEL_API_KEY"{
"mode": "quota_limited",
"rate_limits": [
{ "window": "5h", "limit": 5, "used": 5, "remaining": 0, "window_start": "...", "reset_at": "..." }
]
}即使 Key 额度用尽或已过期,GET /v1/usage 也能调用。见 按 Key 限额与预算。
#套餐限额
套餐分组的 Key 受套餐每日、每周和每月美元限额约束。任一限额用完后,请求返回 429 USAGE_LIMIT_EXCEEDED,直到该周期重置。GET /v1/usage 的 subscription 字段会显示套餐用量和限额。
#速率相关响应头
网关自身不添加 x-ratelimit-* 响应头。如果模型供应商返回了 x-ratelimit-* 或 retry-after,会原样透传。上面的 RPM 限制会由网关自己设置 Retry-After。
#退避重试
对 429 速率限制和 5xx 错误进行重试;不要重试 400、401、402、403 以及额度 / 窗口 / 套餐类错误,在情况改变前它们会一直失败。有 Retry-After 时按它等待,否则使用带随机抖动的指数退避。
import os, random, time
import requests
URL = "https://bigmodel.io/v1/chat/completions"
HEADERS = {"Authorization": f"Bearer {os.environ['BIGMODEL_API_KEY']}"}
NO_RETRY = {"API_KEY_QUOTA_EXHAUSTED", "USAGE_LIMIT_EXCEEDED", "INSUFFICIENT_BALANCE"}
def chat(body, max_attempts=5):
for attempt in range(max_attempts):
r = requests.post(URL, headers=HEADERS, json=body, timeout=600)
if r.status_code < 400:
return r.json()
err = r.json() if r.headers.get("content-type", "").startswith("application/json") else {}
code = err.get("code") or (err.get("error") or {}).get("type")
message = (err.get("message") or (err.get("error") or {}).get("message") or "")
retryable = r.status_code >= 500 or (
r.status_code == 429 and code not in NO_RETRY and "限额" not in message
)
if not retryable or attempt == max_attempts - 1:
raise RuntimeError(f"{r.status_code} {code}: {message} (request {r.headers.get('X-Request-ID')})")
wait = float(r.headers.get("Retry-After") or min(30, 2 ** attempt))
time.sleep(wait + random.random())
print(chat({"model": "glm-5.3", "messages": [{"role": "user", "content": "Hello!"}]}))const URL = "https://bigmodel.io/v1/chat/completions";
const NO_RETRY = new Set(["API_KEY_QUOTA_EXHAUSTED", "USAGE_LIMIT_EXCEEDED", "INSUFFICIENT_BALANCE"]);
async function chat(body, maxAttempts = 5) {
for (let attempt = 0; attempt < maxAttempts; attempt++) {
const r = await fetch(URL, {
method: "POST",
headers: { Authorization: `Bearer ${process.env.BIGMODEL_API_KEY}`, "Content-Type": "application/json" },
body: JSON.stringify(body),
});
if (r.ok) return r.json();
const err = await r.json().catch(() => ({}));
const code = err.code ?? err.error?.type;
const message = err.message ?? err.error?.message ?? "";
const retryable = r.status >= 500 || (r.status === 429 && !NO_RETRY.has(code) && !message.includes("限额"));
if (!retryable || attempt === maxAttempts - 1) {
throw new Error(`${r.status} ${code}: ${message} (request ${r.headers.get("x-request-id")})`);
}
const wait = Number(r.headers.get("retry-after")) || Math.min(30, 2 ** attempt);
await new Promise((res) => setTimeout(res, (wait + Math.random()) * 1000));
}
}
console.log(await chat({ model: "glm-5.3", messages: [{ role: "user", content: "Hello!" }] }));OpenAI 和 Anthropic 官方 SDK 已经会对 429 和 5xx 自动退避重试(max_retries / maxRetries,默认 2 次)。批量任务可以调大这个值,不必再在 SDK 外面套一层重试。并行请求数保持在并发上限以内,可以避免排队。
#常见问题排查
429“Too many pending requests”。 并行请求远多于并发上限。在客户端限制并行数(工作池或信号量)。
429“Concurrency limit exceeded for user”。 请求排队太久。减少并行请求,或缩短长时间的流式请求。需要更高上限请联系 支持。
带 Retry-After 的 429 rate_limit_exceeded。 触发 RPM 限制,按给出的秒数等待。
429 rate_limit_exceeded“api key 5小时限额已用完”。 触发 Key 消费窗口。等到 reset_at,或在 API Keys 中提高窗口上限、重置用量。
没有其他说明的 429 rate_limit_error。 通常是模型供应商自身的限制。退避重试,或用 models 备选数组切换到其他模型。
#相关文档
更新于 · 以 Markdown 查看