Khi kết thúc hướng dẫn này, bạn sẽ có thể gọi Batch API của OpenAI để chạy hàng nghìn yêu cầu mô hình dưới dạng một tác vụ không đồng bộ duy nhất và nhận lại mọi kết quả với mức giảm giá 50%. Bạn sẽ đóng gói các lời nhắc (prompt) của mình vào một tệp JSONL, gửi một lô (batch), thăm dò cho đến khi hoàn tất và tải xuống đầu ra, sau đó kiểm tra từng bước trong Apidog trước khi triển khai vào môi trường sản xuất. Nếu công việc của bạn mang tính tương tác hơn, đường dẫn đồng bộ sẽ phù hợp hơn và bạn có thể kiểm tra ChatGPT API bằng Apidog thay thế.
Batch API là gì và khi nào nên sử dụng
Batch API là một điểm cuối (endpoint) không đồng bộ dành cho khối lượng lớn các lệnh gọi mô hình có thể chấp nhận độ trễ. Thay vì một yêu cầu HTTP cho mỗi lời nhắc, bạn đóng gói nhiều yêu cầu vào một tệp JSONL duy nhất, gửi nó dưới dạng một công việc và thăm dò để biết khi nào hoàn thành. OpenAI chạy công việc vào thời gian thấp điểm và trả về mọi kết quả trong một tệp đầu ra.
Bạn nhận được hai lợi ích rõ ràng. Thứ nhất, giảm giá cố định 50% cho cả token đầu vào và đầu ra so với API đồng bộ. Thứ hai, thông lượng cao hơn, vì các tác vụ hàng loạt sử dụng một nhóm giới hạn tốc độ riêng biệt và không cạnh tranh với lưu lượng truy cập trực tiếp của bạn. Đánh đổi là độ trễ. OpenAI cam kết hoàn thành trong vòng 24 giờ; nhiều tác vụ hoàn thành sớm hơn, nhưng bạn không thể dựa vào điều đó.
Hãy sử dụng xử lý hàng loạt khi công việc là ngoại tuyến và có hình dạng lớn:
- Phân loại hoặc gắn thẻ các bản ghi tồn đọng
- Tạo nhúng (embeddings) cho toàn bộ tập dữ liệu
- Tạo nội dung hàng loạt (mô tả sản phẩm, tóm tắt, bản dịch)
- Chạy bộ kiểm tra đánh giá hoặc so sánh mô hình trên một tập dữ liệu
Bỏ qua nó đối với bất kỳ thứ gì người dùng đang chờ đợi. Giao diện người dùng trò chuyện, tự động hoàn thành và tác nhân trực tiếp cần các điểm cuối đồng bộ. Nếu bạn đang tạo nhiều cấu hình mô hình hoặc tác nhân cùng lúc, xử lý hàng loạt sẽ rất phù hợp với khối lượng công việc đó; xem hướng dẫn của chúng tôi về tạo hơn 100 cấu hình tác nhân bằng xử lý hàng loạt.
Những gì bạn cần trước khi bắt đầu
Toàn bộ quy trình trải dài qua hai điểm cuối, /v1/files và /v1/batches, và bốn bước. Đây là cấu trúc trước khi chúng ta xem xét các lệnh gọi.
| Bước | Điểm cuối | Điều gì xảy ra |
|---|---|---|
| 1. Tải lên | POST /v1/files |
Gửi tệp .jsonl của bạn với purpose: "batch", nhận lại một ID tệp |
| 2. Tạo | POST /v1/batches |
Gửi ID tệp với một điểm cuối và cửa sổ hoàn thành |
| 3. Thăm dò | GET /v1/batches/{id} |
Kiểm tra status cho đến khi nó đọc là completed |
| 4. Truy xuất | GET /v1/files/{id}/content |
Tải xuống kết quả qua output_file_id |
Để làm theo, bạn cần một khóa API OpenAI được xuất dưới dạng OPENAI_API_KEY, một tệp JSONL chứa các yêu cầu và một công cụ để thực hiện và kiểm tra các lệnh gọi. Mỗi bước trả về một đối tượng mà bạn có thể xác nhận, điều này giúp toàn bộ vòng đời dễ dàng kiểm tra.
Bước 1: Xây dựng và tải lên tệp JSONL
Đầu vào của bạn là một tệp JSONL trong đó mỗi dòng là một yêu cầu độc lập. Mỗi dòng cần bốn trường: một custom_id bạn chọn (để bạn có thể ghép nối kết quả với đầu vào), method (POST), url (điểm cuối đích như /v1/chat/completions) và body chứa các tham số yêu cầu thực tế.
{"custom_id": "req-1", "method": "POST", "url": "/v1/chat/completions", "body": {"model": "gpt-4.1-mini", "messages": [{"role": "user", "content": "Classify the sentiment of: 'shipping was slow but the product is great'"}]}}
{"custom_id": "req-2", "method": "POST", "url": "/v1/chat/completions", "body": {"model": "gpt-4.1-mini", "messages": [{"role": "user", "content": "Classify the sentiment of: 'returned it the same day'"}]}}
custom_id phải là duy nhất trong tệp. Kết quả không được đảm bảo theo thứ tự, vì vậy ID đó là cách bạn kết nối lại mỗi phản hồi với dòng gốc của nó. Một lô duy nhất có thể chứa tới 50.000 yêu cầu và tệp có thể có dung lượng lên tới 200 MB.
Tải nó lên Files API với mục đích batch:
curl https://api.openai.com/v1/files \
-H "Authorization: Bearer $OPENAI_API_KEY" \
-F purpose="batch" \
-F file="@requests.jsonl"
Phản hồi mang một id tệp (giống như file-abc123). Đó là input_file_id của bạn cho bước tiếp theo.
Bước 2: Tạo lô
Bây giờ hãy tạo công việc. Bạn truyền input_file_id, endpoint bạn đang nhắm mục tiêu và completion_window. Hiện tại completion_window chấp nhận một giá trị duy nhất là "24h".
curl https://api.openai.com/v1/batches \
-H "Authorization: Bearer $OPENAI_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"input_file_id": "file-abc123",
"endpoint": "/v1/chat/completions",
"completion_window": "24h",
"metadata": {"job": "sentiment-backfill"}
}'
Trường endpoint phải khớp với url được sử dụng bên trong các dòng JSONL của bạn. Các mục tiêu được hỗ trợ bao gồm /v1/chat/completions, /v1/responses, /v1/embeddings, /v1/completions và /v1/moderations, cùng với các mục tiêu khác. Đối tượng metadata tùy chọn chứa tới 16 cặp khóa-giá trị, rất tiện lợi để gắn thẻ các công việc mà bạn muốn lọc sau này.
Lệnh gọi trả về một đối tượng lô. Các trường bạn sẽ quan tâm nhất:
{
"id": "batch_abc123",
"object": "batch",
"endpoint": "/v1/chat/completions",
"input_file_id": "file-abc123",
"completion_window": "24h",
"status": "validating",
"output_file_id": null,
"error_file_id": null,
"request_counts": { "total": 0, "completed": 0, "failed": 0 },
"created_at": 1733452800,
"metadata": { "job": "sentiment-backfill" }
}
Bước 3: Thăm dò trạng thái lô
Một lô mới bắt đầu ở trạng thái validating. Từ đó, nó di chuyển qua một tập hợp các trạng thái được ghi lại. Thăm dò GET /v1/batches/{batch_id} và đọc trường status.
| Trạng thái | Ý nghĩa |
|---|---|
validating |
Tệp đầu vào đang được kiểm tra trước khi chạy |
in_progress |
Các yêu cầu đang được xử lý |
finalizing |
Quá trình chạy đã hoàn tất và tệp đầu ra đang được chuẩn bị |
completed |
Hoàn thành; kết quả đã sẵn sàng để tải xuống |
failed |
Xác thực thất bại; không có gì được chạy |
expired |
Cửa sổ 24 giờ đã đóng trước khi tất cả các yêu cầu hoàn thành |
cancelling / cancelled |
Bạn đã yêu cầu hủy |
Đối tượng request_counts (total, completed, failed) cung cấp cho bạn tiến độ trực tiếp trong khi trạng thái vẫn là in_progress. Không có webhook nào để chờ đợi ở đây, vì vậy thăm dò theo một khoảng thời gian hợp lý (mỗi vài phút, không phải mỗi giây) là mô hình đúng. Bạn cũng có thể hủy một công việc đang chạy bằng POST /v1/batches/{batch_id}/cancel nếu bạn đã gửi nó do nhầm lẫn.
Bước 4: Truy xuất đầu ra
Khi status hiển thị completed, đối tượng lô chứa một output_file_id. Tải xuống nội dung của tệp đó thông qua Files API:
curl https://api.openai.com/v1/files/file-output456/content \
-H "Authorization: Bearer $OPENAI_API_KEY" > results.jsonl
Đầu ra lại là JSONL, một dòng cho mỗi yêu cầu. Mỗi dòng lặp lại custom_id bạn đã đặt, cộng với một đối tượng response chứa mã trạng thái và nội dung. Bất kỳ yêu cầu nào bị lỗi sẽ hiển thị trong tệp được tham chiếu bởi error_file_id, vì vậy hãy kiểm tra cả hai. Ghép nối kết quả với đầu vào dựa trên custom_id, không phải dựa trên thứ tự dòng.
Lưu ý về các đánh đổi về chi phí và thời gian
Phép toán rất đơn giản: bạn tiết kiệm 50% chi phí token và chấp nhận thời gian xử lý lên tới 24 giờ. Đối với một tác vụ backfill một lần hoặc một công việc hàng đêm, đó là một lựa chọn dễ dàng. Đối với một tính năng trong lộ trình quan trọng của sản phẩm của bạn, thì không phải vậy.
Một vài ghi chú thực tế:
- Giảm giá áp dụng cho cả token đầu vào và đầu ra, trên tất cả các mô hình được hỗ trợ.
- Cửa sổ 24 giờ là giới hạn tối đa, không phải mục tiêu. Lập kế hoạch cho trường hợp xấu nhất; nếu một công việc đạt trạng thái
expired, các yêu cầu đã hoàn thành vẫn được tính phí và trả về, và phần còn lại thì không. - Các tác vụ hàng loạt sử dụng một giới hạn token xếp hàng riêng biệt, vì vậy một lô lớn sẽ không ảnh hưởng đến giới hạn tốc độ mà lưu lượng truy cập trực tiếp của bạn phụ thuộc vào. Nếu bạn đã gặp phải giới hạn, hướng dẫn của chúng tôi về giới hạn tốc độ GPT API và cách kiểm tra chúng bao gồm phía đồng bộ.
- Token giảm giá một nửa vẫn có thể tăng lên với số lượng lớn. Theo dõi chi tiêu cho mỗi công việc bằng cách sử dụng thẻ
metadatađể bạn có thể phân bổ chi phí sau này; đây là hướng dẫn phân bổ chi phí cho chi tiêu OpenAI.
Cách kiểm tra nó trong Apidog
Batch API dễ xảy ra lỗi hơn so với một lệnh gọi trò chuyện đơn lẻ, bởi vì các chế độ lỗi trải rộng trên các tệp, định dạng JSONL và một vòng lặp thăm dò. Một dòng bị định dạng sai trong một tệp 50.000 yêu cầu sẽ khiến toàn bộ quá trình tải lên thất bại, và bạn sẽ không biết cho đến khi quá trình xác thực chạy. Kiểm tra các điểm cuối vòng đời trước khi bạn tự động hóa chúng sẽ giúp bạn tiết kiệm thời gian.
- Trước tiên, xác thực định dạng JSONL. Trước khi bạn tải lên bất cứ thứ gì, hãy xác nhận rằng mỗi dòng mang
custom_id,method,urlvàbody, và rằngbody.modelcùng với các tin nhắn đều có mặt. Việc bắt lỗi thiếu trường cục bộ rẻ hơn so với một lô bị lỗi. - Chạy tải lên multipart. Gửi
POST /v1/filesvớipurpose=batchvà tệp của bạn, sau đó lưuidtrả về vào một biến môi trường. - Tạo lô và xác nhận đối tượng. Thực hiện
POST /v1/batches, sau đó xác nhận rằngstatuslàvalidatingvàendpointkhớp với những gì bạn đã gửi. Các xác nhận trực quan của Apidog cho phép bạn kiểm tra các trường đó mà không cần viết script. - Thăm dò và truy xuất. Thực hiện
GET /v1/batches/{id}trong một vòng lặp, xác nhận khistatustrở thànhcompleted, sau đó lấyoutput_file_idvà tải xuống kết quả. - Thực hành các đường dẫn hủy và lỗi. Gửi một tệp cố tình bị lỗi và xác nhận bạn nhận được trạng thái
failed, và kiểm traPOST /v1/batches/{id}/cancelđể việc xử lý lỗi của bạn là thật, không phải giả định.
Vì tệp đầu ra đến sau, bạn cũng có thể thiết lập một API giả trả về một đối tượng lô đã hoàn thành mẫu và một tệp kết quả được tạo sẵn. Điều đó cho phép bạn xây dựng và kiểm tra logic truy xuất và phân tích cú pháp của mình mà không cần chờ đợi một công việc thực sự mất 24 giờ, và không tốn token trong quá trình phát triển. Khi nhóm của bạn làm việc theo cách tiếp cận ưu tiên đặc tả, bạn cũng có thể tạo bộ sưu tập kiểm tra trực tiếp từ đặc tả OpenAPI và giữ các điểm cuối hàng loạt dưới sự kiểm soát hồi quy trong CI.
Các câu hỏi thường gặp
Một lô thực sự mất bao lâu?
OpenAI cam kết hoàn thành một lô trong vòng 24 giờ. Trong thực tế, nhiều công việc hoàn thành nhanh hơn, nhưng đảm bảo là giới hạn 24 giờ, vì vậy hãy xây dựng hệ thống của bạn dựa trên điều đó. Nếu cửa sổ đóng lại khi công việc chưa hoàn thành, lô sẽ chuyển sang trạng thái expired và chỉ những yêu cầu đã hoàn thành mới được trả về và tính phí.
Giảm giá thực sự là bao nhiêu và có cộng dồn không?
Batch API giảm giá cố định 50% so với các điểm cuối đồng bộ, cho cả token đầu vào và đầu ra. Đây là đòn bẩy chi phí lớn nhất mà OpenAI cung cấp cho các khối lượng công việc ngoại tuyến. Nếu bạn đang cố gắng phân bổ chi tiêu đó trở lại các tính năng hoặc công việc, hướng dẫn phân bổ chi phí sẽ cho bạn thấy cách phân chia nó.
Tôi có thể chạy những điểm cuối nào trong một lô?
Bạn đặt mục tiêu trong cả url của JSONL và trường endpoint của lô, và chúng phải khớp nhau. Các mục tiêu được hỗ trợ bao gồm /v1/chat/completions, /v1/responses, /v1/embeddings, /v1/completions và /v1/moderations, cùng với các điểm cuối hình ảnh và video. Kiểm tra tài liệu hiện tại để biết danh sách đầy đủ, vì OpenAI bổ sung thêm theo thời gian.
Tại sao kết quả của tôi không theo thứ tự?
Chúng không được sắp xếp, theo thiết kế. JSONL đầu ra không giữ nguyên thứ tự dòng đầu vào, đó chính xác là lý do tại sao mỗi yêu cầu cần một custom_id duy nhất. Ghép nối kết quả với đầu vào dựa trên ID đó. Nếu hai dòng có cùng một custom_id, bạn không thể phân biệt được phản hồi của chúng một cách đáng tin cậy.
Kết luận
Giờ đây bạn đã có toàn bộ quy trình: đóng gói các lời nhắc của mình vào một tệp JSONL, tải lên, tạo lô, thăm dò trạng thái và truy xuất đầu ra, tất cả chỉ với một nửa chi phí token trong vòng 24 giờ. Mỗi bước trả về một đối tượng mà bạn có thể xác minh, vì vậy một khi định dạng JSONL và vòng lặp thăm dò đã đúng, phần còn lại là tự động.
Trước khi bạn tự động hóa nó, hãy chạy vòng đời bằng tay. Tải xuống Apidog để xác thực tệp yêu cầu của bạn, thực hành các điểm cuối tải lên, tạo, thăm dò và hủy, và xác nhận các trường đối tượng lô để một dòng bị định dạng sai không bao giờ khiến bạn mất một chuyến đi khứ hồi 24 giờ.
