Если в вашем счёте за Claude есть длинный хвост неинтерактивных нагрузок — ночная классификация, разметка датасетов, ежемесячные прогоны модерации контента, прогон эвалов — вы оставляете примерно половину денег на столе, отправляя эти вызовы через синхронный Messages API. Batch API существует ровно для этого случая: отправляете задачу, ждёте до 24 часов, платите на 50% меньше за входные и выходные токены.
Что такое Batch API на самом деле
Batch API — это асинхронная очередь задач. Вместо того чтобы
отправлять запросы по одному и ждать ответ, вы загружаете JSONL-файл,
где каждая строка — это полноценный запрос Messages API, Anthropic
обрабатывает весь батч в рамках SLA 24 часа, а вы скачиваете
JSONL-файл ответов, привязанных к вашему custom_id в каждой строке.
Экономика простая:
- 50% скидка на входные токены.
- 50% скидка на выходные токены.
- Складывается с prompt caching — можно наложить скидку за кеш поверх скидки за батч на закешированной части входа.
- До 100 000 запросов в одном батче.
- SLA 24 часа — большинство батчей завершается за минуты или несколько часов, но рассчитывать на более быстрое нельзя.
Это самый дешёвый способ запускать Claude в масштабе, точка.
Идеальные сценарии
Batch — правильный примитив, когда ни один отдельный запрос не критичен по времени. Конкретно:
- Ночная классификация миллионов записей. Разметка тикетов поддержки, маршрутизация лидов, скоринг документов на релевантность. Отправили в 18:00, к утру результаты готовы.
- Разметка датасетов и генерация синтетических данных. Построение эвал-сетов, генерация обучающих пар, обогащение RAG-корпусов саммари, заголовками или извлечёнными сущностями.
- Ежемесячные прогоны модерации контента. Перепроверка пользовательского контента под обновлённую политику. Задача запускается раз в месяц, латентность не важна, объём огромный.
- Прогоны эвалов. Прогон нового промпта или модели по полному регресс-набору из тысяч тест-кейсов.
- Обогащение RAG-корпуса. Предвычисление саммари, извлечение FAQ, классификация чанков для базы знаний. Построили один раз — дальше отдаёте дёшево.
- Bulk-семантика "вместо эмбеддингов". Когда вы бы потянулись за эмбеддингами и классификатором, но на самом деле нужен LLM-вердикт по каждому элементу — батч делает путь "LLM на элемент" доступным по цене.
Когда НЕ нужно использовать Batch
Так же важно — не используйте Batch для:
- Интерактивного UX. Всё, чего ждёт пользователь. Чат, автодополнение кода, агенты в продукте. SLA 24 часа здесь фатален.
- Time-sensitive потоков. Фрод-решения, модерация в реальном времени, алертинг.
- Маленьких задач. Если у вас 50 запросов, операционные накладные расходы на загрузку, поллинг и склейку результатов не стоят сэкономленных копеек. Batch начинает окупаться от тысяч запросов.
- Воркфлоу с жёсткими меж-запросными зависимостями. Если запрос N+1 нуждается в выходе запроса N, нужен синхронный цикл, а не батч.
Математика цены: рабочий пример
Возьмём реалистичную задачу bulk-классификации: 100 000 вызовов Sonnet 4.6, по 1 000 входных и 500 выходных токенов каждый. Это 100M входных и 50M выходных токенов в сумме.
По синхронным ставкам это известное число из вашего месячного счёта. Через Batch API та же нагрузка стоит ровно вдвое меньше:
- Синхронно: вход + выход =
X. - Batch:
X / 2.
Для задачи такого масштаба эти 50% обычно — разница между "сделаем раз в квартал" и "запускаем каждую ночь". А если вы ещё кешируете стабильный системный промпт по всем 100 000 запросам, скидка кеша складывается с батчем на закешированной части — эффективная цена входа уходит ещё ниже.
Код: сборка batch JSONL
Каждая строка входного файла — самодостаточный запрос с вашим
custom_id. Через Claudexia направляете на
https://api.claudexia.tech/v1 — Batch API проксируется
прозрачно.
import json
from anthropic import Anthropic
client = Anthropic(
base_url="https://api.claudexia.tech/v1",
api_key="cxa_your_key_here",
)
# 1. Собираем JSONL-файл запросов
records = load_records_to_classify() # ваши 100k элементов
with open("batch.jsonl", "w") as f:
for r in records:
line = {
"custom_id": f"record-{r['id']}",
"params": {
"model": "claude-sonnet-4.6",
"max_tokens": 256,
"system": [
{
"type": "text",
"text": CLASSIFIER_SYSTEM_PROMPT,
"cache_control": {"type": "ephemeral"},
}
],
"messages": [
{"role": "user", "content": r["text"]},
],
},
}
f.write(json.dumps(line) + "\n")
# 2. Отправляем батч
batch = client.messages.batches.create(
requests=[json.loads(line) for line in open("batch.jsonl")]
)
print("submitted:", batch.id)
Поллинг и обработка результатов
Поллинг тривиален. Проверяйте processing_status с разумным
интервалом — раз в 60 секунд более чем достаточно, раз в 5 минут —
с запасом для большинства задач. Никаких горячих циклов.
import time
while True:
b = client.messages.batches.retrieve(batch.id)
if b.processing_status == "ended":
break
time.sleep(60)
# Стримим результаты построчно
for result in client.messages.batches.results(batch.id):
cid = result.custom_id
if result.result.type == "succeeded":
message = result.result.message
save_classification(cid, message.content[0].text)
elif result.result.type == "errored":
log_error(cid, result.result.error)
elif result.result.type == "expired":
# запрос не успел в SLA 24h — возвращаем в очередь
requeue(cid)
Обработка ошибок построчно
Принципиально важно: Batch API сообщает об ошибках на каждый
запрос, а не на батч целиком. Несколько упавших строк не отравят
остальные. Ваш код должен обрабатывать три терминальных состояния на
custom_id:
succeeded— нормальный ответ, сохраняем и двигаемся дальше.errored— ошибка модели или валидации; логируем, опционально ретраим разовым синхронным вызовом, продолжаем.expired— SLA истёк до того, как этот конкретный запрос был обслужен; ставим обратно в следующий батч.
Относитесь к файлу результатов как к стриму. Не грузите 100k ответов в память.
Складывайте с prompt caching ради составной экономии
Batch и prompt caching — независимые скидки. Если ваши 100 000
запросов разделяют длинный системный промпт или контекст документа,
пометьте его cache_control — и закешированная часть получает скидку
кеша поверх 50% скидки за батч. Для агентных классификаторов с
системным промптом на 4k токенов это самый большой рычаг после самого
перехода на батч.
Операционный нюанс на Claudexia
Claudexia проксирует Batch API в Anthropic прозрачно — те же
эндпоинты, тот же JSONL-формат, тот же SDK. Один операционный момент,
специфичный для pay-per-token шлюза: батч списывается в момент
отправки, поэтому пополните баланс на сумму всей задачи до вызова
batches.create. Дашборд показывает оценку стоимости батча по
входному файлу; бюджетируйте от этой оценки плюс запас на выходные
токены.
Итог
Если задача не должна отвечать за секунды — она не должна крутиться на синхронном API. Переносите ночные джобы, обработку датасетов, ежемесячные прогоны и эвалы в Batch, добавляйте prompt caching на стабильные части, а синхронный API оставляйте для того, чего реально ждёт пользователь.