Сразу к делу: Structured Output — это не промпт «верни JSON». Это API, который на этапе декодирования отсекает недопустимые токены по JSON Schema, чтобы финальный ответ можно было разобрать программой. GPT, Gemini и Claude сделали это первоклассной возможностью не потому, что фраза хорошо смотрится на слайде, а потому что агенты, извлечение и заполнение форм должны встроить модель в конвейер. Проза не проходит JSON.parse. Через downstream Schema — тем более.
Статья датирована 8 сентября 2026. Все три уже умеют ограничивать финальный JSON для пользователя или следующего сервиса: OpenAI через response_format.json_schema (strict), Gemini через responseMimeType + responseJsonSchema, Claude через GA output_config.format (старый beta output_format ещё работает в переходный период). Как заполнять поля и чем отличаются подмножества, мы уже разобрали в августе. Этот текст отвечает на два вопроса: что это такое и почему все три были вынуждены это выпустить. Как внедрять — в От промпта к Structured Output. OpenAI vs Gemini — в сравнении Structured Output API.
Что такое Structured Output
Structured Output значит: вы даёте JSON Schema, и финальный ответ модели обязан быть JSON, который ей соответствует. Гарантия срабатывает в момент генерации каждого токена, а не после того, как модель «постаралась выглядеть как JSON». Названия расходятся: OpenAI пишет Structured Outputs, Google — Structured Output, Anthropic — structured outputs / JSON outputs. Лишняя s — брендинг. Задача одна.
Думайте про компилятор и проверку типов. Промпт — комментарий: модель может послушаться. Schema — система типов: неверное имя поля, отсутствующий required, строка вместо числа — такие токены просто не выпускаются. Программа получает объект, а не прозу в ограждении ```json.
| Формулировка | Что это на самом деле | Частая ошибка |
|---|---|---|
| Structured Output | Ограниченное декодирование финального ответа по JSON Schema | Модель стала умнее, или «она умеет писать JSON» |
| JSON Schema | Контракт полей, типов, required, enum | Просто более длинный промпт |
| Ограниченное декодирование | Недопустимые токены отсекаются в момент генерации | Потом почистить регулярками |
| strict / жёсткое ограничение | API гарантирует форму на более строгом подмножестве Schema | Факты верны, цифры не выдуманы |
Schema, которую читают все три, обычно плоская: корень object, явные properties / required, additionalProperties: false. В OpenAI strict «опциональное» чаще делают nullable, а не убирают из required. Подмножества не совпадают; сначала берите пересечение.
{
"type": "object",
"additionalProperties": false,
"properties": {
"task": { "type": "string", "enum": ["extract", "classify", "summarize"] },
"ok": { "type": "boolean" },
"fields": {
"type": "object",
"additionalProperties": false,
"properties": {
"orderId": { "type": "string" },
"total": { "type": "number" },
"note": { "type": ["string", "null"] }
},
"required": ["orderId", "total", "note"]
}
},
"required": ["task", "ok", "fields"]
}
Это не JSON Mode и не Tool Calling
Три названия часто схлопывают в одно. Это разные слои:
| Возможность | Что гарантирует | Чего не гарантирует |
|---|---|---|
| Промпт: «верни JSON» | Более высокую вероятность | Синтаксис, имена полей, списки required |
| JSON Mode | Текст — разбираемый JSON | Форму, типы, enum |
| Structured Output | Финальный ответ соответствует Schema | Семантическую истину и то, что инструмент уже выполнен |
| Tool Calling | Аргументы инструмента соответствуют Schema, Host их выполняет | Форму ответа пользователю |
JSON Mode гарантирует только парные скобки и успешный JSON.parse. Модель всё ещё может выдумать order_id, когда вы просили orderId, или отдать сумму строкой. В продакшене «парсится» — не значит «можно вставить в базу».
Tool Calling / Function Calling ограничивает руку, которая тянется к инструменту, а не последнюю фразу пользователю. Запросы остатков, запись файлов, MCP tools/call — на Schema инструмента. Извлечь письмо, классифицировать тикет, отдать JSON для downstream API — на Structured Output. Полный агент часто включает оба слоя: аргументы на tools, финальный ответ — на выходной Schema. Про слои — в Что такое MCP и потоке данных Agent JSON.
Почему все три начали это поддерживать
В 2023 ещё можно было ставить на промпт. В 2026 агент встраивает модель в цикл: вывод идёт в базу, в следующий инструмент или в модель другого вендора. Три лаборатории не согласовывали пресс-цикл. Они ударились об одно и то же продуктовое давление и один и тот же контракт — JSON Schema.
- Downstream-потребитель — программа, не читатель. Чат может быть прозой. Конвейеру нужны объекты. Одна пропущенная запятая, одно переименованное поле — и ночная очередь ретраев заполняется. Вендорам проще обрезать недопустимые пути в декодере, чем смотреть, как каждый клиент пишет свой ремонтник.
- Агенты сделали стабильную форму обязательной. В многошаговом цикле JSON прошлого хода — вход этого. Один дрейф — и дальше всё неверно. Tool Calling отвечает «как протянуть руку». Structured Output отвечает «как вернуть вывод». Обоим нужна Schema — см. станет ли JSON Schema контрактом агента.
- Промпты доказали, что их недостаточно. «Только JSON, без markdown» хорошо выглядит на бенчмарке, затем теряет поля, добавляет ограждения и перефразирует enum, когда контекст длинный, инструменты перезаливают ответ или языки смешиваются. Ограниченное декодирование превращает «иногда» в API 400 или в повторяемую ошибку Schema.
- JSON Schema уже был наименьшим общим знаменателем. OpenAPI, MCP
inputSchema, экспорт Pydantic / Zod — всё это оно. Частный IDL на стороне модели заставил бы Host переводить дважды. Подключить финальный ответ к той же Schema — вот что делает смену вендора дешёвой. - Гонка стала «можно ли в продакшен», а не «умеет ли болтать». Как только один вендор сделал жёсткое ограничение, шлюзы, фреймворки агентов и закупочные списки вписали это как обязательное. Остальным двум либо догонять, либо не встроиться в тот же граф. В сентябре 2026 флагманский API без Structured Output трудно продать тем, кто пишет строки в базу.
Поэтому даты сбились в кучу: OpenAI сделал Structured Outputs GA в августе 2024; Gemini сложил MIME + Schema в конфиг генерации; Claude в конце 2025 ещё сидел на beta-заголовке, а теперь отдаёт output_config.format как стабильное поле. Имена так и не совпали. Давление — да.
Как включают GPT, Gemini и Claude
Выровняйте понятие. Не копируйте поля между вендорами. Таблица — то, что можно положить в документ 8 сентября 2026, а не полный туториал SDK.
| Вендор | Точка входа | Куда вешается Schema | На что смотреть в 2026 |
|---|---|---|---|
| OpenAI (GPT-5.5 и родственные) | response_format в Chat Completions; text.format в Responses API | type: json_schema + strict: true | В strict у каждого object нужен additionalProperties: false, свойства обычно все сидят в required; опциональное становится nullable |
| Google (Gemini 3.7 Flash и родственные) | MIME + Schema в конфиге генерации | responseMimeType: application/json + responseJsonSchema (в SDK часто response_schema) | Переключателя с именем strict нет; старый responseSchema брал типы OpenAPI в верхнем регистре; новый канал — JSON Schema в нижнем |
| Anthropic (Claude 4.6 / 4.8 и родственные) | output_config.format в Messages API | type: json_schema + schema | GA — заголовок structured-outputs-2025-11-13 не нужен; старый output_format ещё работает в переходный период. strict: true на стороне инструмента — это Tool Calling, не финальный ответ |
Обёртки разные. Тело Schema должно быть одним файлом. Смена модели меняет конверт, не orderId и required. Набросок для Claude (поля спецификации; подставьте свою бизнес-схему):
{
"model": "claude-sonnet-4-6",
"max_tokens": 1024,
"messages": [
{"role": "user", "content": "Extract orderId and total from the order text"}
],
"output_config": {
"format": {
"type": "json_schema",
"schema": {
"type": "object",
"additionalProperties": false,
"properties": {
"orderId": { "type": "string" },
"total": { "type": "number" }
},
"required": ["orderId", "total"]
}
}
}
}
OpenAI кладёт ту же schema в response_format.json_schema и включает strict. Gemini кладёт её в responseJsonSchema и объявляет JSON MIME. Полное сравнение на Python по-прежнему в OpenAI vs Gemini. Продуктовые поверхности (ChatGPT / claude.ai / веб-приложение Gemini) не всегда открывают то же жёсткое ограничение. SLA пишите против того API, который реально вызываете.
Что на самом деле блокирует ограниченное декодирование
Без Structured Output модель сэмплирует весь словарь и надеется, что промпт заставит её выглядеть как JSON. Со Structured Output декодер держит легальный префикс по Schema: следующий токен может быть только тем, что ещё валидно — ", orderId, true или }. Недопустимые пути получают вероятность ноль.
Оно блокирует форму: висячие запятые, markdown-ограждения, отсутствующие required-поля, дрейф типов, лишние ключи при additionalProperties false. Оно не блокирует выдумку: total — число, и число может быть выдумано; легальное значение enum всё равно может быть не тем. В продакшене ту же Schema всё равно прогоняют через валидатор; при ошибке — ретрай, деградация или человек. Ограниченное декодирование снижает аварии парсинга, не галлюцинации.
Большее окно этого не меняет. 1M токенов только расширяют видимость; они не ограничивают форму вывода. Засунули дамп — Schema всё равно нужна, см. окна контекста 1M токенов.
Что делать сейчас
- Сначала напишите Schema, потом выбирайте модель. Имена полей, списки required и enum — продуктовый контракт. GPT / Gemini / Claude — сменные бэкенды. Контракт держите в репозитории, не в промпте.
- Извлечение, классификация, заполнение форм — Structured Output. Побочные эффекты — Tool Calling. Не притворяйтесь, что Structured Output уже сходил в inventory API. Когда инструмент в другом процессе и его нужно переиспользовать между Host — добавляйте MCP.
- Берите пересечение Schema между вендорами: плоские object,
additionalProperties: false, мелкий$ref, без корневогоanyOf. OpenAI strict превращает «опциональное» в nullable. Не ведите три дрейфующие таблицы полей. - Проход API — не последняя проверка. Сохраните Schema и две–три хорошие / плохие фикстуры как JSON; проверьте и сделайте Diff на этом сайте. Ничего не загружается. Это второй шлюз после ограниченного декодирования.
- Возвращайте ошибки структурой: если парсинг или второй валидатор упал, отдайте объект (какое поле, ожидаемый тип). Не заливайте сырой стек в следующий ход.
FAQ
Structured Output — это просто «заставить модель вернуть JSON»?
Нет. Промпт или JSON Mode тоже могут выдать текст JSON. Structured Output на этапе декодирования фильтрует токены по JSON Schema. Имена полей, типы и списки required обеспечивает API, а не «сознательность» модели.
Почему GPT, Gemini и Claude все это выпустили — разве одного вендора мало?
Клиентам нужны мультимодельный failover и сравнение цен. Шлюзы и фреймворки агентов уже соединены как «Schema на входе, JSON на выходе». Вендор без жёсткого ограничения в этот конвейер не встраивается. Конкурентное давление и инженерная нужда — один и тот же факт.
Нужен ли Claude всё ещё фейковый инструмент, чтобы притвориться Structured Output?
Не как основной путь. В 2026 Messages API отдаёт JSON Schema через output_config.format. strict на уровне инструмента по-прежнему покрывает только аргументы. Старый beta-заголовок и output_format остаются в переходном окне; новый код должен идти через output_config.
Если Structured Output включён, всё равно проверять?
Да. Оно гарантирует форму и типы, не истинные значения и не бизнес-правила. Прогоните ту же Schema ещё раз в приложении; при ошибке — ретрай или эскалация. В браузере сначала проверьте фикстуры JSON-инструментами.
Как выбрать между этим, MCP и Tool Calling?
Финальный ответ для программы: Structured Output. Внешнее действие: Tool Calling. Инструменты в другом процессе, переиспользуемые между Host: MCP. Три слоя можно сложить. Не давайте одному слою изображать другой.
Можно ли один JSON Schema отправить всем трём как есть?
Тело можно делить; обёртку запроса — нет. Плоский object, без лишних свойств, опциональные как nullable — побеждает чаще всего. Подмножество OpenAI strict самое жёсткое: сначала пройдите его, затем отдайте тот же файл Gemini / Claude, вместо трёх дрейфующих Schema.
Итоги
Structured Output — розетка флагманских API 2026: финальный ответ декодируется по JSON Schema, и программы перестают ставить на скобки в промпте. GPT, Gemini и Claude все это выпустили, потому что агенты и извлечение вписали «стабильную форму» в приёмку, а JSON Schema был контрактом, на котором все три уже говорили. Это не JSON Mode. Это не замена Tool Calling или MCP.
Меняете модель — меняйте только поля обёртки. Имена полей и required держите в репозитории и до запуска проверяйте образцы локально той же Schema. Как настраивать каждый API и как это делится со слоем инструментов, этот сайт уже разобрал. Эта статья делает однозначными только «что» и «почему».