Giới hạn tốc độ API LLM: Xử lý lỗi 429, thử lại và chạy song song an toàn
Tác giả: Nicho
Một ứng dụng LLM chạy thực tế cần nhiều hơn một vòng lặp thử lại. Ứng dụng cần biết vì sao một yêu cầu bị từ chối, có thể nhận thêm bao nhiêu yêu cầu, và khi nào nên dừng thử lại.
Điểm khởi đầu thực tế rất đơn giản: phân loại lỗi, kiểm soát việc nhận yêu cầu, và chỉ thử lại những lỗi có khả năng hồi phục trong thời hạn của tác vụ. Tăng số lần thử lại mà không có các kiểm soát này có thể biến một đợt tăng lưu lượng nhỏ thành sự cố kéo dài hơn.
Hướng dẫn này nói về thiết kế ứng dụng không phụ thuộc nhà cung cấp. Hạn mức, mã lỗi, header và quy tắc tính toán cụ thể phụ thuộc vào nhà cung cấp, mô hình, tài khoản và gateway của bạn.
Hiểu rõ bạn đã chạm giới hạn nào
Các kiểm soát này trả lời những câu hỏi khác nhau:
| Kiểm soát | Đo lường điều gì | Cách ứng dụng phản hồi |
|---|---|---|
| Tốc độ yêu cầu | Số yêu cầu được nhận trong một khoảng thời gian | Điều tiết nhịp khởi động và làm mượt các đợt tăng vọt |
| Tốc độ token | Mức sử dụng token hoặc nhu cầu token ước tính | Dự trữ dung lượng token và giới hạn kích thước yêu cầu |
| Số luồng chạy đồng thời | Số yêu cầu đang xử lý | Giới hạn số worker hoặc dùng semaphore |
| Chi tiêu hoặc số dư | Khả năng thanh toán | Kiểm tra thanh toán hoặc hạn mức chi tiêu |
Ví dụ, OpenAI ghi rõ giới hạn yêu cầu và giới hạn token riêng biệt, với phạm vi có thể gồm cả dự án và các nhóm mô hình dùng chung. Vì vậy, một API key mới không hẳn là dung lượng mới. Tài liệu của OpenAI cũng phân biệt lỗi giới hạn tốc độ tạm thời với giới hạn chi tiêu cứng, dù cả hai đều dùng 429. Hãy đọc nội dung lỗi thay vì chỉ dựa vào mã trạng thái để quyết định. Tài liệu về giới hạn tốc độ của OpenAI
Chuẩn HTTP định nghĩa 429 nhưng không quy định cách một dịch vụ nhận diện người gọi hay đếm yêu cầu. Chuẩn này cũng để Retry-After là tùy chọn. Đừng cho rằng mọi endpoint tương thích OpenAI đều có hành vi điều tiết giống hệt nhau. Đặc tả HTTP 429
Tính toán lưu lượng theo giới hạn chặt hơn
Hãy xét một ví dụ đơn giản, giả định: hạn mức 60 yêu cầu mỗi phút và 120,000 token mỗi phút. Nếu mỗi yêu cầu dùng 4,000 token được tính, dung lượng token chỉ đủ cho 30 yêu cầu như vậy mỗi phút:
120,000 tokens/minute ÷ 4,000 tokens/request = 30 requests/minute
Đây là ví dụ để lập kế hoạch, không phải hạn mức của nhà cung cấp hay bộ điều phối chính xác. Một dịch vụ có thể dự trữ token đầu ra ước tính, dùng cửa sổ áp dụng ngắn hơn, hoặc tính các loại token khác nhau theo cách khác nhau.
Hãy đo phân bố kích thước yêu cầu của chính bạn. Chỉ nhìn số trung bình sẽ che mất những tệp tài liệu lớn và những lần sinh nội dung dài. Hãy để dư dung lượng cho các trường hợp ngoại lệ này thay vì nhắm đúng mức tối đa theo toán học.
Dùng kiểm soát riêng cho việc khởi động và việc đang xử lý. Chỉ giới hạn số luồng chạy đồng thời không đủ để áp đặt số yêu cầu mỗi phút: phản hồi nhanh có thể giải phóng chỗ đủ nhanh để tạo ra quá nhiều lượt khởi động. Ngược lại, bộ giới hạn tốc độ yêu cầu không ngăn các luồng streaming chậm tích tụ và làm cạn kết nối.
Đặt kiểm soát nhận yêu cầu trước khi thử lại
Một luồng xử lý yêu cầu hữu ích là:
Authenticated request → bounded queue → rate/token admission → worker → provider
Hãy thiết kế hàng đợi một cách có chủ đích:
- Đặt độ dài hàng đợi tối đa và thời gian chờ tối đa.
- Cho các yêu cầu tương tác thời hạn ngắn hơn so với tác vụ chạy nền.
- Từ chối hoặc hoãn phần việc vượt mức bằng một phản hồi rõ ràng ở tầng ứng dụng.
- Xóa các tác vụ đã hủy và hết hạn trước khi điều phối.
- Chia sẻ trạng thái tiếp nhận giữa các bản sao cùng dùng một hạn mức upstream.
Nếu không, việc thêm máy chủ ứng dụng có thể làm lưu lượng tăng gấp nhiều lần trong khi năng lực upstream không đổi. Với khối lượng công việc hỗn hợp, hãy dành một phần năng lực cho các yêu cầu hướng tới người dùng để một tác vụ nhập tài liệu không thể chiếm hết mọi chỗ.
Đây là các khuyến nghị về kiến trúc, không phải cam kết rằng một gateway cụ thể có hàng đợi hay các điều khiển đồng thời có thể điều chỉnh.
Dùng một chính sách thử lại có giới hạn
Thử lại cần có người chịu trách nhiệm. Hãy kiểm tra hành vi của SDK trước khi thêm một vòng lặp khác. Trong một cấu hình giả định, ba lần thử ở tầng ứng dụng bọc quanh ba lần thử của SDK có thể tạo ra chín lần thử upstream cho một thao tác logic.
Một chính sách thực tế là:
- Phân loại lỗi dựa trên thông tin lỗi được nhà cung cấp ghi trong tài liệu.
- Dừng ngay với các lỗi cần thay đổi thông tin xác thực, quyền, thanh toán hoặc nội dung yêu cầu.
- Chỉ thử lại các lỗi tạm thời đủ điều kiện khi cả ngân sách số lần thử và thời gian vẫn còn.
- Tuân theo hướng dẫn thử lại hợp lệ từ máy chủ; nếu không, dùng backoff lũy thừa có giới hạn kèm jitter.
- Trả về lỗi cuối cùng kèm đủ ngữ cảnh để điều tra an toàn.
Retry-After có thể chỉ định một độ trễ hoặc một ngày. Hãy coi độ trễ áp dụng từ máy chủ là mức tối thiểu, không phải gợi ý để rút ngắn. Nếu độ trễ vượt quá thời hạn còn lại của thao tác, hãy hoãn việc hoặc báo lỗi rõ ràng thay vì thử lại sớm. Ngữ nghĩa Retry-After của HTTP
Thời gian chờ ngẫu nhiên giúp giảm các đợt thử lại đồng loạt. Hết thời gian chờ và số lần thử có giới hạn giúp việc thử lại không giữ tài nguyên vô thời hạn. Hướng dẫn kỹ thuật của AWS giải thích vì sao thử lại có thể khuếch đại tình trạng quá tải và vì sao hết thời gian chờ không chứng minh rằng một thao tác không có tác dụng gì. Hướng dẫn của AWS về hết thời gian chờ và thử lại
Đừng phát lại mù quáng các streaming hoặc hành động của agent
Một streaming dừng sau khi đã hiển thị văn bản không giống với một yêu cầu bị từ chối trước khi công việc bắt đầu. Giao diện của bạn cần một trạng thái chưa hoàn tất rõ ràng. Tự động bắt đầu lại có thể nhân đôi văn bản, tốn thêm token hoặc tạo ra câu trả lời khác.
Quy trình agent cần thêm một ranh giới: thử lại việc tạo của mô hình không được tự động phát lại các hành động đã hoàn tất. Hãy ghi lại kết quả hành động và dùng các cơ chế idempotency ở nơi dịch vụ hành động hỗ trợ. Một phản hồi lỗi không biện minh cho việc gửi cùng một email hay tạo cùng một đơn hàng hai lần.
Theo dõi công việc logic, không chỉ thành công HTTP
Theo dõi riêng các mục sau:
- Thao tác logic và số lần thử upstream.
- Thời gian chờ trong hàng đợi và các yêu cầu đang xử lý.
- Số lần từ chối theo lý do lỗi được ghi trong tài liệu.
- Mức sử dụng đầu vào/đầu ra và chi phí cho mỗi thao tác hoàn tất.
- Hết thời gian chờ, công việc bị hủy và các streaming chưa hoàn tất.
Dùng mã định danh yêu cầu và siêu dữ liệu đã lọc sạch. Mặc định đừng ghi log header authorization hay toàn bộ prompt. Tỷ lệ lỗi giảm không phải là thắng lợi nếu việc thử lại làm chi phí mỗi tác vụ hoàn thành tăng gấp đôi.
Kiểm tra riêng phần kiểm soát của gateway và năng lực xử lý
Thông tin bảng giá và tài khoản mà cheapaimodel công bố mô tả hạn mức chi tiêu theo từng key, thời hạn, danh sách cho phép model/IP, và phản hồi 403 khi số dư tài khoản cạn. Tình trạng số dư đó không phải thứ mà một lần chờ ngắn rồi thử lại giải quyết được. Những phần kiểm soát đó cũng không thiết lập thông lượng yêu cầu hay token vô hạn.
Trước khi mở rộng một tích hợp, hãy xem tài liệu cheapaimodel hiện tại và xác nhận các giới hạn áp dụng cho route bạn định dùng. Giữ phần kiểm soát tiếp nhận và chính sách thử lại ở dạng cấu hình được, để thay đổi không cần viết lại logic của ứng dụng.
Mục tiêu là công việc hoàn thành có thể dự đoán được: chờ trong giới hạn, lỗi giải thích được, chi tiêu có kiểm soát, và việc thử lại giúp phục hồi thay vì chống lại quá trình phục hồi.