Когда ответ модели читает не человек, а код — парсер заявок, классификатор, извлечение полей из документа, — нужен строгий JSON. В формате OpenAI Chat Completions для этого есть параметр response_format. Heli передаёт его модели как есть, поэтому JSON mode и Structured Outputs работают через https://getheli.ru/v1 у всех моделей каталога, которые их поддерживают.
Два режима
- JSON mode: response_format {"type": "json_object"}. Модель гарантированно вернёт синтаксически валидный JSON, но структура полей не контролируется. В сообщениях обязательно должно быть слово JSON — без него часть моделей отклоняет запрос.
- Structured Outputs: response_format {"type": "json_schema", ...} с JSON Schema и strict: true. Ответ соответствует схеме: все поля из required на месте, лишних нет.
- В strict-режиме все свойства перечисляются в required, а у объектов задаётся additionalProperties: false. Необязательное поле описывается типом с null.
- Поддержка режимов зависит от модели. Перед запуском в продакшн проверьте выбранную модель коротким запросом со своей схемой.
Пример на Python
Даже со схемой проверяйте результат в коде: валидируйте его через pydantic или jsonschema и обрабатывайте отказ модели — в этом случае поле refusal заполнено, а content пустой. В Python SDK есть метод client.chat.completions.parse, который принимает модель pydantic и строит схему сам.
import json
import os
from openai import OpenAI
client = OpenAI(base_url="https://getheli.ru/v1", api_key=os.environ["HELI_API_KEY"])
resp = client.chat.completions.create(
model="openai/gpt-5.4-mini",
messages=[
{"role": "system", "content": "Извлеки данные заказа. Ответ — только JSON."},
{"role": "user", "content": "Иван, две пиццы и сок, доставка к 19:00"},
],
response_format={
"type": "json_schema",
"json_schema": {
"name": "order",
"strict": True,
"schema": {
"type": "object",
"properties": {
"name": {"type": "string"},
"items": {"type": "array", "items": {"type": "string"}},
"time": {"type": ["string", "null"]},
},
"required": ["name", "items", "time"],
"additionalProperties": False,
},
},
},
max_tokens=500,
)
choice = resp.choices[0]
if choice.finish_reason == "length":
raise RuntimeError("Ответ обрезан: увеличьте max_tokens")
order = json.loads(choice.message.content)
print(order["items"])Какие модели выбрать
Для извлечения полей и классификации обычно хватает быстрых моделей со строгой схемой. Сильная модель нужна, когда сначала надо понять сложный документ, а потом заполнить много вложенных полей.
GPT-5.4 mini — строгие схемы, извлечение данных.
Gemini 3.5 Flash — массовая классификация.
Claude Sonnet 5 — сложные документы и вложенные структуры.
Частые ошибки
- Ошибка о неподдерживаемом response_format — модель не умеет json_schema; используйте json_object с описанием структуры в промпте или другую модель.
- Ошибка про слово JSON — в режиме json_object добавьте в system-сообщение явное требование отвечать в JSON.
- Невалидный или оборванный JSON — ответ упёрся в max_tokens; проверяйте finish_reason и увеличьте лимит.
- 401 и 402 — неверный ключ или закончился баланс; проверьте вкладки «Ключи» и «Баланс».
- Таймауты на больших документах — разбейте документ на части и извлекайте поля по частям.
Оплата — пополнение баланса.
Попробуйте Heli
Ключ sk-heli- появляется после подтверждения почты. Через Google и Яндекс — сразу в кабинете.