429 Too Many Requests là phản hồi hữu ích nhất mà nhà cung cấp LLM gửi cho bạn. Hữu ích hơn cả phần thân JSON. Có tính hành động hơn mã lỗi. Vì ẩn trong header của nó là một đồng hồ đo công suất thời gian thực —x-ratelimit-remaining, retry-after— mà hầu hết code sản xuất bỏ qua. Kỹ sư coi giới hạn tốc độ là một bức tường để đâm vào. Nó là một đồng hồ để đọc.
Đâm vào tường trông như thế này. App của bạn chạy tốt lúc 2 giờ chiều. Lưu lượng tăng lúc 3 giờ. Đến 3:15, mọi request trả về 429. Logic retry của bạn kích hoạt —khoảng cố định một giây— và tạo ra một đàn gấu (thundering herd). Mọi lần retry đều đâm vào cùng một cửa sổ giới hạn. Mười phút sự cố dây chuyền. Người dùng thấy lỗi. Người trực bị gọi. Giải pháp không phải là “retry mạnh hơn”. Nó chưa bao giờ là retry mạnh hơn.
Khoảng cách giữa hai kết cục đó —đâm vào tường so với đọc đồng hồ— là ba lớp code. Bài viết này bao quát cả ba. Lớp phản ứng: backoff hàm mũ với jitter. Lớp chủ động: throttling thông minh header đọc ngân sách còn lại và giảm tốc trước khi đâm vào tường. Lớp dự đoán: tạm dừng trước lời gọi, lưu checkpoint trạng thái agent trước khi lời gọi tiếp theo cạn kiệt hạn mức. Code Python hoạt động cho mỗi lớp. Các mẫu đã kiểm chứng trong sản xuất.
Cho các khái niệm nền tảng về xác thực API và quản lý key làm nền tảng cho việc xử lý giới hạn tốc độ, xem hướng dẫn bảo mật API key của chúng tôi.
Vì sao giới hạn tốc độ tồn tại —và chúng thực sự hoạt động thế nào
Giới hạn tốc độ không phải hình phạt. Chúng là bảo vệ hạ tầng. Mỗi request API tiêu thụ bộ nhớ GPU và tài nguyên tính toán. Một client không throttling có thể làm bão hòa cụm suy luận của nhà cung cấp trong vài giây. Giới hạn đảm bảo phân bổ công bằng giữa mọi người dùng.
Ba giới hạn bạn cần quan tâm:
- RPM (Requests Per Minute): số lần gọi API bạn có thể thực hiện. Gói trả theo nhu cầu: thường 500–3,000 RPM. Gói miễn phí: 10–50 RPM. Doanh nghiệp: tùy chỉnh.
- TPM (Tokens Per Minute): tổng token của mọi request —đầu vào + đầu ra. Một prompt 100K token tiêu thụ hạn mức bằng 500 request thường. Giới hạn TPM bảo vệ chống điều này.
- Request đồng thời: số request có thể đang xử lý cùng lúc. Vượt mức này, request mới bị xếp hàng hoặc từ chối. Giới hạn này thường không được ghi chép và học qua kinh nghiệm đau đớn.
Các tầng theo nhà cung cấp đưa con số thực vào các giới hạn này. Tier 5 của OpenAI (mức trả theo nhu cầu cao nhất) cấp 10,000 RPM và 30,000,000 TPM cho model GPT-4.x —nhưng Tier 1 chỉ bắt đầu từ 500 RPM và 200,000 TPM. Claude API của Anthropic cung cấp 1,000 RPM ở tầng tiêu chuẩn với 80,000 TPM cho Claude Opus và 400,000 TPM cho Claude Sonnet, phản ánh chi phí suy luận khác nhau của mỗi model.
Gemini API của Google cung cấp 1,500 RPM trả theo nhu cầu với trần 2,000,000 TPM. Mỗi nhà cung cấp cũng áp dụng ghi đè theo model —giới hạn TPM của Claude Opus 4 chặt hơn Claude Sonnet 4 vì model lớn hơn tiêu thụ tỷ lệ tài nguyên tính toán nhiều hơn. Chuyển từ Tier 1 lên Tier 5 ở OpenAI đòi hỏi cả lịch sử chi tiêu tăng ($250+/tháng) lẫn thành tích sử dụng không lạm dụng trong 30+ ngày.
Bạn không có được giới hạn cao bằng cách hỏi khéo —bạn kiếm được chúng qua các mẫu lưu lượng sản xuất bền vững chứng minh bạn sẽ không làm ngập cụm. Biết chính xác tầng và giới hạn của mình là bước một để xây bất kỳ lớp nào trong ba lớp tiếp theo.
Cách đọc giới hạn hiện tại của bạn. Mỗi phản hồi API đều có header giới hạn tốc độ —và gần như không ai đọc chúng. Tài liệu giới hạn tốc độ của OpenAI giải thích định dạng header và cấu trúc tầng:
x-ratelimit-remaining-requests: 487
x-ratelimit-remaining-tokens: 823000
x-ratelimit-reset-requests: 12s
Những header này có trên phản hồi 200, không chỉ 429. Chúng cho bạn biết chính xác còn bao nhiêu ngân sách trước khi bị throttling. Đưa chúng lên dashboard giám sát như một đồng hồ đo. Cảnh báo khi mức còn lại dưới 20%. Khác biệt giữa “chúng tôi đâm vào giới hạn” và “chúng tôi thấy nó đến và định tuyến né” chính là việc đọc các header này.
Câu chuyện kinh hoàng về giới hạn tốc độ: hai sự cố bạn không muốn lặp lại
Một nền tảng thương mại điện tử châu Âu ra mắt trợ lý mua sắm AI chạy bằng GPT-4.5 cho dịp Black Friday. QA của họ thử nghiệm với 50 người dùng đồng thời —sản xuất đạt 2,300 trong giờ đầu tiên. Retry khoảng cố định biến 429 thành sự cố 47 phút.
Tổn thất doanh thu: $180,000 trong số giỏ hàng bị bỏ được theo dõi trong khoảng thời gian đó. Nguyên nhân gốc không phải khối lượng lưu lượng —mà là logic retry khuếch đại đỉnh điểm thay vì hấp thụ nó.
Một công ty SaaS phân tích di chuyển giữa các phiên bản API OpenAI mà không đọc nhật ký thay đổi giới hạn. Phiên bản mới cắt giảm RPM của họ từ 3,000 xuống 1,500 ở tầng của họ. Code throttling hiện có giả định giới hạn cũ.
Sản xuất chạy tốt trong sáu ngày —cho đến khi chu kỳ báo cáo hàng tháng tăng gấp ba khối lượng request. Mọi tác vụ báo cáo đồng loạt nhận 429. Phát hiện mất 22 phút vì giám sát của họ chỉ theo dõi lỗi 5xx, không phải 429.
Sửa lỗi chỉ ba dòng: cập nhật hằng số RPM. Bài học là vĩnh viễn: mỗi lần di chuyển phiên bản API là một lần di chuyển giới hạn tốc độ.
Lớp 1: Throttling phía client
Lớp đơn giản nhất. Một token bucket hoặc semaphore ngăn ứng dụng của bạn vượt quá giới hạn đã khai báo của nhà cung cấp.
import asyncio
import time
class RateLimiter:
"""Token bucket rate limiter for LLM API calls."""
def __init__(self, max_rpm: int):
self.max_rpm = max_rpm
self.tokens = max_rpm
self.last_refill = time.monotonic()
self.semaphore = asyncio.Semaphore(max_rpm // 6) # Concurrency cap
async def acquire(self):
"""Wait until a request can be sent without exceeding RPM."""
# Refill tokens based on elapsed time
now = time.monotonic()
elapsed = now - self.last_refill
refill = elapsed * (self.max_rpm / 60)
self.tokens = min(self.max_rpm, self.tokens + refill)
self.last_refill = now
if self.tokens < 1:
wait_time = (1 - self.tokens) / (self.max_rpm / 60)
await asyncio.sleep(wait_time)
self.tokens = 1
self.tokens -= 1
limiter = RateLimiter(max_rpm=500)
async def rate_limited_api_call(model: str, messages: list):
await limiter.acquire()
# Make the API call
Thứ tự quan trọng: Luôn lấy token RPM trước semaphore đồng thời. Đảo ngược thứ tự gây chặn đầu hàng đợi —các slot đồng thời bị lấp bởi request không gửi được, bỏ đói các request có thể gửi.
Lớp này ngăn vết thương tự gây phổ biến nhất: vượt giới hạn đã khai báo của tầng vì bạn không theo dõi tốc độ gọi. Với hầu hết ứng dụng lưu lượng thấp đến trung bình, điều này là đủ.
Lớp 2: Backoff thông minh header
Lớp 1 ngăn bạn vượt giới hạn đã biết. Lớp 2 xử lý điều xảy ra khi công suất thực của nhà cung cấp dao động —và nó dao động liên tục, tùy theo tải tổng thể của cụm.
import random
from openai import OpenAI
client = OpenAI(
base_url="https://api.tokspan.com/v1",
api_key="ts-your-key-here"
)
def chat_with_backoff(messages, model="claude-opus-4-8", max_retries=4):
"""Exponential backoff with jitter + header awareness."""
for attempt in range(max_retries):
try:
response = client.chat.completions.create(
model=model,
messages=messages,
timeout=30
)
# Read remaining budget from headers —even on success
remaining = response.headers.get("x-ratelimit-remaining-requests")
if remaining and int(remaining) < 50:
print(f"Rate limit low: {remaining} requests remaining. Slow down.")
return response
except Exception as e:
if "429" in str(e) or "rate_limit" in str(e).lower():
if attempt == max_retries - 1:
raise # Out of retries
# Exponential backoff: 1s —2s —4s —8s
wait = (2 ** attempt) + random.uniform(0, 1)
print(f"Rate limited. Retrying in {wait:.1f}s (attempt {attempt + 1}/{max_retries})")
import time
time.sleep(wait)
else:
raise # Not a rate limit error —don't retry
Ba quy tắc của backoff:
- Không bao giờ retry khoảng cố định. Nó tạo đàn gấu. Mọi client retry tại t+1s đâm vào cùng cửa sổ giới hạn.
- Luôn thêm jitter.
+ random.uniform(0, 1)trải các lần retry qua cửa sổ. Chỉ riêng điều này ngăn hầu hết sự cố dây chuyền. - Không bao giờ retry 401, 403 hoặc 400. Retry một API key sai hoặc request lỗi định dạng không sửa được. Chỉ retry 429 và 5xx.
Điều KHÔNG nên làm. Mẫu này —xuất hiện trong code sản xuất thường đến bất ngờ— tương đương với việc hét to hơn vào người không nói ngôn ngữ của bạn:
# DO NOT DO THIS
while True:
try:
response = client.chat.completions.create(...)
break
except:
time.sleep(1) # Fixed interval, no jitter, infinite retry
Điều này tạo đàn gấu và đảm bảo bạn kẹt trong giới hạn. Mọi lần retry đến đúng cùng một điểm của cửa sổ giới hạn. Hạ tầng nhà cung cấp thấy một đỉnh các request giống hệt, throttling tất cả, và app của bạn đi vào vòng xoáy chết.
Lớp 3: Tạm dừng dự đoán
Lớp 1 và 2 mang tính phản ứng —chúng trả lời sau khi đâm vào (hoặc tiến gần) một giới hạn. Lớp 3 mang tính dự đoán —nó đọc ngân sách trước lời gọi và quyết định: tiếp tục, chờ ngắn, hoặc checkpoint và tạm dừng.
def predict_rate_limit(response_headers: dict) -> str:
"""Three-valued decision based on remaining budget."""
remaining_req = int(response_headers.get("x-ratelimit-remaining-requests", 1000))
remaining_tok = int(response_headers.get("x-ratelimit-remaining-tokens", 1000000))
if remaining_req > 100 and remaining_tok > 200000:
return "continue" # Plenty of budget
elif remaining_req > 20:
return "wait" # Budget running low —short pause
else:
return "checkpoint" # Budget nearly exhausted —suspend
# Usage in an agent loop:
for step in agent_steps:
response = call_llm(current_state)
decision = predict_rate_limit(response.headers)
if decision == "continue":
process(response)
elif decision == "wait":
time.sleep(5) # Short pause, let budget recover
process(response)
else: # checkpoint
save_agent_state(current_state) # Save progress
time.sleep(60) # Wait for rate-limit window reset
resume_agent_from_checkpoint() # Resume without losing work
Công nghệ mới nhất 2026: agentpause. Một thư viện Python đọc header giới hạn trên mỗi phản hồi, dự đoán cạn kiệt trước lời gọi tiếp theo và lưu checkpoint trạng thái agent trước khi tạm dừng. Kết quả đo được: tỷ lệ crash 0% so với đường cơ sở phản ứng 100%. Không lỗi 429. Ít lãng phí token 80% từ các lần retry thất bại. Nếu bạn chạy agent sản xuất thông lượng cao, agentpause hoặc logic dự đoán tương đương không còn là tùy chọn —nó là khác biệt giữa “agent của chúng tôi đáng tin cậy” và “agent của chúng tôi sập ngẫu nhiên khi lưu lượng tăng đột biến”.
Định tuyến đa nhà cung cấp: giải pháp giới hạn tốc độ tốt nhất
Mọi chiến lược trên giả định bạn nói chuyện với một nhà cung cấp. Chiến lược giới hạn hiệu quả nhất là nói chuyện với nhiều nhà cung cấp.
Hiểu biết cốt lõi: Thay vì chờ giới hạn của một nhà cung cấp được thiết lập lại, hãy gửi request đến nhà cung cấp khác. Giới hạn hiệu quả của bạn trở thành tổng của mọi nhà cung cấp bạn có thể định tuyến tới.
Một router round-robin với token bucket mỗi nhà cung cấp và cooldown tự động:
PROVIDERS = {
"openai": {"rpm": 2000, "cooldown_until": 0},
"anthropic": {"rpm": 1500, "cooldown_until": 0},
"google": {"rpm": 1000, "cooldown_until": 0},
}
def route_request(messages):
now = time.time()
available = [
p for p, cfg in PROVIDERS.items()
if now > cfg["cooldown_until"]
]
if not available:
raise RuntimeError("All providers in cooldown")
# Round-robin among available providers
provider = available[hash(str(messages)) % len(available)]
try:
return call_provider(provider, messages)
except RateLimitError:
PROVIDERS[provider]["cooldown_until"] = now + 30 # Cooldown for 30s
return route_request(messages) # Retry with a different provider
Nền tảng tổng hợp xử lý việc này ở cấp hạ tầng —endpoint duy nhất của bạn định tuyến tới mọi nhà cung cấp, với cooldown tự động, chuyển đổi dự phòng và giám sát giới hạn. Bạn đặt thông lượng mong muốn. Nền tảng quản lý giới hạn mỗi nhà cung cấp. Cho triển khai định tuyến đầy đủ và chuyển đổi dự phòng thông minh độ trễ, xem hướng dẫn thiết lập đa model sản xuất và tài liệu custom routing của chúng tôi.
Câu hỏi thường gặp
Lỗi giới hạn tốc độ phổ biến nhất là gì?
Retry khoảng cố định. Trễ một giây trên mọi client tạo đàn gấu đảm bảo nhiều 429 hơn. Luôn dùng backoff hàm mũ với jitter ngẫu nhiên. Chỉ riêng jitter —thêm random.uniform(0, 1) vào thời gian chờ— ngăn hầu hết sự cố dây chuyền.
Làm sao biết giới hạn tốc độ của mình?
Kiểm tra dashboard nhà cung cấp để biết giới hạn đã khai báo của tầng. Sau đó đọc header x-ratelimit-remaining-* trên mỗi phản hồi API —chúng cho biết ngân sách còn lại thực tế theo thời gian thực. Giám sát chúng. Bạn không biết giới hạn của mình cho đến khi đâm vào —và đó là cách hầu hết đội vận hành.
Dùng nhiều nhà cung cấp có thực sự giải quyết giới hạn không?
Có —hiệu quả. Giới hạn 500 RPM mỗi nhà cung cấp trở thành 2,000 RPM trên bốn nhà cung cấp với router round-robin. Nền tảng tổng hợp với định tuyến đa nhà cung cấp làm điều này minh bạch: một endpoint, quản lý giới hạn tự động ở cấp nhà cung cấp. Kết hợp định tuyến đa nhà cung cấp với chiến lược tối ưu chi phí để tăng thông lượng mà không nhân đôi hóa đơn —định tuyến model rẻ hơn cho request không quan trọng và dành model đắt cho tác vụ cần chúng.
Sửa lỗi đơn giản nhất có thể triển khai hôm nay?
Thay retry khoảng cố định bằng backoff hàm mũ + jitter. Năm dòng code. Ngăn đàn gấu biến một lần 429 thành sự cố dây chuyền. Code Lớp 2 trong bài viết này sẵn sàng để copy-paste.
Nền tảng tổng hợp có thể xử lý giới hạn cho tôi không?
Có. Định tuyến đa nhà cung cấp, cooldown tự động cho nhà cung cấp bị throttling và dashboard giới hạn thống nhất là các tính năng tiêu chuẩn. Bạn cấu hình thông lượng mong muốn. Nền tảng xử lý quản lý hạn mức mỗi nhà cung cấp, giám sát header và chuyển đổi dự phòng tự động. Một endpoint. Không 429.
Ba lớp ở đây —throttle, backoff, dự đoán— biến giới hạn tốc độ từ mối đe dọa độ tin cậy thành vấn đề kỹ thuật đã giải. Nhưng khi định tuyến đa nhà cung cấp trở thành tiêu chuẩn và các nhà cung cấp cạnh tranh bằng cam kết thông lượng, câu hỏi dịch chuyển: liệu “vượt giới hạn tốc độ” có gia nhập “đầy đĩa” và “hết bộ nhớ” như những lỗi mà hạ tầng hiện đại đơn giản làm cho lỗi thời không? Hiện tại, code trong bài viết này giữ bạn hoạt động. Vòng cung dài hơn chỉ về một nơi thú vị hơn.
Lớp 1 và Lớp 2 bạn có thể triển khai trong một buổi chiều với code trên. Lớp 3 —tạm dừng dự đoán— cần đầu tư nhiều hơn. Nền tảng tổng hợp gói cả ba vào đường request: định tuyến đa nhà cung cấp hấp thụ throttling cấp nhà cung cấp, giám sát header nuôi dưỡng dashboard giới hạn dùng chung, và cooldown tự động giữ nhà cung cấp khỏe mạnh trong vòng xoay khi một nhà cung cấp suy giảm. Không kiến trúc nào loại bỏ hoàn toàn 429, nhưng trải lưu lượng qua các nhà cung cấp và đọc header trước khi đâm vào tường biến chúng từ sự cố hàng tuần thành trường hợp hiếm gặp.