This article hasn't been translated into this language yet; showing the Persian version.

Basic

محدودیت نرخ درخواست (rate limit) و چطور باهاش کنار بیای

یعنی چی وقتی HTTP 429 می‌گیری، فرقش با کیف پول خالی چیه، و چطور کدت رو در برابرش مقاوم کنی.

اگه وسط زدن چندتا درخواست پشت‌سرهم به بنفش یه HTTP 429 گرفتی — این مقاله برای توئه. تا آخرش می‌دونی این خطا دقیقاً یعنی چی، با کیف پول خالی (402) چه فرقی داره، و کدت رو چطور بنویسی که خودش ازش رد بشه.

۴۲۹ یعنی چی

HTTP 429 یعنی تعداد درخواست‌هات تو یه بازه‌ی زمانی از یه سقف رد شده — نه این‌که کلیدت مشکل داره (۴۰۱)، نه این‌که کیف پولت خالیه (۴۰۲). سرور موقتاً داره درخواست‌های جدید رو رد می‌کنه تا بار کم بشه.

این با سقف کیف پول یا سقف هر اجرا فرق داره

«کنترل مصرف و هزینه» و «رفع اشکال اتصال» دو تا خطای دیگه رو توضیح می‌دن که شبیه به نظر می‌رسن ولی علتشون کاملاً جداست:

  • HTTP 402 = کیف پولت خالیه. تا شارژ نکنی برطرف نمی‌شه.
  • HTTP 401 بعد از پر شدن سقف هر اجرا = کلیدت خودکار جایگزین شده. باید کلید جدید رو برداری.
  • HTTP 429 = نرخ یا همزمانی درخواست‌هات بالاست. بعد از یه مکث کوتاه، همون درخواست دوباره جواب می‌ده — چیزی رو عوض نمی‌کنی، فقط صبر می‌کنی.

عدد دقیق سقف رو از خودِ جواب بخون، نه از این مقاله

سقف نرخ می‌تونه بر اساس کلید، مدل، یا کل gateway فرق کنه و با زمان تغییر کنه — یه عدد اینجا بنویسیم فردا ممکنه اشتباه باشه. جواب ۴۲۹ معمولاً جزئیاتش رو تو بدنه یا هدر می‌ده؛ همیشه از همون‌جا بخون:

css
HTTP/1.1 429 Too Many Requests
Retry-After: 2

{"error": {"message": "..."}}

اگه هدر Retry-After هست، دقیقاً همون‌قدر (به ثانیه) صبر کن قبل از تلاش بعدی.

راه‌حل: exponential backoff، نه حلقه‌ی بی‌وقفه

هیچ‌وقت بلافاصله بعد از ۴۲۹ همون درخواست رو دوباره نزن — این فقط سقف رو بیشتر فشار میاره. یه backoff نمایی ساده:

ts
async function callWithBackoff(fn: () => Promise<Response>, maxRetries = 5) {
  for (let attempt = 0; attempt < maxRetries; attempt++) {
    const res = await fn();
    if (res.status !== 429) return res;
    const retryAfter = res.headers.get("Retry-After");
    const waitMs = retryAfter ? Number(retryAfter) * 1000 : 2 ** attempt * 500;
    await new Promise((r) => setTimeout(r, waitMs));
  }
  throw new Error("rate limited after max retries");
}

اکثر SDKهای رسمی OpenAI این رفتار رو خودشون داخلی دارن (retry با backoff روی ۴۲۹ و ۵xx) — قبل از پیاده‌کردن دستی، تنظیمات retry خودِ SDK رو چک کن.

اگه مدام ۴۲۹ می‌گیری

  • همزمانی درخواست‌هات رو کم کن — به‌جای زدن چندتا درخواست موازی، صف‌شون کن.
  • اگه یه agent یا اسکریپت داری که تو حلقه سریع می‌زنه، بین درخواست‌ها یه تاخیر ثابت بذار، نه این‌که هرچی سریع‌تر می‌تونی بزنی.
  • اگه فکر می‌کنی سقفی که بهت خورده برای مصرف واقعیت کمه، از «اتصال به ابزارها» وضعیت کلیدت رو چک کن — شاید یه سقف اختیاری (سقف هر کلید یا سقف هر اجرا) خودت روش گذاشته باشی.