
Batch API позволяет отправлять сотни и тысячи запросов к AI-моделям одним пакетом и забирать результаты через 24 часа. Это удобно для массовых задач: сгенерировать описания для 500 товаров на Wildberries, проанализировать 10 000 отзывов, перевести каталог на 5 языков, извлечь реквизиты из 1 000 счетов. Вместо 500 отдельных вызовов получается один batch.
flowchart LR
A["500 отдельных<br/>запросов"] --> B["Очередь<br/>API"]
B --> C["Медленно<br/>Дорого"]
D["1 batch<br/>с 500 задачами"] --> E["Пакетная<br/>обработка"]
E --> F["Быстро<br/>Дешевле на 50%"]
style A fill:#fee
style C fill:#fee
style D fill:#efe
style F fill:#efeСкидка 50% применяется не автоматически. В каталоге VEGA есть отдельные слаги моделей с суффиксом :batch, и у них цена за токены уже снижена вдвое относительно обычной версии.
Например, openai/gpt-6-astra стоит $0.00001 за prompt-токен и $0.00005 за completion. А openai/gpt-6-astra:batch стоит $0.000005 и $0.000025 соответственно. Ровно половина.
Если отправить пакет с обычной моделью без суффикса :batch, списания пойдут по стандартной ставке и скидки не будет. В поле model пакета указывайте именно batch-слаг.
На данный момент в каталоге 68 batch-моделей: openai/gpt-6-astra:batch, anthropic/claude-opus-5:batch, google/gemini-3.8-flash:batch, deepseek/deepseek-v4-pro-0813:batch, x-ai/grok-4.3:batch и другие. Узнать полный список можно через GET /api/v1/models, отфильтровав те, чей id содержит :batch. Для эмбеддингов отдельных batch-слагов нет, используется обычная модель вроде openai/text-embedding-3-small.
Batch API работает только с текстом:
modalities, audio, image_configinput принимает только строки или массивы токеновЕсли нужна мультимодальность, используйте обычный синхронный API.
sequenceDiagram
participant U as Вы
participant V as API VEGA
participant M as AI-модель
U->>V: POST /api/beta/batches<br/>массив requests[]
V-->>U: 202 Accepted<br/>batch_id, status: validating
Note over V,M: Обработка в фоне<br/>до 24 часов
V->>M: Запрос 1, 2, 3...N
M-->>V: Результаты
V-->>U: GET /api/beta/batches/{id}<br/>status: completed
U->>V: Забрать results[]Шаг 1. Отправляете POST-запрос с массивом задач. В ответ получаете batch_id и статус validating. Пачка принята и поставлена в очередь, но задачи ещё не выполнены.
Шаг 2. Периодически проверяете статус по batch_id. Цепочка статусов: validating → in_progress → finalizing → completed. Возможны также failed, expired и cancelled. Терминальные статусы, после которых пакет не меняется: completed, failed, expired, cancelled.
Шаг 3. Когда статус completed, забираете массив результатов.
Batch-запросы стоят 50% от стандартной цены модели за токены при использовании batch-слага. Это зеркалит скидки OpenAI и Anthropic на их собственных batch-эндпоинтах.
Нюансы по тарификации:
Для завершённого пакета поле usage.cost показывает итоговую сумму списания. Для BYOK-маршрутов там будет только комиссия API VEGA, а провайдер списывает деньги за инференс напрямую.
API VEGA работает как прокси, совместимый с OpenRouter API. Оплата в рублях, базовая валюта кредитов RUB. Все эндпоинты доступны через единый base URL: https://api.vega.chat/api/v1. Batch API живёт по отдельному пути: https://api.vega.chat/api/beta/batches.
Batch-запрос требует три обязательных поля верхнего уровня:
| Поле | Описание |
|---|---|
endpoint | Формат API для всех запросов в пачке: /v1/chat/completions, /v1/responses, /v1/messages, /v1/embeddings |
model | Слаг batch-модели, например openai/gpt-6-astra:batch. Применяется ко всем запросам в пачке |
requests | Непустой массив объектов { custom_id, body }. custom_id должен быть уникальным в пределах batch |
Важно: в JSON-теле поля endpoint и model должны идти перед requests. API стримит парсинг запроса, чтобы принимать огромные массивы без буферизации, и вернёт ошибку 400, если requests окажется первым.
Модель на уровне пакета применяется ко всем запросам. В теле запроса можно не указывать model, тогда он унаследует пакетное значение. Если тело задаёт свою модель, она должна совпадать с пакетной, иначе отправка отклоняется.
Для моделей Google все запросы в пакете должны использовать одинаковый response_format: либо все без него, либо все json_object, либо все json_schema с одной и той же схемой. Иначе валидация упадёт. Отправляйте отдельный пакет на каждый response_format и на каждую схему.
Дальше идут рабочие примеры под реальные задачи. В каждом используется batch-слаг модели, осмысленные custom_id и системный промпт, который задаёт формат ответа.
Селлер на Wildberries или Ozon загружает характеристики товаров в каталог. Нужно сгенерировать продающие описания с ключевыми словами для 500 позиций. Каждый запрос берёт характеристики конкретного товара и просит модель написать описание по шаблону.
import json
import requests
# Выгрузка из каталога: артикул, название, категория, характеристики
products = [
{
"sku": "WB-100234",
"name": "Беспроводные наушники SoundPro X5",
"category": "Аудиотехника",
"specs": "Bluetooth 5.3, 40 часов работы, активное шумоподавление, USB-C, вес 250 г"
},
{
"sku": "WB-100235",
"name": "Умные часы FitBand 7",
"category": "Носимые устройства",
"specs": "AMOLED 1.43, пульсоксиметр, GPS, водозащита 5 ATM, 14 дней автономности"
},
# ... ещё 498 товаров
]
SYSTEM_PROMPT = (
"Ты копирайтер для маркетплейса. Напиши продающее SEO-описание товара "
"для карточки на Wildberries. Объём 400-600 знаков. Используй ключевые "
"слова из названия и категории. Не выдумывай характеристики, которых "
"нет в исходных данных. Структура: первый абзац про главное преимущество, "
"второй про особенности, третий про то, кому подойдёт товар. Без эмодзи."
)
requests_array = [
{
"custom_id": f"product-{p['sku']}",
"body": {
"messages": [
{"role": "system", "content": SYSTEM_PROMPT},
{"role": "user", "content": (
f"Название: {p['name']}\n"
f"Категория: {p['category']}\n"
f"Характеристики: {p['specs']}\n\n"
"Напиши описание для карточки товара."
)}
],
"max_tokens": 800
}
}
for p in products
]
response = requests.post(
url="https://api.vega.chat/api/beta/batches",
headers={
"Authorization": "Bearer <VEGA_API_KEY>",
"Content-Type": "application/json",
},
data=json.dumps({
"endpoint": "/v1/chat/completions",
"model": "openai/gpt-6-astra:batch",
"requests": requests_array
})
)
batch = response.json()
print("batch_id:", batch["id"])
print("status:", batch["status"])После завершения пакета в results окажется по одному ответу на каждый custom_id. Сопоставляйте custom_id вида product-WB-100234 с артикулом в вашей базе и записывайте описание обратно в каталог.
У магазина 10 000 отзывов. Для каждого нужно определить тональность, выделить ключевые проблемы и сгенерировать краткое резюме для отчёта. Используем response_format с json_schema, чтобы модель возвращала структурированный объект, а не свободный текст.
curl https://api.vega.chat/api/beta/batches \
-H "Content-Type: application/json" \
-H "Authorization: Bearer $VEGA_API_KEY" \
-d '{
"endpoint": "/v1/chat/completions",
"model": "openai/gpt-6-astra:batch",
"requests": [
{
"custom_id": "review-88001",
"body": {
"messages": [
{
"role": "system",
"content": "Проанализируй отзыв покупателя. Верни JSON с полями sentiment (positive, negative, neutral), score от 1 до 5, problems (массив строк), summary (одно предложение на русском)."
},
{
"role": "user",
"content": "Товар: Беспроводные наушники SoundPro X5. Отзыв: Звук хороший, но через месяц перестал заряжаться левый наушник. Вернул по гарантии. Расстроился, брал в подарок."
}
],
"max_tokens": 300,
"response_format": {
"type": "json_schema",
"json_schema": {
"name": "review_analysis",
"strict": true,
"schema": {
"type": "object",
"properties": {
"sentiment": {"type": "string", "enum": ["positive", "negative", "neutral"]},
"score": {"type": "integer", "minimum": 1, "maximum": 5},
"problems": {"type": "array", "items": {"type": "string"}},
"summary": {"type": "string"}
},
"required": ["sentiment", "score", "problems", "summary"],
"additionalProperties": false
}
}
}
}
},
{
"custom_id": "review-88002",
"body": {
"messages": [
{
"role": "system",
"content": "Проанализируй отзыв покупателя. Верни JSON с полями sentiment (positive, negative, neutral), score от 1 до 5, problems (массив строк), summary (одно предложение на русском)."
},
{
"role": "user",
"content": "Товар: Умные часы FitBand 7. Отзыв: Отличные часы за свои деньги. Заряд держат реально 12 дней, пульс меряет точно, сравнивал с нагрудным датчиком. Экран яркий, на солнце всё видно."
}
],
"max_tokens": 300,
"response_format": {
"type": "json_schema",
"json_schema": {
"name": "review_analysis",
"strict": true,
"schema": {
"type": "object",
"properties": {
"sentiment": {"type": "string", "enum": ["positive", "negative", "neutral"]},
"score": {"type": "integer", "minimum": 1, "maximum": 5},
"problems": {"type": "array", "items": {"type": "string"}},
"summary": {"type": "string"}
},
"required": ["sentiment", "score", "problems", "summary"],
"additionalProperties": false
}
}
}
}
}
]
}'В ответе на каждый отзыв приходит JSON, который можно сразу писать в базу или BI-систему. Никакого парсинга свободного текста.
Селлер расширяется на зарубежные площадки. Нужно перевести 500 описаний товаров на английский, казахский, белорусский, армянский и узбекский. Это 2 500 запросов, которые уходят одним пакетом.
const products = [
{
sku: 'OZ-2001',
name: 'Детский конструктор "Город" 240 деталей',
description: 'Конструктор из экологичного пластика. Развивает мелкую моторику и пространственное мышление. В наборе 240 деталей, инструкция на русском языке. Для детей от 5 лет.'
},
{
sku: 'OZ-2002',
name: 'Набор для творчества "Юный художник"',
description: 'В наборе 24 фломастера, 12 красок, 3 кисти, палитра и блокнот 30 листов. Все материалы нетоксичные, сертифицированы для детей. Подходит для занятий в школе и дома.'
},
// ... ещё 498 товаров
];
const targetLangs = [
{ code: 'en', name: 'английский' },
{ code: 'kk', name: 'казахский' },
{ code: 'be', name: 'белорусский' },
{ code: 'hy', name: 'армянский' },
{ code: 'uz', name: 'узбекский' },
];
const SYSTEM_PROMPT =
'Ты профессиональный переводчик описаний товаров для маркетплейсов. ' +
'Переведи текст на указанный язык. Сохрани продающий тон, не добавляй ' +
'информации, которой нет в оригинале. Названия брендов оставляй без перевода. ' +
'Верни только переведённый текст, без пояснений.';
const requests = products.flatMap((product) =>
targetLangs.map((lang) => ({
custom_id: `${product.sku}-${lang.code}`,
body: {
messages: [
{ role: 'system', content: SYSTEM_PROMPT },
{
role: 'user',
content:
`Переведи на ${lang.name} язык.\n\n` +
`Название: ${product.name}\n` +
`Описание: ${product.description}`,
},
],
max_tokens: 600,
},
}))
);
const response = await fetch('https://api.vega.chat/api/beta/batches', {
method: 'POST',
headers: {
Authorization: 'Bearer <VEGA_API_KEY>',
'Content-Type': 'application/json',
},
body: JSON.stringify({
endpoint: '/v1/chat/completions',
model: 'openai/gpt-6-astra:batch',
requests,
}),
});
const batch = await response.json();
console.log('batch_id:', batch.id);
console.log('total requests:', batch.request_counts.total);custom_id вида OZ-2001-en позволяет после получения результатов разложить переводы по товарам и языкам без дополнительной логики.
У селлера 3 000 товаров без категорий. Нужно сопоставить каждый с внутренним справочником категорий и вернуть код категории. Используем json_object, чтобы ответ был машиночитаемым.
import json
import requests
CATEGORIES = {
"ELEC": "Электроника и гаджеты",
"HOME": "Товары для дома",
"KIDS": "Детские товары",
"APPAREL": "Одежда и обувь",
"BEAUTY": "Красота и здоровье",
"SPORT": "Спорт и отдых",
"AUTO": "Автотовары",
"FOOD": "Продукты питания",
}
SYSTEM_PROMPT = (
"Ты классификатор товаров для маркетплейса. Отнеси товар к одной из "
"категорий из справочника. Верни JSON: "
'{"category_code": "код", "confidence": 0.0-1.0, "reason": "короткое объяснение"}. '
"Если товар не подходит ни под одну категорию, верни category_code = null."
)
products = [
{"sku": "T-3001", "name": "Автомобильное зарядное устройство 2USB 3.4A", "specs": "Подходит для смартфонов и планшетов, защита от перегрева"},
{"sku": "T-3002", "name": "Набор контейнеров для еды 5 шт BPA-free", "specs": "Микроволновка, морозилка, посудомойка"},
{"sku": "T-3003", "name": "Кроссовки беговые мужские размер 42", "specs": "Сетка, амортизация, подошва EVA"},
# ... ещё 2997 товаров
]
requests_array = [
{
"custom_id": f"cls-{p['sku']}",
"body": {
"messages": [
{"role": "system", "content": SYSTEM_PROMPT + "\n\nСправочник категорий:\n" + json.dumps(CATEGORIES, ensure_ascii=False, indent=2)},
{"role": "user", "content": f"Название: {p['name']}\nХарактеристики: {p['specs']}"}
],
"max_tokens": 200,
"response_format": {"type": "json_object"}
}
}
for p in products
]
response = requests.post(
url="https://api.vega.chat/api/beta/batches",
headers={
"Authorization": "Bearer <VEGA_API_KEY>",
"Content-Type": "application/json",
},
data=json.dumps({
"endpoint": "/v1/chat/completions",
"model": "openai/gpt-6-astra:batch",
"requests": requests_array
})
)
print(response.json())Бухгалтерия получает 1 000 выписок и счетов в виде текста после OCR. Нужно извлечь реквизиты компании, сумму, дату и номер документа в структурированном виде. Один пакет, на выходе готовая таблица.
curl https://api.vega.chat/api/beta/batches \
-H "Content-Type: application/json" \
-H "Authorization: Bearer $VEGA_API_KEY" \
-d '{
"endpoint": "/v1/chat/completions",
"model": "openai/gpt-6-astra:batch",
"requests": [
{
"custom_id": "invoice-2026-0001",
"body": {
"messages": [
{
"role": "system",
"content": "Извлеки реквизиты из текста счёта. Верни JSON с полями: seller_name (название продавца), seller_inn (ИНН), buyer_name, buyer_inn, invoice_number, invoice_date (ISO 8601), amount (число, рубли), vat (число, рубли или 0), currency. Если поле не найдено, ставь null."
},
{
"role": "user",
"content": "СЧЁТ № 2026-0001 от 15 августа 2026 г. Продавец: ООО Ромашка, ИНН 7701234567. Покупатель: АО Вектор, ИНН 7707654321. Итого: 145 000,00 руб., в т.ч. НДС 20%: 24 166,67 руб."
}
],
"max_tokens": 400,
"response_format": {"type": "json_object"}
}
},
{
"custom_id": "invoice-2026-0002",
"body": {
"messages": [
{
"role": "system",
"content": "Извлеки реквизиты из текста счёта. Верни JSON с полями: seller_name (название продавца), seller_inn (ИНН), buyer_name, buyer_inn, invoice_number, invoice_date (ISO 8601), amount (число, рубли), vat (число, рубли или 0), currency. Если поле не найдено, ставь null."
},
{
"role": "user",
"content": "Счёт на оплату № 14/08 от 14.08.2026. Исполнитель: ИП Сидоров А.В., ИНН 773312345678. Заказчик: ООО Гамма, ИНН 5024555000. Сумма к оплате: 38 000 руб., без НДС (УСН)."
}
],
"max_tokens": 400,
"response_format": {"type": "json_object"}
}
}
]
}'Чтобы построить поиск по каталогу из 50 000 товаров, нужны векторы всех названий и описаний. Группируем по 100 строк на запрос, чтобы не плодить лишние вызовы. Для эмбеддингов отдельных batch-слагов нет, используется обычная модель.
import json
import requests
# Названия и описания товаров из каталога
catalog_texts = [
"Беспроводные наушники SoundPro X5, Bluetooth 5.3, активное шумоподавление, 40 часов работы",
"Умные часы FitBand 7, AMOLED 1.43, пульсоксиметр, GPS, водозащита 5 ATM",
"Детский конструктор Город 240 деталей, экологичный пластик, от 5 лет",
# ... ещё 49 997 строк
]
# Группируем по 100 строк на один запрос эмбеддингов
BATCH_SIZE = 100
requests_array = []
for i in range(0, len(catalog_texts), BATCH_SIZE):
chunk = catalog_texts[i:i + BATCH_SIZE]
requests_array.append({
"custom_id": f"emb-chunk-{i // BATCH_SIZE:05d}",
"body": {
"input": chunk
}
})
response = requests.post(
url="https://api.vega.chat/api/beta/batches",
headers={
"Authorization": "Bearer <VEGA_API_KEY>",
"Content-Type": "application/json",
},
data=json.dumps({
"endpoint": "/v1/embeddings",
"model": "openai/text-embedding-3-small",
"requests": requests_array
})
)
print(response.json())После завершения каждый результат содержит массив векторов, упорядоченный по index. Порядок совпадает с порядком строк в input, поэтому сопоставить вектор с товаром можно по индексу внутри чанка.
Успешная отправка возвращает 202 Accepted со статусом validating. Это значит, что пакет сохранён и поставлен в очередь на валидацию, но не что все запросы уже выполнены.
{
"id": "batch_abc123",
"object": "batch",
"endpoint": "/v1/chat/completions",
"model": "openai/gpt-6-astra:batch",
"completion_window": "24h",
"status": "validating",
"created_at": 1782097200,
"finalized_at": null,
"request_counts": {
"total": 500,
"completed": 0,
"failed": 0
},
"usage": null,
"results": null,
"error": null
}Сохраните id. По нему вы будете проверять статус и забирать результаты. Поддерживается только окно завершения 24h.
# Получить статус и результаты конкретного batch
curl https://api.vega.chat/api/beta/batches/batch_abc123 \
-H "Authorization: Bearer $VEGA_API_KEY"
# Список всех batch в вашем workspace
curl "https://api.vega.chat/api/beta/batches?limit=10&status=completed" \
-H "Authorization: Bearer $VEGA_API_KEY"Когда статус станет completed, в поле results появятся ответы на каждый запрос с соответствующим custom_id. У каждого результата заполнено ровно одно из полей: response или error. Отдельного эндпоинта для скачивания результатов нет, всё приходит в одном ответе.
Поле request_counts показывает, сколько запросов завершилось успешно, а сколько упало:
{
"total": 500,
"completed": 498,
"failed": 2
}Пример результата для запроса из примера 1 про SEO-описание товара:
{
"id": "batch_req_123",
"custom_id": "product-WB-100234",
"response": {
"status_code": 200,
"request_id": "request_123",
"body": {
"id": "gen-batch-1782097200-a1b2c3d4e5f6a7b8c9d0",
"object": "chat.completion",
"created": 1782097200,
"model": "openai/gpt-6-astra:batch",
"choices": [
{
"index": 0,
"message": {
"role": "assistant",
"content": "Беспроводные наушники SoundPro X5 с активным шумоподавлением для погружения в музыку без отвлекающих звуков. До 40 часов работы от одного заряда, быстрое наполнение через USB-C. Bluetooth 5.3 держит стабильное соединение на расстоянии до 10 метров, вес 250 грамм позволяет носить их весь день без усталости. Подходят для поездок, работы в офисе и занятий спортом."
},
"finish_reason": "stop"
}
]
}
},
"error": null
}Формат задаётся полем endpoint на верхнем уровне и применяется ко всем запросам в пакете. Все запросы в одном пакете используют один и тот же эндпоинт. Чтобы смешивать форматы, отправляйте отдельные пакеты.
Поддерживаются четыре формата: /v1/chat/completions, /v1/responses, /v1/messages (Anthropic-совместимый) и /v1/embeddings.
Пример пакета для Anthropic Messages. Та же задача, что в примере 1, но через /v1/messages и модель anthropic/claude-opus-5:batch:
{
"endpoint": "/v1/messages",
"model": "anthropic/claude-opus-5:batch",
"requests": [
{
"custom_id": "product-WB-100234",
"body": {
"max_tokens": 800,
"system": "Ты копирайтер для маркетплейса. Напиши продающее SEO-описание товара для карточки на Wildberries. Объём 400-600 знаков. Используй ключевые слова из названия и категории. Не выдумывай характеристики, которых нет в исходных данных. Без эмодзи.",
"messages": [
{
"role": "user",
"content": "Название: Беспроводные наушники SoundPro X5\nКатегория: Аудиотехника\nХарактеристики: Bluetooth 5.3, 40 часов работы, активное шумоподавление, USB-C, вес 250 г\n\nНапиши описание для карточки товара."
}
]
}
}
]
}Если у вас настроен ключ провайдера, пакеты маршрутизируются через него автоматически, как и синхронные запросы. Провайдер списывает оплату за инференс напрямую, а VEGA берёт только комиссию BYOK. У завершённых пакетов поле usage.is_byok равно true.
Для Google Vertex используется бакет в вашем GCP-проекте. По умолчанию можно не указывать bucket, и сервис создаст приватный бакет в совместимом регионе при первом пакете. Можно также передать существующий бакет.
Входные данные и результаты пакетов хранятся как JSONL-артефакты в Google Cloud Storage и удаляются через 30 дней после создания. Скачивайте нужные результаты до истечения 30-дневного окна.
Группируйте по модели. Все запросы в одном batch должны использовать одну и ту же модель. Если нужны разные модели, создавайте несколько пакетов.
Следите за response_format. Для моделей Google все запросы в batch должны использовать одинаковый response_format: либо все без него, либо все json_object, либо все json_schema с одной и той же схемой. Иначе валидация упадёт.
Используйте осмысленные custom_id. Это ваш идентификатор для сопоставления запроса и результата. Делайте его привязанным к бизнес-сущности: product-WB-100234, review-88001, invoice-2026-0001, OZ-2001-en. Тогда после получения результатов не придётся писать отдельную логику сопоставления.
Не ждите мгновенного результата. Completion window 24 часа. Для срочных задач используйте обычный синхронный API.
Проверяйте usage. В завершённом batch поле usage.cost покажет итоговую стоимость. Для BYOK-маршрутов там будет только комиссия API VEGA, а провайдер списывает деньги за инференс напрямую.
:batch из каталогаhttps://api.vega.chat/api/beta/batchesbatch_id и проверяйте статус каждые 15-30 минутcompleted, заберите результаты из поля resultsBatch API подходит для систематической обработки больших объёмов данных: переводы, классификация, анализ отзывов, генерация описаний, извлечение реквизитов, эмбеддинги для поиска. Для разовых запросов и мультимодальных задач используйте синхронный API.