이 가이드가 끝나면 OpenAI 배치 API를 호출하여 수천 개의 모델 요청을 단일 비동기 작업으로 실행하고 모든 결과를 50% 할인된 가격으로 다시 가져올 수 있게 됩니다. 프롬프트를 JSONL 파일로 패키징하고, 하나의 배치를 제출하고, 완료될 때까지 폴링하고, 출력을 다운로드한 다음, 프로덕션에 연결하기 전에 Apidog에서 각 단계를 테스트할 것입니다. 작업이 더 상호적이라면 동기 경로가 더 적합하며, 그 대신 Apidog로 ChatGPT API를 테스트할 수 있습니다.
배치 API란 무엇이며 언제 사용해야 할까요?
배치 API는 지연을 허용하는 대량의 모델 호출을 위한 비동기 엔드포인트입니다. 프롬프트당 하나의 HTTP 요청 대신, 많은 요청을 단일 JSONL 파일로 묶어 하나의 작업으로 제출하고 완료를 폴링합니다. OpenAI는 비수기 시간에 작업을 실행하고 출력 파일에 모든 결과를 반환합니다.
두 가지 구체적인 이점을 얻을 수 있습니다. 첫째, 동기 API 대비 입력 및 출력 토큰 모두에서 50%의 고정 할인. 둘째, 배치 작업은 별도의 속도 제한 풀을 사용하고 실시간 트래픽과 경쟁하지 않으므로 처리량이 더 높습니다. 단점은 지연 시간입니다. OpenAI는 24시간 이내에 완료할 것을 약속합니다. 많은 작업이 더 빨리 완료되지만, 그것을 확신할 수는 없습니다.
작업이 오프라인이고 대량 형태일 때 배치 처리를 사용하세요:
- 기록 백로그 분류 또는 태그 지정
- 전체 코퍼스에 대한 임베딩 생성
- 대량 콘텐츠 생성(제품 설명, 요약, 번역)
- 데이터셋에 대한 평가 스위트 또는 모델 비교 실행
사용자가 기다리는 모든 것에는 건너뛰세요. 채팅 UI, 자동 완성, 라이브 에이전트는 동기식 엔드포인트가 필요합니다. 한 번에 여러 모델 또는 에이전트 구성을 생성하는 경우 배치 처리가 해당 워크로드와 잘 맞습니다. 배치 처리로 100개 이상의 에이전트 구성 생성에 대한 가이드에서 자세한 내용을 확인하세요.
시작하기 전에 필요한 것
전체 흐름은 두 개의 엔드포인트(/v1/files 및 /v1/batches)와 네 단계를 포함합니다. 호출을 살펴보기 전에 대략적인 형태를 먼저 보겠습니다.
| 단계 | 엔드포인트 | 수행되는 작업 |
|---|---|---|
| 1. 업로드 | POST /v1/files |
purpose: "batch"와 함께 .jsonl 파일을 전송하고, 파일 ID를 반환받습니다 |
| 2. 생성 | POST /v1/batches |
엔드포인트와 완료 기간과 함께 파일 ID를 제출합니다 |
| 3. 폴링 | GET /v1/batches/{id} |
status가 completed가 될 때까지 확인합니다 |
| 4. 검색 | GET /v1/files/{id}/content |
output_file_id를 통해 결과를 다운로드합니다 |
따라하려면 OPENAI_API_KEY로 내보낸 OpenAI API 키, 요청이 포함된 JSONL 파일, 그리고 호출을 실행하고 검사할 도구가 필요합니다. 각 단계는 확인할 수 있는 객체를 반환하므로 전체 수명 주기를 테스트하기 쉽습니다.
1단계: JSONL 파일 구축 및 업로드
입력은 각 줄이 하나의 독립적인 요청인 JSONL 파일입니다. 각 줄에는 네 가지 필드가 필요합니다: 직접 선택하는 custom_id(결과를 입력과 일치시킬 수 있도록), method(POST), url(/v1/chat/completions와 같은 대상 엔드포인트), 그리고 실제 요청 매개변수를 포함하는 body.
{"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는 파일 내에서 고유해야 합니다. 결과는 순서가 보장되지 않으므로, 그 ID가 각 응답을 해당 원본 행에 다시 연결하는 방법입니다. 단일 배치는 최대 50,000개의 요청을 담을 수 있으며 파일은 최대 200MB까지 가능합니다.
batch 용도로 파일 API에 업로드하세요:
curl https://api.openai.com/v1/files \
-H "Authorization: Bearer $OPENAI_API_KEY" \
-F purpose="batch" \
-F file="@requests.jsonl"
응답은 파일 id(예: file-abc123)를 반환합니다. 이것이 다음 단계에서 사용할 input_file_id입니다.
2단계: 배치 생성
이제 작업을 생성합니다. input_file_id, 대상 endpoint, 그리고 completion_window를 전달합니다. 현재 completion_window는 단일 값인 "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"}
}'
endpoint 필드는 JSONL 줄 내에서 사용된 url과 일치해야 합니다. 지원되는 대상에는 /v1/chat/completions, /v1/responses, /v1/embeddings, /v1/completions, /v1/moderations 등이 포함됩니다. 선택적 metadata 객체는 최대 16개의 키-값 쌍을 포함할 수 있으며, 나중에 필터링할 작업을 태그 지정하는 데 유용합니다.
호출은 배치 객체를 반환합니다. 가장 중요한 필드는 다음과 같습니다:
{
"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" }
}
3단계: 배치 상태 폴링
새로운 배치는 validating으로 시작합니다. 거기서부터 문서화된 상태 세트를 통해 진행됩니다. GET /v1/batches/{batch_id}를 폴링하고 status 필드를 읽으세요.
| 상태 | 의미 |
|---|---|
validating |
실행이 시작되기 전에 입력 파일을 확인 중입니다 |
in_progress |
요청이 처리 중입니다 |
finalizing |
실행이 완료되었고 출력 파일이 준비 중입니다 |
completed |
완료; 결과를 다운로드할 준비가 되었습니다 |
failed |
유효성 검사 실패; 아무것도 실행되지 않았습니다 |
expired |
모든 요청이 완료되기 전에 24시간 기간이 마감되었습니다 |
cancelling / cancelled |
취소를 요청했습니다 |
request_counts 객체(total, completed, failed)는 상태가 in_progress일 때 실시간 진행 상황을 제공합니다. 여기서는 기다릴 웹훅이 없으므로, 적절한 간격(매초가 아닌 몇 분마다)으로 폴링하는 것이 올바른 패턴입니다. 실수로 제출한 경우 POST /v1/batches/{batch_id}/cancel을 사용하여 실행 중인 작업을 취소할 수도 있습니다.
4단계: 출력 검색
status가 completed로 읽히면 배치 객체는 output_file_id를 가집니다. 파일 API를 통해 해당 파일의 내용을 다운로드하세요:
curl https://api.openai.com/v1/files/file-output456/content \
-H "Authorization: Bearer $OPENAI_API_KEY" > results.jsonl
출력은 다시 JSONL이며, 요청당 한 줄입니다. 각 줄은 설정한 custom_id와 상태 코드 및 본문을 포함하는 response 객체를 반영합니다. 오류가 발생한 요청은 error_file_id로 참조되는 파일에 나타나므로 둘 다 확인하십시오. custom_id를 기준으로 결과를 입력과 일치시키세요. 줄 순서로 일치시키지 마십시오.
비용 및 기간 절충 고려
계산은 간단합니다. 토큰 비용을 50% 절약하고 최대 24시간의 처리 시간을 허용합니다. 일회성 백필 또는 야간 작업의 경우 쉬운 결정입니다. 제품의 중요한 경로에 있는 기능의 경우 그렇지 않습니다.
몇 가지 실용적인 참고 사항:
- 할인은 지원되는 모델 전체에 걸쳐 입력 및 출력 토큰 모두에 적용됩니다.
- 24시간 기간은 목표가 아니라 상한선입니다. 최악의 경우를 대비하세요. 작업이
expired상태가 되면 완료된 요청은 계속 청구되고 반환되며 나머지는 그렇지 않습니다. - 배치 작업은 별도의 대기열 토큰 제한에서 가져오므로 대량 배치는 실시간 트래픽이 의존하는 속도 제한을 잠식하지 않습니다. 이미 한도에 부딪히고 있다면, GPT API 속도 제한 및 테스트 방법에 대한 가이드가 동기식 측면을 다룹니다.
- 반값 토큰도 대량으로 쌓이면 비용이 커집니다. 나중에 비용을 할당할 수 있도록
metadata태그를 사용하여 작업당 지출을 추적하세요. 여기에 OpenAI 지출에 대한 비용 할당 플레이북이 있습니다.
Apidog에서 테스트하는 방법
배치 API는 파일, JSONL 형식, 폴링 루프 등 여러 곳에서 오류가 발생할 수 있으므로 단일 채팅 호출보다 오류가 발생하기 쉽습니다. 50,000개 요청 파일의 잘못된 줄 하나가 전체 업로드를 실패하게 만들 수 있으며, 유효성 검사가 실행될 때까지는 알 수 없습니다. 자동화하기 전에 수명 주기 엔드포인트를 테스트하면 이러한 왕복 시간을 절약할 수 있습니다.
Apidog는 각 단계를 요청으로 실행하고, 연결하며, 응답을 확인할 수 있는 API 플랫폼입니다. 엔드포인트를 테스트하고 모의합니다. OpenAI SDK는 아닙니다. 현실적인 설정은 다음과 같습니다:
- JSONL 형식을 먼저 검증합니다. 아무것도 업로드하기 전에 각 줄에
custom_id,method,url,body가 있고,body.model과 메시지가 있는지 확인합니다. 로컬에서 누락된 필드를 발견하는 것이 실패한 배치보다 저렴합니다. - 멀티파트 업로드를 실행합니다.
purpose=batch및 파일을 사용하여POST /v1/files를 보내고, 반환된id를 환경 변수에 캡처합니다. - 배치를 생성하고 객체를 확인합니다.
POST /v1/batches를 실행한 다음,status가validating이고endpoint가 보낸 내용과 일치하는지 확인합니다. Apidog의 시각적 확인 기능을 사용하면 스크립트를 작성하지 않고도 해당 필드를 확인할 수 있습니다. - 폴링 및 검색. 루프에서
GET /v1/batches/{id}를 호출하고,status가completed가 되면 확인한 다음,output_file_id를 가져와 결과를 다운로드합니다. - 취소 및 오류 경로를 연습합니다. 의도적으로 손상된 파일을 제출하고
failed상태를 받는지 확인하며,POST /v1/batches/{id}/cancel을 테스트하여 오류 처리가 가정된 것이 아니라 실제인지 확인합니다.
출력 파일이 나중에 도착하므로, 샘플 완성 배치 객체와 미리 준비된 결과 파일을 반환하는 모의 API를 설정할 수도 있습니다. 이렇게 하면 실제 24시간 작업을 기다리거나 개발 중에 토큰을 소모하지 않고 검색 및 구문 분석 로직을 구축하고 테스트할 수 있습니다. 팀이 사양 우선으로 작업하는 경우 OpenAPI 사양에서 직접 테스트 컬렉션을 생성하고 CI에서 배치 엔드포인트를 회귀 테스트 범위에 유지할 수도 있습니다.
자주 묻는 질문
실제로 배치는 얼마나 걸리나요?
OpenAI는 24시간 이내에 배치를 완료할 것을 약속합니다. 실제로 많은 작업이 더 빨리 완료되지만, 보장은 24시간 상한선이므로 이에 맞춰 시스템을 구축하세요. 작업이 완료되지 않은 채 기간이 마감되면 배치는 expired 상태로 이동하고 완료된 요청만 반환되고 청구됩니다.
실제 할인은 어느 정도이며 중복 적용되나요?
배치 API는 동기식 엔드포인트 대비 입력 및 출력 토큰 모두에서 50%의 고정 할인을 제공합니다. 이는 OpenAI가 오프라인 워크로드에 대해 제공하는 가장 큰 비용 절감 수단입니다. 해당 지출을 기능이나 작업에 다시 할당하려는 경우, 비용 할당 플레이북에서 분할 방법을 보여줍니다.
배치에서 어떤 엔드포인트를 실행할 수 있나요?
JSONL url과 배치 endpoint 필드 모두에서 대상을 설정해야 하며, 이들은 일치해야 합니다. 지원되는 대상에는 /v1/chat/completions, /v1/responses, /v1/embeddings, /v1/completions, /v1/moderations, 그리고 이미지 및 비디오 엔드포인트가 포함됩니다. OpenAI가 시간이 지남에 따라 추가하므로 전체 목록은 현재 문서를 확인하세요.
내 결과는 왜 순서가 뒤죽박죽인가요?
의도적으로 순서가 지정되지 않습니다. 출력 JSONL은 입력 줄 순서를 유지하지 않으며, 이것이 바로 모든 요청에 고유한 custom_id가 필요한 이유입니다. 해당 ID를 기준으로 결과를 입력과 일치시키세요. 두 줄이 custom_id를 공유하면 응답을 안정적으로 구분할 수 없습니다.
결론
이제 전체 흐름을 알게 되었습니다. 프롬프트를 JSONL 파일로 묶고, 업로드하고, 배치를 생성하고, 상태를 폴링하고, 출력을 검색하는 모든 과정을 24시간 이내에 토큰 비용의 절반으로 할 수 있습니다. 각 단계는 확인할 수 있는 객체를 반환하므로, JSONL 형식과 폴링 루프가 올바르게 설정되면 나머지는 기계적입니다.
자동화하기 전에 수동으로 수명 주기를 실행해보세요. Apidog를 다운로드하여 요청 파일을 검증하고, 업로드, 생성, 폴링, 취소 엔드포인트를 연습하며, 배치 객체 필드를 확인하여 잘못된 줄 하나로 24시간 왕복하는 일이 없도록 하세요.
