跳至主要內容

速率限制

每把金鑰的 RPM / TPM 與並發限制、429 回應標頭,以及退避與排隊策略。

速率限制

速率限制以單把 API 金鑰為單位計算,用來保護共用容量並避免異常流量。

預設限制

限制預設值說明
每分鐘請求數(RPM)600滑動視窗計算。
每分鐘 token 數(TPM)2,000,000以 input + output token 總和計。
並發請求數60同時進行中的請求(串流從開始到結束皆計入)。

實際上限依帳戶等級而異,可在 Dashboard 的 API Keys 頁面查看。需要更高額度請與我們聯絡並說明流量樣態。

GET /v1/models 有獨立且較寬鬆的限制,可以安全地當成健康檢查。

回應標頭

每個回應都會帶回目前的配額狀態:

X-RateLimit-Limit-Requests: 600
X-RateLimit-Remaining-Requests: 583
X-RateLimit-Reset-Requests: 42
X-RateLimit-Limit-Tokens: 2000000
X-RateLimit-Remaining-Tokens: 1904220
X-RateLimit-Reset-Tokens: 42

*-Reset-* 為距離視窗重置的秒數。

超過限制時

HTTP/1.1 429 Too Many Requests
Retry-After: 12
Content-Type: application/json

{
  "error": {
    "code": "rate_limited",
    "message": "Rate limit exceeded for this API key. Retry in 12 seconds."
  }
}

Retry-After 是建議的等待秒數。有這個標頭時請優先採用它,而不是自己算的退避時間。

退避重試(Python)

import os
import random
import time

from openai import OpenAI, APIStatusError

client = OpenAI(
    base_url="https://api.alphacurve.io/v1",
    api_key=os.environ["INFERENCE_API_KEY"],
)

def complete_with_backoff(**kwargs):
    for attempt in range(6):
        try:
            return client.chat.completions.create(**kwargs)
        except APIStatusError as err:
            if err.status_code != 429:
                raise
            retry_after = err.response.headers.get("Retry-After")
            delay = float(retry_after) if retry_after else min(2 ** attempt, 30)
            time.sleep(delay + random.uniform(0, 0.5))  # 加抖動避免同步重試
    raise RuntimeError("rate limited: retries exhausted")

限制並發(Node / TypeScript)

與其被動吃 429,不如主動限制同時發出的請求數:

import OpenAI from "openai";

const client = new OpenAI({
  baseURL: "https://api.alphacurve.io/v1",
  apiKey: process.env.INFERENCE_API_KEY!,
  maxRetries: 5, // SDK 內建對 429 / 5xx 的重試
});

async function mapWithConcurrency<T, R>(
  items: T[],
  limit: number,
  fn: (item: T) => Promise<R>,
): Promise<R[]> {
  const results: R[] = new Array(items.length);
  let cursor = 0;

  const workers = Array.from({ length: limit }, async () => {
    while (cursor < items.length) {
      const index = cursor++;
      results[index] = await fn(items[index]);
    }
  });

  await Promise.all(workers);
  return results;
}

const answers = await mapWithConcurrency(prompts, 16, async (prompt) => {
  const resp = await client.chat.completions.create({
    model: "openai/gpt-4o-mini",
    messages: [{ role: "user", content: prompt }],
  });
  return resp.choices[0].message.content;
});

實務建議

  • 一律加上抖動。 沒有抖動的固定退避會讓所有 client 同時重試,反而更容易被限流。
  • 批次工作獨立用一把金鑰。 大量離線任務和線上流量分開,避免批次把互動式請求擠掉。
  • 監控 X-RateLimit-Remaining-*。 在接近上限時主動放慢,比撞牆後再退避更平順。
  • 善用串流。 串流不會提高吞吐量,但能大幅降低使用者感受到的延遲。
  • 速率限制與花費上限是兩回事。 429 是流量問題,402 是餘額或上限問題,兩者互不影響。