OpenAI Batch API로 대량 임베딩 비용 50% 절감하기

문제 상황

사내 문서 검색 시스템에 RAG를 적용하면서 약 50만 개의 문서를 임베딩해야 했다. 실시간 API로 처리하니 비용이 예상보다 2배 이상 나왔고, rate limit 때문에 처리 시간도 오래 걸렸다.

Batch API 도입

OpenAI Batch API는 50% 할인된 가격으로 비동기 처리를 제공한다. 24시간 내 완료를 보장하며, rate limit도 별도로 적용된다.

import fs from 'fs';
import OpenAI from 'openai';

const client = new OpenAI();

// JSONL 형식으로 배치 요청 생성
const requests = documents.map((doc, idx) => ({
  custom_id: `req-${idx}`,
  method: 'POST',
  url: '/v1/embeddings',
  body: {
    model: 'text-embedding-3-small',
    input: doc.content
  }
}));

const jsonl = requests.map(r => JSON.stringify(r)).join('\n');
fs.writeFileSync('batch_input.jsonl', jsonl);

// 배치 업로드 및 실행
const file = await client.files.create({
  file: fs.createReadStream('batch_input.jsonl'),
  purpose: 'batch'
});

const batch = await client.batches.create({
  input_file_id: file.id,
  endpoint: '/v1/embeddings',
  completion_window: '24h'
});

// 상태 확인
while (true) {
  const status = await client.batches.retrieve(batch.id);
  if (status.status === 'completed') {
    const result = await client.files.content(status.output_file_id);
    break;
  }
  await new Promise(resolve => setTimeout(resolve, 60000));
}

결과

  • 비용: $120 → $60 (50% 절감)
  • 처리 시간: rate limit 회피로 안정적 처리
  • 재처리 용이: custom_id로 실패 건 추적 가능

급하지 않은 대량 작업은 Batch API가 확실히 효율적이었다. 다만 결과가 나올 때까지 기다려야 하므로, 실시간 응답이 필요한 케이스와는 구분해서 사용해야 한다.