Tools

Xử lý lỗi Claude API đúng cách: 429, 529, spend cap và rate limit

Tóm tắt

Không phải lỗi nào cũng nên retry. 429 có thể là rate limit (có retry-after) hoặc chạm spend cap (không retry được đến tháng sau). Prompt caching giúp tăng throughput vì cache read không tính vào ITPM với hầu hết model.

Ứng dụng gọi Claude API chạy ngon trên máy dev, lên production thì thỉnh thoảng nhận 429, đôi lúc 529, có hôm cả hệ thống "chết" đến đầu tháng sau mà không ai hiểu vì sao. Phần lớn sự cố này đến từ việc đối xử mọi lỗi như nhau: retry tất cả, hoặc không retry gì. Bài này hệ thống hoá các mã lỗi, cơ chế rate limit và cách xử lý đúng theo tài liệu chính thức của Anthropic.

Bảng mã lỗi: cái nào retry, cái nào không

HTTPerror.typeNguyên nhânRetry?
400invalid_request_errorRequest sai format/nội dung; cũng dùng khi chạm spend limit do bạn tự đặtKhông, sửa request
401authentication_errorAPI key sai, bị thu hồi, hết hạnKhông
402billing_errorVấn đề thanh toánKhông
403permission_errorKey không có quyền với tài nguyênKhông
404not_found_errorSai endpoint hoặc IDKhông
413request_too_largeVượt kích thước (Messages 32 MB, Batch 256 MB, Files 500 MB)Không, cắt nhỏ
429rate_limit_errorVượt rate limit, hoặc chạm spend cap của tierCó, theo retry-after (trừ spend cap)
500api_errorLỗi nội bộCó, exponential backoff
504timeout_errorXử lý quá lâuCó; nên chuyển sang streaming
529overloaded_errorAPI quá tải chung, không phải lỗi của riêng bạnCó, backoff

Lỗi luôn trả về JSON có error.type, error.message và request_id. Mỗi response cũng có header request-id: luôn log giá trị này, đó là thứ đầu tiên support hỏi.

Rate limit hoạt động thế nào?

  • Ba loại limit theo model: RPM (request/phút), ITPM (input token/phút), OTPM (output token/phút). Vượt bất kỳ cái nào đều nhận 429.
  • Token bucket: dung lượng được nạp lại liên tục chứ không reset theo phút tròn. 60 RPM có thể được áp như 1 request/giây, nên burst ngắn vẫn dính 429 dù tổng trong phút chưa vượt.
  • Theo tier: tổ chức được xếp tier tự động theo lịch sử dùng. Tổ chức mới có thể bắt đầu ở tier Evaluation với limit thấp hơn.
  • Acceleration limit: tăng traffic đột ngột có thể nhận 429 dù chưa chạm limit danh nghĩa. Hãy tăng tải từ từ.

Prompt caching = tăng limit miễn phí

Với hầu hết model, cache_read_input_tokens không tính vào ITPM; chỉ input_tokens và cache_creation_input_tokens bị tính. Tài liệu đưa ví dụ: limit 2 triệu ITPM, tỉ lệ cache hit 80% thì xử lý được hiệu quả khoảng 10 triệu input token/phút. Còn OTPM chỉ đếm token thực sinh ra, max_tokens đặt cao không làm hao limit.

Bẫy lớn: 429 vì chạm spend cap

Mỗi tier có trần chi tiêu tháng. Khi chạm, API trả 429 cùng error.type với rate limit, nhưng:

  • Không có header retry-after, và error.details.error_code là enforced_spend_limit_reached.
  • Retry vô ích cho đến 00:00 UTC ngày 1 tháng sau, trừ khi nâng tier.

Nếu code chỉ nhìn status 429 rồi retry vô hạn, bạn sẽ đốt CPU và log trong khi người dùng chờ mãi. Phân biệt bằng error_code và báo động ngay.

Logic xử lý gợi ý

try:
    resp = client.messages.create(...)
except anthropic.RateLimitError as e:
    body = e.body or {}
    code = body.get("error", {}).get("details", {}).get("error_code")
    if code == "enforced_spend_limit_reached":
        alert_oncall("Chạm spend cap"); raise   # không retry
    raise                                       # để SDK/hàng đợi retry
except (anthropic.APIStatusError) as e:
    log.error("claude_error", status=e.status_code,
              request_id=e.response.headers.get("request-id"))
    raise

SDK chính thức đã tự retry 2 lần với exponential backoff cho lỗi kết nối, 429 và 5xx, có tôn trọng retry-after. Chỉnh bằng max_retries. Đừng bọc thêm vòng retry thủ công bên ngoài mà không giới hạn, kẻo nhân số lần thử lên nhiều lần.

Theo dõi bằng header

Mỗi response có anthropic-ratelimit-requests-remaining, anthropic-ratelimit-input-tokens-remaining, anthropic-ratelimit-output-tokens-remaining và các header -reset (định dạng RFC 3339). Ghi chúng vào metrics để thấy trước khi nào sắp chạm trần.

Áp dụng thế nào?

  • Dev: Bắt lỗi theo class của SDK, không so chuỗi message. Log request-id. Dùng streaming cho request dài thay vì tăng timeout.
  • Tech Lead: Đưa job khối lượng lớn qua hàng đợi có giới hạn đồng thời; job không gấp chuyển sang Batch API. Bật prompt caching cho system prompt và tài liệu lặp lại để tăng throughput.
  • PM: Đặt spend limit cho từng workspace trong Console và cảnh báo trước 80% để không bị "tắt" giữa tháng.

Nguồn & tham khảo

  1. Claude API errors — Claude Docs
  2. Rate limits — Claude Docs