배치 처리는 대량의 요청을 효율적으로 처리하기 위한 강력한 방식입니다. 요청을 한 번에 하나씩 처리하고 즉시 응답을 받는 대신, 배치 처리를 사용하면 여러 요청을 함께 제출하여 비동기적으로 처리할 수 있습니다. 이 패턴은 다음과 같은 경우에 특히 유용합니다:
Message Batches API는 이 패턴의 첫 번째 구현입니다.
Message Batches API는 Messages 요청의 대량을 비동기적으로 처리하는 강력하고 비용 효율적인 방식입니다. 이 방식은 즉시 응답이 필요하지 않은 작업에 적합하며, 대부분의 배치는 1시간 이내에 완료되면서 비용을 50% 절감하고 처리량을 증가시킵니다.
이 가이드 외에도 API 참조를 직접 살펴볼 수 있습니다.
Message Batches API에 요청을 보낼 때:
이는 다음과 같이 즉시 결과가 필요하지 않은 대량 작업에 특히 유용합니다:
모든 활성 모델은 Message Batches API를 지원합니다.
Messages API에 대해 수행할 수 있는 모든 요청을 배치에 포함할 수 있습니다. 여기에는 다음이 포함됩니다:
배치의 각 요청은 독립적으로 처리되므로 단일 배치 내에서 다양한 유형의 요청을 혼합할 수 있습니다.
배치는 5분 이상 처리될 수 있으므로, 배치 처리 시 공유 컨텍스트를 사용할 때 더 나은 캐시 히트율을 위해 프롬프트 캐싱과 함께 1시간 캐시 지속 시간을 사용하는 것을 고려하세요.
Batches API는 상당한 비용 절감을 제공합니다. 모든 사용량은 표준 API 가격의 50%로 청구됩니다.
| Model | Batch input | Batch output |
|---|---|---|
| Claude Opus 4.5 | $2.50 / MTok | $12.50 / MTok |
| Claude Opus 4.1 | $7.50 / MTok | $37.50 / MTok |
| Claude Opus 4 | $7.50 / MTok | $37.50 / MTok |
| Claude Sonnet 4.5 | $1.50 / MTok | $7.50 / MTok |
| Claude Sonnet 4 | $1.50 / MTok | $7.50 / MTok |
| Claude Sonnet 3.7 (deprecated) | $1.50 / MTok | $7.50 / MTok |
| Claude Haiku 4.5 | $0.50 / MTok | $2.50 / MTok |
| Claude Haiku 3.5 | $0.40 / MTok | $2 / MTok |
| Claude Opus 3 (deprecated) | $7.50 / MTok | $37.50 / MTok |
| Claude Haiku 3 | $0.125 / MTok | $0.625 / MTok |
Message Batch는 Message를 생성하기 위한 요청 목록으로 구성됩니다. 개별 요청의 형태는 다음으로 구성됩니다:
custom_idparams 객체requests 매개변수에 이 목록을 전달하여 배치를 생성할 수 있습니다:
curl https://api.anthropic.com/v1/messages/batches \
--header "x-api-key: $ANTHROPIC_API_KEY" \
--header "anthropic-version: 2023-06-01" \
--header "content-type: application/json" \
--data \
'{
"requests": [
{
"custom_id": "my-first-request",
"params": {
"model": "claude-sonnet-4-5",
"max_tokens": 1024,
"messages": [
{"role": "user", "content": "Hello, world"}
]
}
},
{
"custom_id": "my-second-request",
"params": {
"model": "claude-sonnet-4-5",
"max_tokens": 1024,
"messages": [
{"role": "user", "content": "Hi again, friend"}
]
}
}
]
}'이 예제에서는 두 개의 별도 요청이 비동기 처리를 위해 함께 배치됩니다. 각 요청에는 고유한 custom_id가 있고 Messages API 호출에 사용할 표준 매개변수를 포함합니다.
Messages API로 배치 요청 테스트
각 메시지 요청의 params 객체 검증은 비동기적으로 수행되며, 검증 오류는 전체 배치의 처리가 끝났을 때 반환됩니다. Messages API로 요청 형태를 먼저 확인하여 입력을 올바르게 구성하고 있는지 확인할 수 있습니다.
배치가 처음 생성될 때 응답은 in_progress의 처리 상태를 갖습니다.
{
"id": "msgbatch_01HkcTjaV5uDC8jWR4ZsDV8d",
"type": "message_batch",
"processing_status": "in_progress",
"request_counts": {
"processing": 2,
"succeeded": 0,
"errored": 0,
"canceled": 0,
"expired": 0
},
"ended_at": null,
"created_at": "2024-09-24T18:37:24.100435Z",
"expires_at": "2024-09-25T18:37:24.100435Z",
"cancel_initiated_at": null,
"results_url": null
}Message Batch의 processing_status 필드는 배치가 처리 중인 단계를 나타냅니다. in_progress로 시작하여 배치의 모든 요청이 처리를 완료하고 결과가 준비되면 ended로 업데이트됩니다. Console을 방문하거나 검색 엔드포인트를 사용하여 배치의 상태를 모니터링할 수 있습니다.
Message Batch를 폴링하려면 배치 생성 시 응답에 제공되거나 배치를 나열하여 얻을 수 있는 id가 필요합니다. 처리가 끝날 때까지 주기적으로 배치 상태를 확인하는 폴링 루프를 구현할 수 있습니다:
import anthropic
import time
client = anthropic.Anthropic()
message_batch = None
while True:
message_batch = client.messages.batches.retrieve(
MESSAGE_BATCH_ID
)
if message_batch.processing_status == "ended":
break
print(f"Batch {MESSAGE_BATCH_ID} is still processing...")
time.sleep(60)
print(message_batch)list 엔드포인트를 사용하여 Workspace의 모든 Message Batches를 나열할 수 있습니다. API는 페이지 매김을 지원하며 필요에 따라 자동으로 추가 페이지를 가져옵니다:
import anthropic
client = anthropic.Anthropic()
# Automatically fetches more pages as needed.
for message_batch in client.messages.batches.list(
limit=20
):
print(message_batch)배치 처리가 끝나면 배치의 각 Messages 요청에는 결과가 있습니다. 4가지 결과 유형이 있습니다:
| 결과 유형 | 설명 |
|---|---|
succeeded | 요청이 성공했습니다. 메시지 결과를 포함합니다. |
errored | 요청에 오류가 발생했고 메시지가 생성되지 않았습니다. 가능한 오류에는 잘못된 요청과 내부 서버 오류가 포함됩니다. 이러한 요청에 대해서는 청구되지 않습니다. |
canceled | 사용자가 이 요청을 모델로 보낼 수 있기 전에 배치를 취소했습니다. 이러한 요청에 대해서는 청구되지 않습니다. |
expired | 배치가 이 요청을 모델로 보낼 수 있기 전에 24시간 만료에 도달했습니다. 이러한 요청에 대해서는 청구되지 않습니다. |
배치의 request_counts로 결과의 개요를 볼 수 있으며, 이는 각 4가지 상태에 도달한 요청의 수를 보여줍니다.
배치의 결과는 Message Batch의 results_url 속성에서 다운로드할 수 있으며, 조직 권한이 허용하면 Console에서도 사용 가능합니다. 결과의 잠재적으로 큰 크기로 인해 모든 결과를 한 번에 다운로드하는 대신 결과를 스트리밍하는 것이 좋습니다.
#!/bin/sh
curl "https://api.anthropic.com/v1/messages/batches/msgbatch_01HkcTjaV5uDC8jWR4ZsDV8d" \
--header "anthropic-version: 2023-06-01" \
--header "x-api-key: $ANTHROPIC_API_KEY" \
| grep -o '"results_url":[[:space:]]*"[^"]*"' \
| cut -d'"' -f4 \
| while read -r url; do
curl -s "$url" \
--header "anthropic-version: 2023-06-01" \
--header "x-api-key: $ANTHROPIC_API_KEY" \
| sed 's/}{/}\n{/g' \
| while IFS= read -r line
do
result_type=$(echo "$line" | sed -n 's/.*"result":[[:space:]]*{[[:space:]]*"type":[[:space:]]*"\([^"]*\)".*/\1/p')
custom_id=$(echo "$line" | sed -n 's/.*"custom_id":[[:space:]]*"\([^"]*\)".*/\1/p')
error_type=$(echo "$line" | sed -n 's/.*"error":[[:space:]]*{[[:space:]]*"type":[[:space:]]*"\([^"]*\)".*/\1/p')
case "$result_type" in
"succeeded")
echo "Success! $custom_id"
;;
"errored")
if [ "$error_type" = "invalid_request" ]; then
# Request body must be fixed before re-sending request
echo "Validation error: $custom_id"
else
# Request can be retried directly
echo "Server error: $custom_id"
fi
;;
"expired")
echo "Expired: $line"
;;
esac
done
done
결과는 .jsonl 형식으로 제공되며, 각 줄은 Message Batch의 단일 요청 결과를 나타내는 유효한 JSON 객체입니다. 스트리밍된 각 결과에 대해 custom_id와 결과 유형에 따라 다른 작업을 수행할 수 있습니다. 다음은 결과 집합의 예입니다:
{"custom_id":"my-second-request","result":{"type":"succeeded","message":{"id":"msg_014VwiXbi91y3JMjcpyGBHX5","type":"message","role":"assistant","model":"claude-sonnet-4-5-20250929","content":[{"type":"text","text":"Hello again! It's nice to see you. How can I assist you today? Is there anything specific you'd like to chat about or any questions you have?"}],"stop_reason":"end_turn","stop_sequence":null,"usage":{"input_tokens":11,"output_tokens":36}}}}
{"custom_id":"my-first-request","result":{"type":"succeeded","message":{"id":"msg_01FqfsLoHwgeFbguDgpz48m7","type":"message","role":"assistant","model":"claude-sonnet-4-5-20250929","content":[{"type":"text","text":"Hello! How can I assist you today? Feel free to ask me any questions or let me know if there's anything you'd like to chat about."}],"stop_reason":"end_turn","stop_sequence":null,"usage":{"input_tokens":10,"output_tokens":34}}}}결과에 오류가 있으면 result.error가 표준 오류 형태로 설정됩니다.
배치 결과는 입력 순서와 일치하지 않을 수 있습니다
배치 결과는 어떤 순서로든 반환될 수 있으며, 배치가 생성될 때 요청의 순서와 일치하지 않을 수 있습니다. 위의 예에서 두 번째 배치 요청의 결과가 첫 번째보다 먼저 반환됩니다. 결과를 해당 요청과 올바르게 일치시키려면 항상 custom_id 필드를 사용하세요.
취소 엔드포인트를 사용하여 현재 처리 중인 Message Batch를 취소할 수 있습니다. 취소 직후 배치의 processing_status는 canceling이 됩니다. 위에서 설명한 동일한 폴링 기법을 사용하여 취소가 완료될 때까지 기다릴 수 있습니다. 취소된 배치는 ended 상태로 끝나며 취소 전에 처리된 요청에 대한 부분 결과를 포함할 수 있습니다.
import anthropic
client = anthropic.Anthropic()
message_batch = client.messages.batches.cancel(
MESSAGE_BATCH_ID,
)
print(message_batch)응답은 배치가 canceling 상태임을 보여줍니다:
{
"id": "msgbatch_013Zva2CMHLNnXjNJJKqJ2EF",
"type": "message_batch",
"processing_status": "canceling",
"request_counts": {
"processing": 2,
"succeeded": 0,
"errored": 0,
"canceled": 0,
"expired": 0
},
"ended_at": null,
"created_at": "2024-09-24T18:37:24.100435Z",
"expires_at": "2024-09-25T18:37:24.100435Z",
"cancel_initiated_at": "2024-09-24T18:39:03.114875Z",
"results_url": null
}Message Batches API는 프롬프트 캐싱을 지원하므로 배치 요청의 비용과 처리 시간을 잠재적으로 줄일 수 있습니다. 프롬프트 캐싱과 Message Batches의 가격 할인은 누적되므로 두 기능을 함께 사용할 때 훨씬 더 큰 비용 절감을 제공합니다. 그러나 배치 요청은 비동기적으로 동시에 처리되므로 캐시 히트는 최선의 노력 기준으로 제공됩니다. 사용자는 일반적으로 트래픽 패턴에 따라 30%에서 98% 사이의 캐시 히트율을 경험합니다.
배치 요청에서 캐시 히트의 가능성을 최대화하려면:
cache_control 블록을 포함합니다배치에서 프롬프트 캐싱을 구현하는 예:
curl https://api.anthropic.com/v1/messages/batches \
--header "x-api-key: $ANTHROPIC_API_KEY" \
--header "anthropic-version: 2023-06-01" \
--header "content-type: application/json" \
--data \
'{
"requests": [
{
"custom_id": "my-first-request",
"params": {
"model": "claude-sonnet-4-5",
"max_tokens": 1024,
"system": [
{
"type": "text",
"text": "You are an AI assistant tasked with analyzing literary works. Your goal is to provide insightful commentary on themes, characters, and writing style.\n"
},
{
"type": "text",
"text": "<the entire contents of Pride and Prejudice>",
"cache_control": {"type": "ephemeral"}
}
],
"messages": [
{"role": "user", "content": "Analyze the major themes in Pride and Prejudice."}
]
}
},
{
"custom_id": "my-second-request",
"params": {
"model": "claude-sonnet-4-5",
"max_tokens": 1024,
"system": [
{
"type": "text",
"text": "You are an AI assistant tasked with analyzing literary works. Your goal is to provide insightful commentary on themes, characters, and writing style.\n"
},
{
"type": "text",
"text": "<the entire contents of Pride and Prejudice>",
"cache_control": {"type": "ephemeral"}
}
],
"messages": [
{"role": "user", "content": "Write a summary of Pride and Prejudice."}
]
}
}
]
}'이 예제에서 배치의 두 요청 모두 동일한 시스템 메시지와 캐시 히트의 가능성을 높이기 위해 cache_control로 표시된 Pride and Prejudice의 전체 텍스트를 포함합니다.
Batches API를 최대한 활용하려면:
custom_id 값을 사용하여 결과를 요청과 쉽게 일치시킵니다.예상치 못한 동작이 발생하는 경우:
request_too_large 오류가 발생할 수 있습니다.custom_id를 가지고 있는지 확인합니다.created_at (처리 ended_at 아님) 시간 이후 29일 미만이 경과했는지 확인합니다. 29일 이상 경과한 경우 결과를 더 이상 볼 수 없습니다.배치의 한 요청이 실패해도 다른 요청의 처리에는 영향을 주지 않습니다.
Workspace 격리: 배치는 생성된 Workspace 내에서 격리됩니다. 해당 Workspace와 연결된 API 키 또는 Console에서 Workspace 배치를 볼 수 있는 권한이 있는 사용자만 액세스할 수 있습니다.
결과 가용성: 배치 결과는 배치 생성 후 29일 동안 사용 가능하므로 검색 및 처리를 위한 충분한 시간을 제공합니다.