요약: OpenAI Batch API는 즉시 응답이 필요 없는 대량 작업을 24시간 비동기 처리로 보내 비용을 낮추는 방식이다. 평가, 분류, 임베딩, 오프라인 생성처럼 실시간성이 낮은 작업은 동기 API 대신 Batch로 분리하는 것만으로 비용과 rate limit 압박을 줄일 수 있다.
AI 기능을 운영하다 보면 실시간 요청과 오프라인 요청이 섞인다. 사용자가 채팅창에서 답을 기다리는 요청은 즉시 처리해야 한다. 반면 기존 문서 10만 건을 분류하거나, 상품 설명을 다시 태깅하거나, 대화 로그를 평가하거나, 검색용 임베딩을 재생성하는 작업은 몇 분 또는 몇 시간이 걸려도 된다.
이런 작업을 동기 API로 처리하면 비용과 rate limit 문제가 생긴다. 워커를 많이 띄우면 제한에 걸리고, 천천히 돌리면 운영 스크립트가 복잡해진다. 실패 재시도와 결과 매핑도 직접 구현해야 한다. OpenAI Batch API는 이 영역을 위해 만들어졌다.
OpenAI 문서에 따르면 Batch API는 동기 API 대비 50% 비용 할인을 제공하고, 별도의 더 높은 rate limit pool을 사용하며, 24시간 completion window 안에서 비동기 처리한다. 사용 가능한 endpoint에는 /v1/responses, /v1/chat/completions, /v1/embeddings, /v1/moderations, 이미지, 비디오 관련 endpoint가 포함된다. 단, 모델과 endpoint 지원 여부는 문서와 model reference를 확인해야 한다.
Batch에 적합한 작업은 응답을 바로 사용자에게 보여줄 필요가 없는 작업이다. 대표적으로 eval 실행, 데이터셋 라벨링, 고객 리뷰 감성 분류, FAQ 후보 생성, 문서 요약, 임베딩 재생성, 콘텐츠 moderation backlog 처리, 대량 이미지 설명 생성이 있다. 실패해도 재시도할 수 있고, 결과를 나중에 합치면 되는 작업이 좋다.
부적합한 작업도 명확하다. 사용자 채팅 응답, 실시간 고객지원, 결제 직전 판단, 라이브 코딩 보조, 타임아웃이 짧은 API 요청은 Batch로 보내면 안 된다. Batch는 24시간 안에 완료되는 구조이므로 latency SLA가 분 단위 이하인 기능에는 맞지 않는다.
실무에서는 같은 기능 안에서도 분리가 필요하다. 예를 들어 문서 검색 서비스에서 사용자가 질문하면 검색과 답변은 동기로 처리한다. 하지만 문서 업로드 후 chunk quality 평가, 민감정보 스캔, 요약 캐시 생성, 임베딩 재생성은 Batch로 보낼 수 있다. 이렇게 나누면 사용자 경험은 유지하면서 백그라운드 비용을 낮출 수 있다.
Batch API의 흐름은 네 단계다. 먼저 각 요청을 한 줄의 JSON으로 담은 .jsonl 파일을 만든다. 각 line에는 custom_id, method, url, body가 들어간다. custom_id는 결과를 원본 데이터와 매핑하는 키이므로 반드시 안정적으로 만들어야 한다. 문서 ID, 버전, 작업 타입을 조합하는 방식이 좋다.
두 번째로 Files API에 이 JSONL 파일을 업로드한다. 세 번째로 업로드된 file id를 사용해 batch를 생성한다. 이때 endpoint와 completion window를 지정한다. 네 번째로 batch 상태를 조회하다가 completed가 되면 output file을 내려받아 각 line의 custom_id 기준으로 결과를 저장한다. 출력 순서는 입력 순서와 다를 수 있으므로 배열 index에 의존하면 안 된다.
실무에서는 이 과정을 하나의 job table로 감싸는 것이 좋다. batch_id, input_file_id, status, created_at, completed_at, source_dataset_version, error_file_id를 저장한다. 그래야 실패했을 때 어떤 데이터셋을 다시 처리해야 하는지 알 수 있다.
Batch는 비용 할인이 크지만 모든 것을 Batch로 보내면 제품이 느려진다. 추천 구조는 tier를 나누는 것이다. 사용자 대기 요청은 동기 API, 5분 이상 기다릴 수 있는 내부 작업은 queue, 1시간 이상 기다려도 되는 대량 작업은 Batch로 보낸다. 이 기준을 코드에 명시하면 팀이 비용과 latency를 일관되게 관리할 수 있다.
예를 들어 100만 개 고객 리뷰를 카테고리로 분류한다고 하자. 실시간 API로 처리하면 비용뿐 아니라 rate limit 운영이 부담된다. Batch로 보내면 24시간 내 처리라는 조건을 받아들이는 대신 50% 비용 할인과 별도 rate limit pool을 활용할 수 있다. 반면 새 리뷰가 들어온 직후 관리자 화면에 바로 보여줘야 하는 1건 분류는 동기로 처리하는 편이 낫다.
또 하나의 포인트는 모델 선택이다. 모든 batch 작업에 고성능 모델을 쓸 필요는 없다. 분류, 태깅, 단순 요약은 작은 모델로 충분할 수 있다. 중요한 것은 샘플 평가로 품질 기준을 먼저 잡고, 비용·품질·처리 시간을 비교하는 것이다.
Batch 결과에는 성공 응답과 실패 정보가 나뉘어 저장될 수 있다. 실패한 line만 다시 JSONL로 만들어 재시도하는 구조를 준비해야 한다. 전체 batch를 무조건 다시 돌리면 비용도 낭비되고 중복 결과도 생긴다. custom_id를 idempotency key처럼 쓰고, 결과 저장 시 이미 처리된 ID는 덮어쓰거나 skip하는 정책을 정한다.
입력 파일 검증도 중요하다. JSONL 한 줄이라도 잘못되면 validating 단계에서 실패할 수 있다. 업로드 전에 로컬에서 JSON parse, endpoint 통일, model 존재 여부, 최대 토큰, 금지 파라미터(stream=true 등)를 검사한다. 특히 moderation batch는 input 필드가 모든 요청에 있어야 하고, endpoint별 body 형식이 다르므로 스키마 검증이 필요하다.
대량 파일은 200MB 제한을 고려해야 한다. 멀티모달 요청에서 base64 이미지를 직접 넣으면 파일이 커진다. OpenAI 문서는 원격 asset은 image_url로 참조하는 방식을 권장한다. 내부 파일을 쓸 때도 먼저 업로드하거나 접근 가능한 URL을 만들어 batch input을 가볍게 유지하는 편이 좋다.
AI 제품을 운영한다면 매주 1만 개 샘플에 대해 품질 평가를 돌릴 수 있다. 입력에는 사용자 질문, 모델 답변, 검색 결과, 정책 문서 버전을 넣는다. Batch 요청 body에는 평가 전용 프롬프트와 structured output schema를 넣어 정확성, 근거성, 정책 위반, 불필요한 장문 여부를 점수화한다.
완료 후 결과를 warehouse에 저장하고, 대시보드에서 모델 버전별 점수 추이를 본다. 특정 카테고리에서 점수가 떨어지면 샘플을 사람이 리뷰한다. 이 방식은 사용자 요청 path를 느리게 만들지 않으면서도 지속적인 품질 관리를 가능하게 한다.
custom_id를 넣는다.custom_id로 매핑한다.출처: OpenAI API Docs, Batch API; OpenAI API Pricing.