오픈AI 배치 API 사용법

OpenAI 배치 API 배우기: JSONL 파일 업로드, 배치 생성, 상태 폴링, 그리고 50% 할인된 가격으로 결과물 가져오는 방법과 Apidog에서 모든 엔드포인트를 테스트하는 방법까지.

Ashley Innocent

Ashley Innocent

25 June 2026

오픈AI 배치 API 사용법

Apidog 엔터프라이즈

온프레미스 배포

SSO & RBAC

SOC 2 준수

Apidog Enterprise 살펴보기

이 가이드가 끝나면 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} statuscompleted가 될 때까지 확인합니다
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단계: 출력 검색

statuscompleted로 읽히면 배치 객체는 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시간의 처리 시간을 허용합니다. 일회성 백필 또는 야간 작업의 경우 쉬운 결정입니다. 제품의 중요한 경로에 있는 기능의 경우 그렇지 않습니다.

몇 가지 실용적인 참고 사항:

Apidog에서 테스트하는 방법

배치 API는 파일, JSONL 형식, 폴링 루프 등 여러 곳에서 오류가 발생할 수 있으므로 단일 채팅 호출보다 오류가 발생하기 쉽습니다. 50,000개 요청 파일의 잘못된 줄 하나가 전체 업로드를 실패하게 만들 수 있으며, 유효성 검사가 실행될 때까지는 알 수 없습니다. 자동화하기 전에 수명 주기 엔드포인트를 테스트하면 이러한 왕복 시간을 절약할 수 있습니다.

Apidog는 각 단계를 요청으로 실행하고, 연결하며, 응답을 확인할 수 있는 API 플랫폼입니다. 엔드포인트를 테스트하고 모의합니다. OpenAI SDK는 아닙니다. 현실적인 설정은 다음과 같습니다:

출력 파일이 나중에 도착하므로, 샘플 완성 배치 객체와 미리 준비된 결과 파일을 반환하는 모의 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시간 왕복하는 일이 없도록 하세요.

버튼

Apidog에서 API 설계-첫 번째 연습

API를 더 쉽게 구축하고 사용하는 방법을 발견하세요