JSON Mode

[object Object]

JSON Mode — это набор техник и API-механизмов, которые заставляют модель вернуть ответ в JSON. В 2026 практический разговор уже не про "попросить JSON словами", а про выбор между legacy json_object, strict json_schema и tool arguments.

Если результат должен попасть в код, workflow или базу данных без ручной правки, свободный текст почти всегда хуже JSON.

Суть в двух словах

Есть три уровня надёжности:

ПромптGPT-5 mini
Верни JSON с полями: intent, priority, requires_human.

Текст: «Списали оплату дважды и не отвечают третий день»
Ответ модели

{"intent":"billing_issue","priority":"high","requires_human":true}

JSON нужен не ради красоты, а ради надёжного handoff между моделью и приложением. Чем дороже ошибка downstream, тем меньше стоит надеяться на "примерно такой формат".

Что важно понимать в 2026

JSON Mode и Structured Outputs — не одно и то же.

  • JSON Mode гарантирует форму JSON.
  • Structured Outputs или responseSchema гарантируют соответствие схеме.
  • Tool calls гарантируют корректные аргументы инструмента, но не всегда заменяют финальный JSON-ответ пользователю.

Это различие критично. Очень многие пайплайны ломаются не потому, что JSON невалиден, а потому что:

  • поля названы не так;
  • типы расходятся;
  • появляются дополнительные свойства;
  • модель заполняет обязательные поля мусором.

Decision framework

СценарийЧто обычно выбирать
Быстрый прототипjson_object или даже plain JSON request
Внутренний скрипт с tolerant parserJSON object mode
Запись в БДstrict schema
Tool invocationtool arguments
Multi-agent handoffstrict schema или typed tool payload

Практическое правило:

  1. Если downstream tolerant и человек рядом, можно начинать с JSON object.
  2. Если downstream strict и без ручного контроля, переходите на schema-first.
  3. Если JSON нужен только как параметры действия, чаще лучше tool call, а не отдельный JSON-ответ.

Когда использовать какой вариант

Плюсы

  • Удобен для API, workflows, ETL и agentic toolchains
  • Снижает хрупкость парсинга
  • Позволяет валидировать ответ до бизнес-логики
  • Хорошо сочетается с app-side validation

Минусы

  • Слишком сложные схемы делают промпт тяжелее
  • Некоторые модели при плохой схеме начинают заполнять поля мусором
  • JSON сам по себе не делает ответ фактически верным
  • Нужна валидация на стороне приложения даже при strict mode

Достаточно JSON object

Когда downstream tolerant:

  • internal scripts;
  • быстрый прототип;
  • лёгкий extraction без сложной вложенности.

Нужен strict schema

Когда downstream strict:

  • запись в БД;
  • запуск workflow;
  • tool orchestration;
  • интеграция между агентами;
  • compliance и audit-пайплайны.

Tool arguments удобнее отдельного JSON

Когда смысл задачи такой: "выбери параметры действия". Например:

  • вызвать triage_ticket;
  • отправить schedule_meeting;
  • заполнить crm_update.

В этих сценариях модель должна не "описать мир в JSON", а "подготовить валидные аргументы для действия".

Типичные ошибки

Без техники
Ответь строго JSON без комментариев
С техникой
Используй schema-constrained output и всё равно провалидацируй результат в приложении
Даже идеальный JSON может содержать неправильные факты. JSON решает проблему формата, но не проблему истинности.

Другие типовые ошибки:

  1. Делать схему слишком широкой и абстрактной.
  2. Разрешать additionalProperties, хотя проект не готов к дрейфу полей.
  3. Смешивать user-facing summary и machine payload в одном объекте без необходимости.
  4. Не задавать enum там, где вариантов конечное число.
  5. Не оставлять retry/repair strategy.

Как проектировать хорошую схему

Хорошая JSON-схема обычно:

  • короткая;
  • с минимальным числом обязательных полей;
  • с enum там, где это возможно;
  • без свободных словарей "на всякий случай";
  • с отдельным полем для uncertainty, если она важна.

Плохая схема обычно выглядит так:

  • 20-30 полей;
  • половина полей optional и плохо определена;
  • в каждом поле можно вернуть "что угодно";
  • названия полей слишком бизнес-специфичны и непонятны модели.

Практические сценарии

Triage обращения

ПромптGPT-5 mini
Верни JSON с полями: category, priority, requires_human, summary.

Обращение: «Списали оплату дважды, нужен возврат сегодня»
Ответ модели

{"category":"billing","priority":"high","requires_human":true,"summary":"Клиент сообщает о двойном списании и просит срочный возврат"}

Routing лида

ПромптClaude Sonnet 4.6
Верни JSON с полями: segment, intent, urgency, next_owner.

Входящий запрос: «Нам нужен enterprise-план, SSO и договор DPA до конца недели»
Ответ модели

{"segment":"enterprise","intent":"sales","urgency":"high","next_owner":"account_executive"}

В обоих примерах JSON полезен не потому, что он красивый, а потому что дальше его можно:

  • провалидировать;
  • залогировать;
  • отправить в следующий сервис;
  • использовать как часть automation chain.

Техническая реализация

OpenAI: schema-first подход

from openai import OpenAI

client = OpenAI()

response = client.responses.create(
    model="gpt-5-mini",
    text={
        "format": {
            "type": "json_schema",
            "name": "ticket_triage",
            "schema": {
                "type": "object",
                "properties": {
                    "category": {"type": "string"},
                    "priority": {"type": "string"},
                    "requires_human": {"type": "boolean"}
                },
                "required": ["category", "priority", "requires_human"],
                "additionalProperties": False
            },
            "strict": True
        }
    },
    input="Определи triage для обращения: «Списали оплату дважды»",
)

print(response.output_text)

Tool arguments как ещё один вариант

tools = [
    {
        "type": "function",
        "name": "triage_ticket",
        "parameters": {
            "type": "object",
            "properties": {
                "category": {"type": "string"},
                "priority": {"type": "string"}
            },
            "required": ["category", "priority"],
            "additionalProperties": False
        }
    }
]

Если задача по смыслу означает "выбери аргументы для действия", tool call обычно естественнее, чем отдельный JSON response.

App-side validation всё равно нужна

def validate_output(data):
    assert data["priority"] in {"low", "medium", "high"}

Даже при schema constraints оставляйте:

  • schema validation;
  • semantic validation;
  • fallback / retry policy;
  • safe defaults.

Retry + repair loop

def repair_or_retry(raw_text: str, validator):
    try:
        return validator(raw_text)
    except Exception:
        return None

В production почти всегда полезны:

  1. первая попытка со strict schema;
  2. быстрая валидация;
  3. retry на ту же схему при ошибке;
  4. fallback на human review или safe default.

Семантическая проверка

def semantic_validate_ticket(data: dict) -> dict:
    if data["category"] == "billing" and data["priority"] == "low":
        raise ValueError("billing issue with refund urgency looks misclassified")
    return data

Это отдельный слой поверх JSON-валидации. Он отвечает уже не за синтаксис, а за бизнес-правдоподобность результата.

Когда JSON не нужен

Не пытайтесь всё превращать в JSON, если:

  • результат в основном читает человек;
  • ответ исследовательский и структура ещё плавает;
  • важнее богатое объяснение, чем автоматизация;
  • machine payload можно вынести в отдельный маленький блок.

В этих случаях лучше дать модели markdown/memo, а typed payload получить отдельным шагом.

Проверьте себя

Проверьте себя

1. Что надёжнее для production-интеграции?

2. Что JSON не гарантирует?

3. Когда tool arguments удобнее финального JSON-ответа?