Для AI-агентов: markdown этой страницы — /docs-content/ai/chat/json.md индекс документации — /llms.txt
Гарантированный JSON-ответ
Параметр response_format заставляет модель вернуть машиночитаемый ответ вместо свободного текста. Есть два уровня строгости: json_object гарантирует корректный JSON произвольной формы, json_schema — соответствие заданной схеме.
Режим `json_object`
При response_format: {"type": "json_object"} модель возвращает корректный JSON в поле content. Вайбкод автоматически добавляет в системное сообщение инструкцию вернуть только JSON. Структуру результата опишите явно в системном сообщении:
curl -X POST https://vibecode.bitrix24.tech/v1/chat/completions \
-H "X-Api-Key: YOUR_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"model": "bitrix/bitrixgpt-5.5",
"messages": [
{"role": "system", "content": "Классифицируй лид. Верни JSON: {\"quality\": \"high|medium|low\", \"score\": 0-100}"},
{"role": "user", "content": "ООО Вектор, бюджет 2 миллиона в месяц"}
],
"response_format": {"type": "json_object"}
}'
Ответ:
{
"id": "chatcmpl-acdb112cf9cdf9f9",
"object": "chat.completion",
"model": "bitrix/bitrixgpt-5.5",
"choices": [
{
"index": 0,
"finish_reason": "stop",
"message": {
"role": "assistant",
"content": "{\"quality\":\"high\",\"score\":92}"
}
}
],
"usage": {"prompt_tokens": 56, "completion_tokens": 14, "total_tokens": 70}
}
Режим `json_schema`
response_format: {"type": "json_schema", "json_schema": {...}} гарантирует, что ответ модели строго соответствует заданной JSON Schema — модель не может вернуть лишние поля, пропустить обязательные или перепутать типы. Это строже, чем json_object, который гарантирует только корректный JSON.
Режим доступен не на всех моделях. Актуальный список — в ответе GET /v1/me, поле data.ai.structuredOutputs.models.
Поля `json_schema`
| Поле | Тип | Обяз. | Описание |
|---|---|---|---|
Полеname |
Типstring | Обяз.да | ОписаниеИмя схемы. До 64 символов, допустимы a-zA-Z0-9_- |
Полеschema |
Типobject | Обяз.да | ОписаниеСама JSON Schema |
Полеstrict |
Типboolean | Обяз.нет | Описаниеtrue — строгая проверка соответствия схеме. Рекомендуемое значение |
Полеdescription |
Типstring | Обяз.нет | ОписаниеОписание схемы для модели, помогает ей верно истолковать поля |
Пример со схемой
curl -X POST https://vibecode.bitrix24.tech/v1/chat/completions \
-H "X-Api-Key: YOUR_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"model": "bitrix/bitrixgpt-5.5",
"messages": [
{"role": "system", "content": "Верни строгий JSON по схеме."},
{"role": "user", "content": "Привет"}
],
"response_format": {
"type": "json_schema",
"json_schema": {
"name": "hello_response",
"strict": true,
"schema": {
"type": "object",
"properties": {"message": {"type": "string"}},
"required": ["message"],
"additionalProperties": false
}
}
}
}'
Поле choices[0].message.content содержит строку, которая разбирается в объект, точно соответствующий схеме — например {"message":"Привет"}.
Ранний отказ при повторении JSON
Необязательный repetition_guard принимает "off" или "abort". Если его не передавать или передать "off", сохраняется прежнее поведение, включая терминальную проверку повторов после finish_reason: "length". Режим "abort" включайте явно, когда готовы принять эвристический отказ на законном повторяющемся префиксе, например на массиве одинаковых объектов.
Для "abort" нужны response_format с типом json_object или json_schema, отсутствие объявленных инструментов (tools не передан или пуст) и выбранная модель с поддержкой потока, даже при stream: false. Режим недоступен для управляющих запросов и запросов завершения Cowork, а также объявлений об исчерпании квоты. Несовместимый запрос отклоняется до резервирования и обращения к модели: 400 invalid_request, type: "invalid_request_error", param: "repetition_guard". Значения null, boolean и строки вне перечисления тоже дают 400 invalid_request.
Проверяется нормализованный текст ответа content, отдельно от рассуждения. Полный JSON-документ в момент проверки исключается, фактические вызовы инструментов или функций отключают проверку. Защита рассуждения продолжает работать по прежним правилам. Эвристика не распознаёт все зацикливания и не задаёт предельного времени ожидания: для решения нужен достаточный объём текста. При превышении предела проверяемого текста в 1 048 576 символов ранняя проверка отключается.
При stream: false платформа читает поток модели внутри запроса, а клиент получает обычный JSON ответа или 422, без SSE-заголовков и фрагментов. При stream: true HTTP-статус остаётся 200, приходит одно событие error, затем один data: [DONE]. Клиент должен отбросить уже полученный частичный ответ. После обнаружения повтора запрос к модели отменяется без повтора, восстановления ответа или перехода на другую модель. Отмена соединения не гарантирует немедленного освобождения GPU.
Ранний отказ имеет фиксированные message и hint:
{
"error": {
"message": "Repeated JSON content was detected and this request was stopped early.",
"type": "invalid_request_error",
"code": "reasoning_repetition",
"hint": "Disable repetition_guard for expected repeated content; otherwise revise the request or use another model."
}
}
Он не содержит выдуманного finishReason: "length", полей param, suggestedMaxTokens, retryable, retryAfter или совета отключать рассуждение. Сырой ответ, запрос, схема и приватные идентификаторы провайдера в ошибку не включаются. Уже измеренный расход сохраняется по действующим правилам неуспешного вызова. Если модель не прислала расход, он остаётся неизвестным и не оценивается по длине текста. Ранний отказ не означает, что модель не потратила токены.
В OpenAI Python SDK передавайте расширение через extra_body:
from openai import OpenAI
client = OpenAI(base_url="https://vibecode.bitrix24.tech/v1", api_key="YOUR_API_KEY")
response = client.chat.completions.create(
model="bitrix/bitrixgpt-5.5",
messages=[{"role": "user", "content": "Return a JSON object with a greeting."}],
response_format={"type": "json_object"},
extra_body={"repetition_guard": "abort"},
)
Для ожидаемых повторов используйте "off" или уберите опцию. Не включайте "abort" по умолчанию для всех JSON-запросов.
Пример ответа при ошибке
400 model_does_not_support_structured_outputs — модель не поддерживает json_schema. В поле structuredOutputsModels приходит список подходящих моделей:
{
"error": {
"message": "Model 'openai/o3' does not support response_format=json_schema. Use one of: bitrix/bitrixgpt-5.5, bitrix/bitrixgpt-5.5-thinking, openai/gpt-4o, openai/gpt-4o-mini.",
"type": "invalid_request_error",
"code": "model_does_not_support_structured_outputs",
"param": "response_format.type",
"structuredOutputsModels": ["bitrix/bitrixgpt-5.5", "bitrix/bitrixgpt-5.5-thinking", "openai/gpt-4o", "openai/gpt-4o-mini", "openai/o3-mini"]
}
}
422 structured_output_truncated — генерация оборвана по лимиту токенов без обнаруженного повтора:
{
"error": {
"message": "The model's response was cut off (finish_reason=length) before a complete JSON document was produced, so it does not satisfy the requested response_format. Raise max_tokens, or reduce the schema/prompt size.",
"type": "invalid_request_error",
"code": "structured_output_truncated",
"hint": "For reasoning models, max_tokens must cover the reasoning phase plus the JSON answer.",
"param": "max_tokens",
"finishReason": "length",
"suggestedMaxTokens": 2048
}
}
422 structured_output_invalid_json — ответ непустой, но не разбирается как JSON-документ:
{
"error": {
"message": "The model returned a non-empty response (finish_reason=stop) that is not a valid JSON document, so it does not satisfy the requested response_format. The response body was discarded rather than handed over as JSON.",
"type": "invalid_request_error",
"code": "structured_output_invalid_json",
"hint": "Retry the request, or use a model with reliable structured output; for a strict shape use response_format=json_schema. A larger token budget will not change the result.",
"finishReason": "stop"
}
}
Ошибки
| HTTP | Код | Описание |
|---|---|---|
| HTTP400 | Кодinvalid_request |
ОписаниеНесовместимый запрос с repetition_guard: "abort" или недопустимое значение опции. Ограничения описаны выше |
| HTTP400 | Кодmodel_does_not_support_structured_outputs |
ОписаниеМодель не поддерживает json_schema. Список подходящих — в поле structuredOutputsModels |
| HTTP422 | Кодstructured_output_truncated |
ОписаниеМодель оборвала генерацию до полного JSON без обнаруженного повтора или вернула пустой ответ |
| HTTP422 | Кодstructured_output_invalid_json |
ОписаниеМодель вернула непустой ответ, который не разбирается как JSON-объект или массив |
| HTTP422 | Кодreasoning_repetition |
ОписаниеМодель зациклилась в рассуждении — повторяла одни и те же фразы и не начала ответ. Повторите запрос с reasoning_effort: "none" |
| HTTP422 | Кодreasoning_repetition |
ОписаниеПо умолчанию (repetition_guard не передан или "off") обнаружен повтор в непустом незавершённом JSON при json_object или json_schema после finish_reason: "length". Проверка терминальная; Это эвристическая диагностика: она может сработать и на законном повторяющемся массиве, которому не хватило бюджета. Проверьте, ожидаемы ли повторы; если да, проверьте лимит токенов, иначе уточните запрос или смените модель. Подсказки отключить рассуждение нет |
| HTTP422 | Кодreasoning_repetition |
ОписаниеПри явном repetition_guard: "abort" обнаружен повтор JSON до завершения. Отключите опцию для ожидаемых повторов, иначе уточните запрос или смените модель |
Полный список общих ошибок API — Ошибки.
Известные особенности
Обрезанный ответ даёт 422 structured_output_truncated. Если модель оборвала генерацию до полного JSON (finish_reason: "length"), запрос с response_format без обнаруженного повтора возвращает 422 structured_output_truncated с полями finishReason и suggestedMaxTokens. Так ведут себя модели с рассуждением: фаза рассуждения расходует бюджет max_tokens до того, как модель напишет JSON. Обрабатывайте эту ошибку и повторяйте запрос с увеличенным max_tokens — можно взять значение из suggestedMaxTokens. Для строгого JSON задавайте max_tokens с запасом либо используйте модель без рассуждения.
Поля suggestedMaxTokens и param: "max_tokens" присутствуют только при finish_reason: "length" в ошибке structured_output_truncated. При обнаруженном повторе приходит reasoning_repetition без этих полей. Если причина завершения любая другая, а корректного JSON так и нет, ответ тоже 422, но уже без этих двух полей — увеличение max_tokens не поможет, возьмите модель без рассуждения. Строка hint и поле finishReason есть в обеих ветках, finishReason может быть null.
Если же модель с рассуждением на json_object завершилась сама и положила готовый корректный JSON в служебный канал reasoning_content, платформа восстанавливает этот JSON и возвращает 200 с ним в content — отдельной обработки не требуется.
Неразбираемый ответ даёт 422 structured_output_invalid_json. Платформа разбирает ответ перед выдачей: если при response_format модель вернула непустой текст, который не является JSON-объектом или массивом (текст вокруг объекта, ответ в markdown-ограждении кода, одиночное значение вроде 42), такой ответ не отдаётся как успешный. В отказе есть finishReason и hint, но нет param и suggestedMaxTokens — увеличение бюджета токенов здесь не помогает: помогает повтор запроса, а при важной структуре — json_schema со strict: true. Вложенный JSON внутри строкового поля нарушением не считается: проверяется только внешний разбор.
Зацикленное рассуждение даёт 422 reasoning_repetition, а не structured_output_truncated. Если модель с рассуждением так и не начала ответ, потому что повторяла в reasoning_content одни и те же фразы, отказ приходит с кодом reasoning_repetition. В нём есть finishReason и hint, но нет param и suggestedMaxTokens: увеличение бюджета токенов только удлинит повтор. Повторите запрос с выключенным рассуждением — reasoning_effort: "none". Перебор разных формулировок повтором не считается: такой ответ остаётся structured_output_truncated. Если канал reasoning_content начинается как JSON-документ (с { или [), в потоке решение откладывается, пока восстановление возможно (если документ слишком длинный, чтобы его восстановить, повтор обрывает поток сразу): полный документ восстанавливается, как описано выше, даже если в нём одинаковые объекты, а если восстановить не удалось — приходит reasoning_repetition. Восстановление из рассуждения выполняется только для json_object: без response_format ответ, пришедший только в reasoning_content, при зацикливании обрывается событием reasoning_repetition.
Терминальная попытка, закончившаяся 422, тарифицируется. Ответ 422 — и при обрыве, и при неразбираемом ответе, и при зацикленном рассуждении — приходит после того, как модель отработала, поэтому токены попытки учитываются в статистике расхода GET /v1/ai/usage и в месячной AI-квоте портала. Повтор с увеличенным max_tokens — это ещё один оплачиваемый вызов.
Заниженный max_tokens на бесплатной модели с рассуждением поднимается автоматически. Если у бесплатной модели с рассуждением запрошен структурированный ответ, а max_tokens задан явно и ниже нижней границы, платформа поднимает его до этой границы и сообщает об этом на успешном ответе 200: в теле появляется массив warnings с элементом {"code": "MAX_TOKENS_RAISED", "message": "..."}. Это не ошибка — читайте warnings как необязательное поле. Если max_tokens в запросе не задан, правка не применяется.
В потоковом режиме ошибка (и восстановленный ответ) приходят внутри потока. Служебное событие {"error":{"code":"structured_output_truncated"}}, {"error":{"code":"structured_output_invalid_json"}} или {"error":{"code":"reasoning_repetition"}} идёт перед data: [DONE]. Во втором случае фрагменты ответа уже переданы — их следует отбросить, статус потока остаётся 200 по протоколу. Восстановленный из reasoning_content JSON приходит событием потока с полем content перед терминальным событием с finish_reason — читайте поток до конца.
json_object не проверяет структуру. Он гарантирует только то, что ответ разберётся как JSON, — набор полей и их типы остаются на усмотрение модели. Если структура важна, используйте json_schema со strict: true.
Повтор в оборванном JSON тоже даёт reasoning_repetition. При отсутствии repetition_guard или значении "off", с json_object или json_schema, если генерация завершилась по finish_reason: "length", непустой незавершённый JSON проверяется на повтор. При обнаруженном повторе приходят код reasoning_repetition и сообщение про JSON, без совета отключать рассуждение, без param и suggestedMaxTokens. Это эвристическая диагностика: она может сработать и на законном повторяющемся массиве, которому не хватило бюджета. Проверьте, ожидаемы ли повторы; если да, проверьте лимит токенов, иначе уточните запрос или смените модель. Проверка выполняется после завершения генерации и не сокращает ожидание. Короткая обрезка без обнаруженного повтора и целый JSON при length сохраняют structured_output_truncated; законный повторяющийся массив при нормальном завершении приходит целиком.