跳转到内容

限流

限流是为了让共享资源保持可用,所以几乎都作用在 Token Factory 上。下面四组限制各自独立生效。

每个请求要依次通过两层检查:平台先决定是否放行,网关再按账号计量。

限制范围典型值
每分钟请求数每个 API Key30
每分钟请求数每个 IP 地址120,仅在部署的边缘节点能提供可信的客户端地址时生效
并发请求数每个 API Key8
并发请求数每个模型取决于该模型后端能承受的并发
并发请求数每个服务进程共享池
并发请求数全平台共享池
限制范围典型值
每分钟请求数每个账号20,60 秒滑动窗口
每日用量上限每个账号以 Token Factory 的 pts 计量,按北京时间的自然日累计,每天 00:00(UTC+8)重置

聊天、语音合成(/v1/audio/speech)和决策(/v1/systemone)请求共用同一个每分钟窗口和同一个每日用量上限。

列出模型不占用并发名额,但计入每分钟限制。

返回 429 和 Retry-After 响应头。响应体的格式取决于是哪一层拒绝了请求。

平台准入 返回 OpenAI 格式的错误,放在 detail 里:

{
"detail": {
"error": {
"message": "Model API rate limit exceeded; please retry later",
"type": "rate_limit_error",
"code": "token_rate_limit_exceeded"
}
}
}

code 表示触发的是哪一项限制:

代码含义
token_rate_limit_exceeded这个 API Key 每分钟的请求太多。
ip_rate_limit_exceeded这个 IP 每分钟的请求太多。
token_concurrency_rate_limit_exceeded这个 API Key 同时进行的请求太多。
model_concurrency_rate_limit_exceeded这个模型达到了自身的并发上限,其他模型可能还有余量。
process_concurrency_rate_limit_exceeded服务进程已满载。
global_concurrency_rate_limit_exceeded整个平台已满载。

每分钟限制返回 Retry-After: 60。并发限制返回 Retry-After: 1,你正在进行的请求一结束就会解除。

网关计量 在顶层返回 OpenAI 格式的错误,code 统一是 rate_limit_exceeded,Retry-After 按窗口计算:

{
"error": {
"message": "Rate limit exceeded: maximum 20 requests per minute for this OneClick user. Please try again later.",
"type": "rate_limit_error",
"param": null,
"code": "rate_limit_exceeded"
}
}

每日用量上限用完时,返回同样格式的错误,信息是 Daily usage limit exceeded: maximum $N per period for this OneClick user.,Retry-After 是本周期剩余的秒数。

在 /v1/messages 上,网关使用 Anthropic 的格式:{"type": "error", "error": {"type": "rate_limit_error", "message": "..."}}。

以上限制都不适用。实例上的模型服务前面没有网关:代理只核对 API Key 和实例是否匹配,然后转发。请求路径上没有每分钟限制、并发配额或每日用量上限。

上限来自实例本身:vLLM 的请求队列、--max-num-seqs 等参数,以及你启动的 GPU。超出后请求会排队,而不是返回 429。实例运行期间一直消耗积分,不管有没有请求。

从模板启动实例时,按 IP 地址在 1 分钟、10 分钟和 1 小时三个滑动窗口内限流。这是为了拦住重试循环,正常使用不会碰到。

超出后返回 429 和 Retry-After。另外,每个账号同一时间只能有一个实例,销毁前一个之前,再次启动会被拒绝。

登录尝试和新账号注册按 IP 限流,只影响在控制台里的操作,不影响 API 调用。

按 Retry-After 等待,不要自己设定间隔,并在此基础上加入带随机抖动的指数退避。如果大量客户端都在 60 秒整重试,只会再次造成触发限流的流量高峰。

在客户端把并发控制在每个 API Key 的并发配额以内,而不是一次发出大量请求再处理 429。用一个容量为 8 的信号量,比重试循环更简单,也更快。

除了 429,不要重试其他 4xx 错误。400 或 401 重试多少次结果都一样。

import time, random, requests
def call_with_retry(payload, attempts=5):
for i in range(attempts):
r = requests.post(URL, headers=H, json=payload, timeout=600)
if r.status_code != 429:
r.raise_for_status()
return r.json()
wait = float(r.headers.get("Retry-After", 60))
time.sleep(wait + random.uniform(0, 2) * (2 ** i))
raise RuntimeError("rate limited after retries")

如果长期需要比 Token Factory 额度更多的用量,请在自己的实例上部署模型服务,那里的唯一限制是你的实例能处理多少请求。