Dev48
ЯЗЫК
  • О нас
  • Услуги
  • Индустрии
  • Технологии
  • Статьи
  • Контакты
Забронировать звонок
    Главная/Статьи/Kak poluchit strukturirovannyy vyvod ot lyuboy llm json schema vyzovy instrument
Dev48
info@dev48.org+375 29 320-40-96WhatsApp@isky_by

© 2026 · Все права защищены.

Как получить структурированный вывод от любой LLM: JSON Schema, вызовы инструментов или модель принятия решений

Источник: OpenRouter Blog•10 ноября 2026 г. в 18:17

Как получить структурированный вывод от любой LLM: JSON Schema, вызовы инструментов или модель принятия решений

Когда ваш код считывает поля из ответа модели, такие как ID заказа или сумма возврата, он ожидает чистый JSON в каждом случае. В большинстве случаев он его получает. Но временами модель оборачивает JSON в блок кода, добавляет поле, о котором вы не просили, или передает число в виде текста, и ваш…

Когда ваш код считывает поля из ответа модели, такие как ID заказа или сумма возврата, он ожидает чистый JSON в каждом случае. В большинстве случаев он его получает. Но временами модель оборачивает JSON в блок кода, добавляет поле, о котором вы не просили, или передает число в виде текста, и ваш код ломается. Если вы используете несколько моделей, одно исправление не подойдет для всех, потому что каждая модель и провайдер обрабатывают структурированный вывод по-своему.

Существует три способа получить надежный структурированный вывод LLM, и правильный выбор зависит от того, что поддерживает модель. Если она поддерживает структурированные выводы, отправьте ей строгую JSON Schema. Если она поддерживает только инструменты, заставьте ее вызвать инструмент, который использует вашу схему. А если вам нужна только метка, например «возврат» или «обмен», используйте вместо этого модель принятия решений. На OpenRouter все три способа работают с одним ключом API и одним форматом запроса.

Чтобы проверить эффективность каждого способа, мы протестировали их на 24 запутанных сообщениях службы поддержки с использованием девяти моделей, поддерживающих структурированные выводы, а также GLM 5.3 FlashX, которая поддерживает только инструменты. Среди девяти моделей 209 из 216 ответов соответствовали строгой схеме, а все 7 неудачных ответов поступили от одного провайдера, который игнорирует схему. Когда мы запрашивали только JSON в промпте, 18 ответов оказались неудачными, каждый раз из-за блока кода.

TL;DR

  • Отправьте строгую схему в response_format и установите require_parameters: true, чтобы запрос завершался ошибкой, если ее не поддерживает ни одна конечная точка.

Отправьте строгую схему в response_format и установите require_parameters: true, чтобы запрос завершался ошибкой, если ее не поддерживает ни одна конечная точка.

  • Если у модели есть только инструменты, поместите схему в один инструмент и принудительно вызовите его.

Если у модели есть только инструменты, поместите схему в один инструмент и принудительно вызовите его.

  • Оставьте функцию Response Healing включенной для поврежденного JSON и проверяйте каждый ответ самостоятельно. Некоторые конечные точки принимают строгую схему и все равно нарушают ее.

Оставьте функцию Response Healing включенной для поврежденного JSON и проверяйте каждый ответ самостоятельно. Некоторые конечные точки принимают строгую схему и все равно нарушают ее.

  • Если вам нужна только метка, модель принятия решений, такая как Jev, возвращает вероятности для ваших вариантов, поэтому парсить ничего не нужно.

Если вам нужна только метка, модель принятия решений, такая как Jev, возвращает вероятности для ваших вариантов, поэтому парсить ничего не нужно.

Шаг 1: Напишите схему, которую принимает каждый провайдер

Когда у провайдера есть строгий режим (strict mode), модель может писать только такой текст, который делает вывод действительным в соответствии с вашей схемой. Именно поэтому блоки кода и лишний текст не появляются в выводе строгого режима.

Для этого строгому режиму OpenAI необходимо знать каждый ключ заранее. Каждое свойство должно быть перечислено в required, а для каждого объекта должно быть задано дополнительное свойство additionalProperties: false. Если значение может отсутствовать, вы добавляете null к его типу вместо того, чтобы пропускать ключ.

Это были самые строгие правила, которые мы обнаружили, и схема, следующая им, работала на каждой опробованной нами модели. Когда мы добавили необязательное поле note, модель GPT-6 Luna отклонила запрос со следующей ошибкой.

Недопустимая схема для response_format «ticket»: В контексте=(), поле «required» должно быть предоставлено и быть массивом, включающим каждый ключ в properties. Отсутствует «note».

Claude Haiku 5.5 и Mistral Large 4 приняли ту же схему и заполнили поле note. Gemini 3.8 Flash приняла ее и оставила note пустым. Поэтому, если поле является необязательным, сделайте его обязательным и допускающим значение null (nullable).

Шаг 2: Отправьте схему или принудительно вызовите один инструмент

Вы можете передать одну и ту же схему модели двумя способами. В response_format она управляет текстом сообщения. В качестве параметров инструмента она управляет аргументами вызова инструмента, и провайдеры со строгим вызовом инструментов применяют там те же ограничения. Таким образом, если вы заставите модель вызвать этот единственный инструмент и сохранить его аргументы, вы получите структурированный вывод от модели, у которой есть инструменты, но нет структурированных выводов. Ваш код никогда не запускает сам инструмент.

Приведенный ниже скрипт выполняет оба действия и проверяет каждый результат с помощью jsonschema. Затем он показывает два сбоя на GLM 5.3 FlashX — модели, у которой есть инструменты, но нет структурированных выводов.

Вот что он вывел, когда мы запустили его 20 октября 2026 года.

Оба способа превратили #482913 в ORD-482913, а $1,249.50 — в число. Тем не менее, намерение может меняться от запуска к запуску. В более раннем запуске GPT-6 Luna выбрала damaged_item вместо refund, потому что этот короткий промпт не объясняет, что означает каждое намерение. Схема контролирует форму ответа, а ваши инструкции — значения.

Если вы вызываете модель Claude с параметром «strict»: true для инструмента, также отправьте заголовок x-anthropic-beta: structured-outputs-2025-11-13. Без него мы удаляем strict, и провайдер не применяет схему к аргументам инструмента. Вам не нужен этот заголовок для response_format, потому что мы добавляем его туда за вас.

Сохраняйте шаг проверки даже для моделей, которые принудительно применяют схемы. Сбои, описанные далее в этом руководстве, вернулись со статусом 200 OK и finish_reason: «stop», и их обнаружил только валидатор.

Шаг 3: Сделайте так, чтобы неподдерживаемая схема завершалась с громкой ошибкой

Поддержка структурированных выводов принадлежит каждой конечной точке (endpoint), то есть каждому провайдеру, который обслуживает модель, а не самой модели. Документация по структурированным выводам говорит о том же самом. 8 октября 2026 года 386 из 469 идентификаторов моделей в нашем API моделей указывали structured_outputs в supported_parameters, 401 указывали tools, а 55 имели инструменты, но не имели структурированных выводов.

Когда у модели есть конечные точки, поддерживающие response_format, и те, которые не поддерживают, мы уже отправляем запрос на ту, которая поддерживает. У DeepSeek V4.1 Flash было 23 конечные точки структурированного вывода из 31, и каждый запрос json_schema в наших запусках попадал на одну из 23.

Проблема заключается в модели, у которой ни одна конечная точка ее не поддерживает. По умолчанию запрос все равно проходит, и схема игнорируется. GLM 5.3 FlashX вернула 0 действительных выводов из 24 при таком подходе. Каждый ответ был обернут в блок кода, а в некоторых были поля, которые схема не разрешает.

Чтобы остановить это, установите require_parameters: true в объекте провайдера. После этого мы используем только те конечные точки, которые поддерживают каждый отправленный вами параметр. Если ни одна из них не поддерживает, запрос завершается ошибкой 404 (третья строка вывода выше), и ваш код может попробовать другую модель.

Шаг 4: Принудительный вызов инструмента способом, который принимает провайдер

Обычный способ принудительного вызова инструмента — это именованный tool_choice. Некоторые провайдеры отклоняют его, как показывает ошибка 400 в GLM выше. tool_choice: «required» означает «вызвать любой инструмент». Когда в запросе всего один инструмент, это принудительно вызывает именно его.

GLM вернула 22 действительных вывода из 24 при таком подходе. Два сбоя содержали строку «null» в order_id, чего шаблон схемы не допускает. Это означает, что данный провайдер не применяет схему к аргументам инструментов.

Вы можете посмотреть, какие значения tool_choice принимает конечная точка, в параметре supports_tool_choice из GET /api/v1/models/{author}/{slug}/endpoints. Однако это поле может быть неверным. 20 октября конечная точка GLM указывала required как неподдерживаемое, но описанный выше вызов «required» все равно работал при каждом запуске в тот день. Поэтому используйте это поле в качестве ориентира и тестируйте вызов самостоятельно.

Если в ответе нет tool_calls, значит, модель ответила простым текстом. Шаг 5 Preview сделал это один раз за 24 принудительных вызова, и скрипт возвращает для него «no output».

Определения инструментов также добавляют входные токену. Мы отправили запрос скрипта пять раз в обе стороны для девяти моделей. На восьми из них принудительный вызов инструмента использовал больше токенов промпта: от 23 дополнительных на Mistral Large 4 до 440 дополнительных на DeepSeek V4.1 Flash. Gemini 3.8 Flash была единственной моделью, которая использовала меньше.

Тем не менее, дополнительный ввод не определил стоимость. Большинство моделей записали меньше токенов, когда отвечали через инструмент, поэтому принудительный вызов инструмента обошелся дешевле на шести из девяти моделей. Количество токенов, записываемых моделью, меняется от запуска к запуску, поэтому проверяйте стоимость на своих собственных запросах.

Полный цикл работы с инструментами см. в разделе Вызов инструментов для любой модели.

Шаг 5: Оставьте исправление ответов (Response Healing) включенным для синтаксических ошибок

Плагин Response Healing исправляет JSON-вывод LLM после завершения работы модели. Он удаляет маркеры кода и исправляет поврежденный JSON, например пропущенную скобку или лишнюю запятую. Он не читает вашу схему.

На GLM он увеличил количество успешных выводов json_schema с 0 до 19 из 24, и все 24 ответа были успешно разобраны как JSON. В остальных пяти все еще оставалось поле, не разрешенное схемой. Это обнаруживает только провайдер, принудительно применяющий схему, или ваш собственный валидатор.

У плагина есть несколько ограничений, о которых вам следует знать.

  • Он запускается только тогда, когда в запросе для response_format задано значение json_schema или json_object. Именно так он понимает, что ответ должен быть в формате JSON. Когда мы помещали схему только в промпт, маркеры кода оставались неизменными.

Он запускается только тогда, когда в запросе для response_format задано значение json_schema или json_object. Именно так он понимает, что ответ должен быть в формате JSON. Когда мы помещали схему только в промпт, маркеры кода оставались неизменными.

  • Он работает только для запросов без потоковой передачи (streaming).

Он работает только для запросов без потоковой передачи (streaming).

  • Он не затрагивает аргументы вызова инструментов.

Он не затрагивает аргументы вызова инструментов.

  • Он не может исправить ответ, усеченный параметром max_tokens. Именно поэтому скрипт сначала проверяет finish_reason на наличие значения length.

Он не может исправить ответ, усеченный параметром max_tokens. Именно поэтому скрипт сначала проверяет finish_reason на наличие значения length.

На моделях, которые принудительно применяют схему, ему нечего было исправлять, поэтому нет причин отключать его.

Что надежнее: схема JSON или вызов инструментов?

На эндпоинтах, принудительно применяющих схемы, оба способа почти всегда возвращали валидный вывод. Каждая ячейка ниже представляет собой количество валидных выводов из 24 (по одному запуску на каждый) с использованием промпта, определяющего каждое намерение.

Если не учитывать Qwen, схема json_schema была валидной 192 раза из 192, а принудительный вызов инструмента — 191 раз из 192. Режим JSON («type»: «json_object» со схемой в промпте) был валидным 216 раз из 216. Режим JSON гарантирует только то, что вывод является JSON. Правильная форма получилась благодаря тому, что модели следовали промпту, а не принудительному применению.

Qwen 3.8 Omni Flash показывает, как выглядит эндпоинт, который не принудительно применяет схему. Единственный провайдер этой модели перечисляет структурированные выводы, но относится к схеме как к рекомендации. Семи ответов обернули тикет в массив, а принудительные вызовы инструментов возвращали refund_amount_usd в виде строки («89.98») для каждого тикета с возвратом средств. Параметр required был отклонен с этой ошибкой.

Параметр tool_choice не поддерживает установку в значение required или object в режиме мышления (thinking mode).

Режим JSON был валидным 24 раза из 24 на Qwen. Таким образом, для этой модели режим JSON со схемой в промпте работает лучше, чем json_schema.

Когда выводом является метка, используйте модель принятия решений

Некоторые поля, такие как intent и needs_human, являются решениями. Одно из них — выбор из фиксированного списка, а другое — да или нет. Чат-модель записывает эти ответы в виде текста, поэтому ей требуются схема и валидатор.

Модель принятия решений, такая как Jev, ничего не пишет. Она оценивает перечисленные вами варианты и возвращает вероятность для каждого из них, используя ваши собственные ключи, поэтому ее ответ не может вернуться в неправильной форме. Вы вызываете ее через API решений, передавая входные данные в качестве состояния (state) и короткое описание каждого варианта в критериях (criteria).

noul — это вероятность того, что ответ «да». Вы выбираете пороговое значение, с которым сравниваете его, и этот порог определяет, как часто сообщения передаются человеку. Здесь угроза возвратного платежа (chargeback) подняла значение needs_human примерно до 0.8, несмотря на то, что возврат составляет всего 120 долларов. Значение немного менялось между запусками (от 0.77 до 0.83), поэтому оставляйте некоторый запас вокруг своего порогового значения.

Мы задали те же два вопроса для всех 24 сообщений и сравнили Jev с двумя чат-моделями, которые возвращали строгую схему из двух полей.

Все три модели правильно определили каждую метку на этом небольшом наборе, а Jev обошелся примерно в два раза дешевле, чем GPT-6 Luna. Задержка указана для нашей настройки с шестью одновременными запросами. Сначала мы пометили одно сообщение как damaged_item, а затем изменили его на exchange после того, как каждая модель ответила exchange на запрос «send replacements».

Jev не извлекает ID или элементы, поэтому используйте его вместе с вызовом схемы или вместо него, когда вам нужны только метки. Jev также слабо справляется с арифметикой, поэтому сначала протестируйте правило вроде «возврат средств свыше 200 долларов» на собственных данных. В сравнении Jev и LLM сопоставляются на более крупном наборе.

Какой способ использовать

Выбирайте способ в зависимости от того, какой результат вам нужен и что поддерживают эндпоинты модели.

Вы можете узнать, какие модели поддерживают каждый вариант, на странице моделей или в поле supported_parameters из API моделей.

Часто задаваемые вопросы

Что означает структурированный вывод JSON?

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

Является ли режим JSON тем же самым, что и структурированные выводы?

Нет. Режим JSON («type»: «json_object») гарантирует только валидный JSON. Структурированные выводы («type»: «json_schema») отправляют вашу схему, а провайдеры со строгим режимом заставляют вывод соответствовать ей.

Гарантирует ли строгий режим вывод, соответствующий схеме?

Только там, где это обеспечивается провайдером. Некоторые провайдеры относятся к схеме как к сильной подсказке, и в нашем тесте один эндпоинт проигнорировал strict: true в 7 запросах из 24.

В чем разница между вызовом функций и структурированными выводами?

Структурированные выводы применяют вашу схему к тексту сообщения. Вызов функций, также называемый вызовом инструментов, применяет ее к аргументам вызова инструмента.

Можно ли передавать структурированный вывод в режиме стриминга?

Да. Добавьте stream: true в запрос json_schema. Response Healing не работает для запросов со стримингом, поэтому проверяйте полный ответ после окончания потока.

Как получить структурированный вывод от модели, которая его не поддерживает?

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

Следующие шаги

  • Наша документация по структурированным выводам охватывает формат запросов и потоковую передачу.

Наша документация по структурированным выводам охватывает формат запросов и потоковую передачу.

  • В разделе маршрутизации провайдеров описываются require_parameters и заголовок Anthropic для строгих инструментов.

В разделе маршрутизации провайдеров описываются require_parameters и заголовок Anthropic для строгих инструментов.

  • Учебное пособие по Jev охватывает типы вопросов Choice, Noul и Score.

Учебное пособие по Jev охватывает типы вопросов Choice, Noul и Score.

← Все статьи

О чём эта статья

Ещё в разделе «AI и машинное обучение»

Все →
MCP против CLI против Skills: стоимость в контексте
OpenRouter

MCP против CLI против Skills: стоимость в контексте

Квантование LLM: как fp8 и fp4 влияют на качество и цену
OpenRouter

Квантование LLM: как fp8 и fp4 влияют на качество и цену

Ограничения скорости API LLM: как исправить ошибки 429 для OpenAI и Claude
OpenRouter

Ограничения скорости API LLM: как исправить ошибки 429 для OpenAI и Claude

WAV против MP3: как выбрать правильный формат аудиофайла
ElevenLabs

WAV против MP3: как выбрать правильный формат аудиофайла

ERNIE Light DT 1.0 против Ling 3.1 Flash: 25-кратная разница в цене в одной весовой категории
OrcaRouter

ERNIE Light DT 1.0 против Ling 3.1 Flash: 25-кратная разница в цене в одной весовой категории

ERNIE 5.5 Flash против ERNIE 5.5 Flash Base: одну можно скачать, другую можно только арендовать
OrcaRouter

ERNIE 5.5 Flash против ERNIE 5.5 Flash Base: одну можно скачать, другую можно только арендовать

Ещё от OpenRouter

MCP против CLI против Skills: стоимость в контексте
OpenRouter

MCP против CLI против Skills: стоимость в контексте

Квантование LLM: как fp8 и fp4 влияют на качество и цену
OpenRouter

Квантование LLM: как fp8 и fp4 влияют на качество и цену

Ограничения скорости API LLM: как исправить ошибки 429 для OpenAI и Claude
OpenRouter

Ограничения скорости API LLM: как исправить ошибки 429 для OpenAI и Claude

Как создать голосового ИИ-агента
OpenRouter

Как создать голосового ИИ-агента

Лучшая модель OCR для сканированных документов: результаты измерений
OpenRouter

Лучшая модель OCR для сканированных документов: результаты измерений

Как Sentry ограничила бесконтрольные расходы на ИИ без ограничения доступа
OpenRouter

Как Sentry ограничила бесконтрольные расходы на ИИ без ограничения доступа