AI API 활용

Claude API 메시지 배치로 대량 요청을 비동기 처리한 방법 - 공식 문서 기준으로 정리한 기록

소개왕 탑백귀 2026. 7. 15. 20:07

Claude API 메시지 배치로 대량 요청을 비동기 처리한 방법 - 공식 문서 기준으로 정리한 기록

AI API 활용

공식 문서와 실제 사용 경험을 기준으로 정리했습니다.

수백~수천 건의 요청을 한 건씩 실시간으로 보내다 보면, 응답을 기다리는 시간도 길고 비용도 부담스럽습니다. 메시지 배치(Message Batches)는 여러 요청을 한꺼번에 제출해 두고 비동기로 처리한 뒤 나중에 결과를 수거하는 방식입니다. 실시간 응답이 필요하지 않은 대량 작업에 적합하고, 표준 가격보다 저렴하게 처리할 수 있습니다. 이 글은 메시지 배치가 어떤 흐름으로 동작하고, 어떻게 만들고 결과를 받는지, 언제 쓰면 좋은지를 공식 문서를 기준으로 정리한 기록입니다. 수치와 세부 동작은 모델·버전에 따라 달라질 수 있으니 본문 끝의 공식 문서를 함께 확인하시길 권합니다.

핵심 개념 — 한꺼번에 맡기고, 나중에 받는다

일반적인 API 호출은 요청 하나를 보내고 응답을 바로 기다립니다. 반면 배치는 여러 요청을 한 묶음으로 제출한 뒤, 즉시 응답을 받는 대신 처리가 끝날 때까지 기다렸다가 결과를 한 번에 가져옵니다. 이 "비동기" 특성 덕분에 세 가지 이점이 생깁니다.

  • 표준 가격보다 저렴 — 공식 문서 기준으로 토큰 사용 비용이 표준 대비 50% 수준입니다.
  • 대량 처리에 유리 — 한 배치에 아주 많은 요청을 담아 한꺼번에 맡길 수 있습니다.
  • 결과 식별이 명확 — 각 요청에 custom_id를 붙여 두면, 나중에 그 값으로 결과를 정확히 찾아올 수 있습니다.

배치를 만드는 법 — batches.create

요청 목록을 만들어 client.messages.batches.create에 넘깁니다. 각 요청은 고유한 custom_id와 실제 메시지 파라미터(params)로 구성합니다.

from anthropic import Anthropic
from anthropic.types.message_create_params import MessageCreateParamsNonStreaming
from anthropic.types.messages.batch_create_params import Request

client = Anthropic()

batch = client.messages.batches.create(
    requests=[
        Request(
            custom_id="req-1",
            params=MessageCreateParamsNonStreaming(
                model="claude-opus-4-8",
                max_tokens=1024,
                messages=[{"role": "user", "content": "기후 변화 영향을 요약해줘"}],
            ),
        ),
        # 필요한 만큼 요청을 더 추가
    ]
)
print(batch.id, batch.processing_status)

처리 상태 확인 — 끝날 때까지 폴링

배치를 제출했다고 결과가 바로 나오는 것은 아닙니다. batches.retrieve로 상태를 확인하면서 processing_status"ended"가 될 때까지 기다립니다.

import time

while True:
    batch = client.messages.batches.retrieve(batch.id)
    if batch.processing_status == "ended":
        break
    time.sleep(60)  # 1분 간격으로 확인

공식 문서 기준으로 대부분의 배치는 1시간 안에 끝나고, 최대 처리 시간은 24시간입니다. 그래서 배치는 "지금 당장 답이 필요한" 작업이 아니라, 어느 정도 기다릴 수 있는 대량 작업에 어울립니다.

결과 수거 — custom_id로 맞춘다

처리가 끝나면 batches.results로 결과를 하나씩 순회합니다. 각 결과에는 제출할 때 넣었던 custom_id와 처리 유형(result.type)이 담겨 있습니다.

for result in client.messages.batches.results(batch.id):
    if result.result.type == "succeeded":
        msg = result.result.message
        text = next((b.text for b in msg.content if b.type == "text"), "")
        print(result.custom_id, text[:80])
    elif result.result.type == "errored":
        print(result.custom_id, "오류 — 재시도 검토")

처리 유형은 succeeded(성공) 외에도 errored(오류), canceled(취소), expired(만료)가 있습니다. 유형을 확인해 성공 결과만 사용하고, 오류·만료 건은 따로 재시도하도록 처리하면 됩니다.

한도와 특성

항목내용(공식 문서 기준)
배치 크기최대 10만 요청 또는 256MB
처리 시간대개 1시간 내, 최대 24시간
결과 보관생성 후 29일
비용표준 가격의 50% 수준
지원 기능비전·툴·프롬프트 캐싱 등 Messages API 기능 지원

배치도 일반 요청과 같은 기능을 그대로 쓸 수 있어서, 예를 들어 여러 요청이 같은 긴 시스템 지침을 공유한다면 프롬프트 캐싱을 함께 적용해 처리 비용을 더 줄일 수 있습니다.

흔한 실수 — 결과는 순서를 보장하지 않는다

가장 자주 겪는 함정은 "제출한 순서대로 결과가 온다"고 가정하는 것입니다. 실제로는 결과가 임의의 순서로 도착합니다. 따라서 결과를 목록의 위치(첫 번째, 두 번째…)로 맞추면 어긋납니다. 반드시 custom_id를 키로 삼아 매칭해야 합니다.

제출할 때 각 요청에 의미 있는 custom_id(예: 사용자 ID, 문서 번호)를 부여해 두면, 결과를 받아 원래 요청과 짝짓기가 쉬워집니다. 위치 기반 매칭은 피하세요.

언제 쓰면 좋고, 언제 안 좋은가

  • 잘 맞는 경우 — 대량 문서 요약·분류·추출처럼 즉답이 필요 없고 어느 정도 기다릴 수 있는 작업. 비용을 아끼면서 한꺼번에 처리하고 싶을 때.
  • 안 맞는 경우 — 사용자가 화면 앞에서 즉시 답을 기다리는 실시간 챗봇처럼 지연이 곧 문제인 작업. 이럴 땐 일반 요청(필요하면 스트리밍)이 낫습니다.

자주 묻는 질문

Q. 결과가 제출한 순서와 다르게 나와요.

정상입니다. 배치 결과는 순서를 보장하지 않으므로, 위치가 아니라 custom_id로 원래 요청과 맞춰야 합니다. 제출 시 요청마다 고유한 custom_id를 넣어 두세요.

Q. 배치 처리는 얼마나 걸리나요?

공식 문서 기준으로 대부분 1시간 안에 끝나며, 최대 처리 시간은 24시간입니다. 상태를 processing_status로 확인하다가 "ended"가 되면 결과를 수거하면 됩니다.

Q. 실시간 응답이 필요한 서비스에도 쓸 수 있나요?

권장하지 않습니다. 배치는 결과를 나중에 받는 비동기 방식이라, 사용자가 즉시 답을 기다리는 상황에는 맞지 않습니다. 그런 경우엔 일반 요청을 사용하세요.

마무리

정리하면, 메시지 배치는 "많은 요청을 한꺼번에 맡기고, 처리가 끝나면 custom_id로 결과를 수거한다"는 단순한 흐름 위에서 동작합니다. 제출(create) → 상태 확인(retrieve) → 결과 수거(results)의 세 단계를 지키고, 결과는 순서가 아닌 custom_id로 맞추는 것 — 이 두 가지만 기억하면 즉답이 필요 없는 대량 작업을 더 저렴하게 처리할 수 있었습니다. 반대로 실시간 응답이 중요한 작업이라면 배치보다 일반 요청이 맞다는 점도 함께 기억해 두면 좋습니다.

이 글의 수치와 동작 설명은 Claude API 공식 문서를 기준으로 정리했습니다. 가격·한도 등 세부 사항은 모델과 시점에 따라 달라질 수 있으니, 최신 내용은 공식 문서에서 직접 확인하시길 권합니다.

※ 본 글은 공개된 공식 문서와 개인적인 사용 경험을 바탕으로 정리한 정보성 콘텐츠입니다. API의 기능·가격·수치는 모델과 시점에 따라 달라질 수 있으며, 특정 비용 절감 결과를 보장하지 않습니다.