k
korAI
고급 전체
🔥 고급2026-05-176~8분

Batch API로 처리량 10× 확보하면서 비용 50% 절감하는 운영 전략

Anthropic Batch API의 비동기 처리 모델을 활용해 대규모 추론 워크로드의 단가를 절반으로 낮추고, 폴링·실패 복구·결과 정합성을 프로덕션 수준으로 설계하는 방법을 다룬다.

batch-apicost-optimizationthroughput

왜 Batch API인가 — 트레이드오프 먼저 이해하기

Batch API는 동기 호출 대비 비용 50% 할인을 제공하는 대신 최대 24시간의 처리 지연을 허용한다. 이 트레이드오프는 오프라인 분류, 대규모 문서 요약, 주기적 평가 파이프라인처럼 레이턴시가 비즈니스 크리티컬하지 않은 워크로드에 정확히 들어맞는다. 반대로 사용자 대화, 실시간 추천에는 적합하지 않다. 배치당 최대 10,000 요청, 요청당 최대 입력 토큰은 동기 API와 동일하므로 단일 배치 내 요청 크기를 균일하게 유지해야 폴링 효율이 높아진다.

실패 모드: 배치 일부 요청이 실패해도 배치 자체는 succeeded 상태가 된다. 결과 파일을 파싱할 때 각 라인의 error 필드를 반드시 확인해야 하며, 이를 건너뛰면 조용한 데이터 손실이 발생한다.

프로덕션 구현 — 폴링과 부분 실패 처리

import anthropic, time, json

client = anthropic.Anthropic()

# 1. 배치 생성
requests = [
    {
        "custom_id": f"doc-{i}",
        "params": {
            "model": "claude-opus-4-5",
            "max_tokens": 256,
            "messages": [{"role": "user", "content": f"Summarize: {doc}"}],
        },
    }
    for i, doc in enumerate(documents)  # documents: list[str]
]
batch = client.messages.batches.create(requests=requests)
batch_id = batch.id

# 2. 지수 백오프 폴링 (최대 24h)
delay = 60  # seconds
for _ in range(100):
    result = client.messages.batches.retrieve(batch_id)
    if result.processing_status == "ended":
        break
    time.sleep(min(delay * 1.5, 600))  # cap at 10분
    delay *= 1.5

# 3. 결과 스트리밍 파싱 + 부분 실패 수집
failed_ids = []
for item in client.messages.batches.results(batch_id):
    if item.result.type == "errored":
        failed_ids.append(item.custom_id)  # 재처리 큐 투입
    else:
        output = item.result.message.content[0].text
        persist(item.custom_id, output)  # DB 저장

if failed_ids:
    requeue(failed_ids)  # 동기 API 또는 다음 배치로 재처리

지수 백오프의 cap을 10분으로 설정하면 24시간 내 최대 약 80회 폴링으로 API 레이트 리밋을 안전하게 유지한다.

비용 계측과 운영 체크리스트

비용 계산 예시: claude-opus-4-5 동기 기준 입력 $15/MTok → Batch API $7.5/MTok. 하루 100만 요청, 평균 500 입력 토큰이면 월 절감액 약 $1,125.

운영 체크리스트

  • [ ] custom_id를 멱등 키로 설계 — 재처리 시 중복 삽입 방지
  • [ ] 배치 생성 전 요청 수 10,000 초과 여부 검증 및 청크 분할 로직 구현
  • [ ] 결과 파일을 스트리밍 파싱(results() 이터레이터 사용) — 메모리 안전
  • [ ] errored 비율 > 5% 시 알람 — 모델·스키마 문제 조기 탐지
  • [ ] 배치 ID를 DB에 영속화 — 서버 재시작 후에도 폴링 재개 가능
  • [ ] 처리 완료 후 결과 파일 TTL(~29일) 내 수집 완료 확인