Bloga dön

Sorun gidermeKılavuz

Bir AI API'sinden 429 Too Many Requests: geri çekilmeli yeniden denemeler

Bir AI API'sinden gelen 429'un ne anlama geldiği ve nasıl ele alınacağı: jitter'lı üstel geri çekilme, Retry-After ve ajan eşzamanlılığı, Python ve JavaScript koduyla.

Yazan: CheapTokens TeamYayınlanma tarihi: Güncellenme tarihi: 5 dk okuma

Bir istek döngüsünün diyagramı: bir 429 yanıtı, artan gecikmeli bir bekleme adımı ve bir yeniden deneme
Bu sayfada
  1. 429 ne anlama gelir
  2. Bir gecikme tahmin etmeden önce başlıkları okuyun
  3. Python: jitter'lı geri çekilme
  4. JavaScript: aynı döngü
  5. Ajanlar 429'u nasıl ele almalı
  6. Ajan döngülerini CheapTokens üzerinde çalıştırın
  7. Hâlâ başarısız olursa

Bir AI API'sinden gelen 429 Too Many Requests, çok fazla isteği çok hızlı gönderdiğiniz veya hesabınızdaki bir limite takıldığınız için isteğin reddedildiği anlamına gelir. Çözüm, üstel geri çekilme ve jitter ile bekleyip yeniden denemek, yanıtta varsa Retry-After başlığını kullanmak ve ajanınızın paralel gönderdiği istek sayısını sınırlamaktır. Gerçekte bir harcama veya bakiye limiti olan bir 429'u yeniden denemeyin: beklemek bunu düzeltmez.

Bu kılavuz, OpenAI ve Anthropic resmi hız limiti kılavuzlarına dayanır; her ikisi de 22 Ekim 2026'da kontrol edilmiştir. Hiçbir sayfa son güncelleme tarihi göstermiyor.

429 ne anlama gelir#

OpenAI, 429'u bir hız limitinin aşılması nedeniyle reddedilen istek (trafik çok hızlı arttığında slow_down koduyla birlikte rate_limit_error) veya katı bir harcama limitine ulaşılması olarak tanımlar. Anthropic de 429 için rate_limit_error kullanır. Harcama limiti kaynaklı bir 429'da retry-after başlığı yoktur ve erişim yeniden sağlanana kadar başarısız olmaya devam eder.

İki komşu durum bununla kolayca karıştırılabilir. OpenAI'nin 503 server_is_overloaded ve Anthropic'in 529 overloaded_error yanıtları aşırı yüklenme durumlarıdır, sizin hız limitiniz değildir. Genellikle aynı yeniden deneme döngüsüyle ele alınırlar, ancak neden hakkında farklı bir şey söylerler.

Yani üç durum var ve her biri farklı bir tepki gerektirir:

Yanıt Neden Ne yapmalı
429 hız limiti Dakikada çok fazla istek veya token Bekleyin, geri çekilmeyle yeniden deneyin
429 harcama veya bakiye limiti Hesap limitine ulaşıldı Yeniden denemeyin; limiti düzeltin veya bakiye yükleyin
503 / 529 aşırı yüklenme Sağlayıcı tarafı meşgul Sınırlı şekilde geri çekilmeyle yeniden deneyin

Bakiyeniz tükendiyse bunun yerine "yeterli token yok" hatasını okuyun. Zaman aşımları ve reddedilen bağlantılar gibi ağ düzeyindeki hatalar için yaygın bağlantı hatalarına bakın.

Bir gecikme tahmin etmeden önce başlıkları okuyun#

OpenAI, hız limitli yanıtlarda şu başlıkları belgeler: Retry-After ve x-ratelimit-limit-requests, x-ratelimit-remaining-requests, x-ratelimit-reset-requests ile -tokens varyantları. Diğer API'ler bunların bir alt kümesini veya hiçbirini gönderebilir, bu yüzden istemciyi Retry-After mevcut olduğunda onu kullanacak, olmadığında kendi programınıza geri dönecek şekilde yazın.

OpenAI'nin yeniden denemeler konusundaki rehberliği kısaca:

  • Retry-After değerini minimum bekleme olarak kabul edin ve üzerine küçük bir rastgele gecikme ekleyin.
  • O yoksa jitter'lı üstel geri çekilme kullanın.
  • Hem deneme sayısını hem de toplam yeniden deneme süresini sınırlayın.
  • Kendi yeniden denemelerinizi SDK'nın yeniden denemelerinin üzerine yığmayın.
  • Kota veya faturalama hatalarını yeniden denemeyin.
  • Başarısız istekler de dakikalık limite sayılır, bu yüzden agresif bir döngü durumu daha da kötüleştirir.
  • Akış (streaming) için, çıktısını zaten tükettiğiniz bir isteği yeniden oynatmayın.

Python: jitter'lı geri çekilme#

Resmi openai paketi herhangi bir OpenAI uyumlu uç noktayla çalışır. SDK'nın kendi yeniden denemelerini kapatın (max_retries=0) ki sizinkilerle çoğalmasınlar. Modelin kimliği CheapTokens dokümanlarından gelir; kimlikler sağlayıcılar arasında farklıdır.

python
import os
import random
import time

from openai import OpenAI, APIStatusError

client = OpenAI(
    base_url="https://api.cheaptokens.dev/v1",
    api_key=os.environ["CHEAPTOKENS_API_KEY"],
    max_retries=0,  # we retry ourselves
)

RETRYABLE = {429, 500, 502, 503, 504}


def chat_with_retry(model, messages, max_attempts=5, max_total=60.0):
    started = time.monotonic()
    for attempt in range(max_attempts):
        try:
            return client.chat.completions.create(model=model, messages=messages)
        except APIStatusError as err:
            last = attempt == max_attempts - 1
            if err.status_code not in RETRYABLE or last:
                raise
            header = err.response.headers.get("retry-after")
            if header and header.replace(".", "", 1).isdigit():
                delay = float(header) + random.uniform(0, 1)  # minimum wait + jitter
            else:
                delay = random.uniform(0, min(30.0, 2.0 ** attempt))  # full jitter
            if time.monotonic() - started + delay > max_total:
                raise
            time.sleep(delay)

Başlık olmadığında gecikmenin üst sınırı 1, 2, 4, 8 saniye olarak büyür (30'da sınırlanır) ve random.uniform bunun altında rastgele bir değer seçer, böylece birçok çalışan aynı anda uyanmaz. Retry-After bir HTTP tarihi de olabilir; yukarıdaki kod sayısal biçimi işler ve aksi durumda geri çekilmeye döner.

JavaScript: aynı döngü#

javascript
import OpenAI from "openai";

const client = new OpenAI({
  baseURL: "https://api.cheaptokens.dev/v1",
  apiKey: process.env.CHEAPTOKENS_API_KEY,
  maxRetries: 0, // we retry ourselves
});

const RETRYABLE = new Set([429, 500, 502, 503, 504]);
const sleep = (ms) => new Promise((r) => setTimeout(r, ms));

export async function chatWithRetry(model, messages, maxAttempts = 5, maxTotalMs = 60000) {
  const started = Date.now();
  for (let attempt = 0; attempt < maxAttempts; attempt++) {
    try {
      return await client.chat.completions.create({ model, messages });
    } catch (err) {
      const last = attempt === maxAttempts - 1;
      if (!RETRYABLE.has(err.status) || last) throw err;
      const header = Number(err.headers?.get?.("retry-after"));
      const delayMs = Number.isFinite(header) && header > 0
        ? header * 1000 + Math.random() * 1000 // minimum wait + jitter
        : Math.random() * Math.min(30000, 2 ** attempt * 1000); // full jitter
      if (Date.now() - started + delayMs > maxTotalMs) throw err;
      await sleep(delayMs);
    }
  }
}

İşe yaradığında, hız limitli bir çağrı sadece daha uzun sürer ve ardından normal bir tamamlama döndürür. Son denemeden sonra hâlâ başarısız olursa orijinal hata yükseltilir, böylece kodunuz onu günlüğe kaydedebilir veya işi daha sonrası için kuyruğa alabilir.

Ajanlar 429'u nasıl ele almalı#

Bir ajan döngüsü çok sayıda kısa çağrı gönderir ve birden fazla ajan veya araç çağrısı aynı anda çalışabilir. Yalnızca yeniden denemek yeterli değildir; istek hızını kaynağında düşürün:

  1. Eşzamanlılığı sınırlayın. 3–5 paralel çağrılık bir semafor makul bir başlangıçtır; yalnızca hatalar seyrek kaldığı sürece artırın.
  2. Tek bir sınırlayıcı paylaşın. Birkaç çalışan aynı anahtarı kullanıyorsa aynı limitleri paylaşırlar, bu yüzden çalışan başına bir yeniden deneme döngüsü yeterli değildir: süreç için tek bir kuyruk veya tek bir semafor kullanın.
  3. Genel olarak geri çekilin. Bir çağrı gecikmeli bir 429 aldığında, yalnızca başarısız çağrıyı değil tüm havuzu o süre boyunca duraklatın.
  4. İstekleri küçük tutun. İstek başına daha az token, dakika başına token limitleri üzerindeki baskıyı azaltır: geçmişi ve araç çıktısını kırpın. Tokenların nereye gittiği için bir AI ajanının maliyeti nasıl tahmin edilir yazısına bakın.
  5. Yeniden denenemeyen hatalarda durun. Bir 401, 400 veya bakiye hatası kendiliğinden düzelmez; hızlıca başarısız olun ve bildirin.
python
import asyncio

limit = asyncio.Semaphore(4)  # at most 4 requests in flight


async def run(job):
    async with limit:
        return await call_model(job)  # your async call with the retry loop above

Ajan döngülerini CheapTokens üzerinde çalıştırın#

Çok sayıda kısa çağrı içeren ajan döngüleri için CheapTokens, MiniMax-M2.7 sunar: günün her saatinde tek fiyat, 180K bağlam, yanıt başına 8.192 token'a kadar ve tüm modeller için tek bakiye. Çıktı 1M token başına $0.15 tutar ve girdi ile çıktı birlikte sayıldığında toplamda OpenRouter'dan daha ucuzdur. OpenAI uyumlu https://api.cheaptokens.dev/v1 uç noktası üzerinden çalışır. Yukarıdaki kod zaten bu uç noktayı işaret ediyor; model kimliğini CheapTokens dokümanlarından ayarlayın ve çalıştırın.

500.000 girdi, 100.000 çıktı iş yükü için canlı fiyatlar:

Model Maliyet OpenRouter
GLM-5.3-Flash $0.014 $0.0282
DeepSeek-V4-Flash $0.0175 $0.0394
MiniMax-M2.7 $0.04 $0.27

Toplamda 500.000 giriş ve 100.000 çıkış token'ı. 1M token başına fiyatlar günceldir ve tarifelerimizle birlikte değişir; OpenRouter sütunu aynı iş yükü için referans fiyatları gösterir.

Tüm fiyatlara, kurulum dokümanlarına bakın ve ilk isteğinizi göndermek için bir anahtar oluşturun.

Hâlâ başarısız olursa#

  • İlk istekte 429. Yanıt gövdesindeki hata türünü ve mesajını okuyun: harcama veya hesap limiti kaynaklı bir 429, limit yükseltilene veya erişim yeniden sağlanana kadar yeniden denemede başarısız olmaya devam eder; hız limiti kaynaklı bir 429 ise bir duraklamadan sonra temizlenir.
  • Uzun bir döngüyle 429 gelmeye devam ediyor. Yeniden denemeleri yığıyor olabilirsiniz: SDK yeniden denemeleri çarpı sizin yeniden denemeleriniz. Örneklerde olduğu gibi SDK'yı sıfıra ayarlayın.
  • Hatalar bir toplu işin başında patlamalar halinde geliyor. Tüm çalışanları aynı anda ateşlemek yerine kademeli olarak artırın; OpenAI çok hızlı büyüyen trafik için slow_down bildirir.
  • Akış çağrısı yarıda başarısız oldu. Çıktıyı tükettikten sonra körü körüne yeniden oynatmayın; tüm yanıtı yeniden başlatmaya mı yoksa elinizdekinden devam etmeye mi karar verin.
  • Yanıtta Retry-After yok. Kod jitter'lı geri çekilmeye döner, bu yüzden değişiklik gerekmez.