Когда ответ модели читает не человек, а код, свободный текст мешает. Нужен JSON с заранее известными полями: разобрать отзыв, вытащить реквизиты из письма, разложить заявку по полям CRM. Для этого в OpenAI-совместимом API есть параметр response_format, а в PlusVibe он работает через тот же /v1/chat/completions, что и обычный чат.
Ниже — три способа получить JSON, от мягкого к строгому, и примеры, которые мы запустили перед публикацией.
Три способа получить JSON
json_object— модель обязана вернуть валидный JSON, но какие в нём поля, вы описываете словами в промпте. Работает на большинстве моделей.json_schemaсоstrict: true— вы передаёте JSON Schema, и модель заполняет ровно эти поля нужных типов. Поддерживается моделями GPT-5.x и совместимыми.- Вызов функции — схема описывается как параметры инструмента, а
tool_choiceзаставляет модель его вызвать. Аргументы вызова и есть нужный JSON. Этот способ выручает на моделях безjson_schema.
json_object: просто валидный JSON
Самый совместимый режим. Опишите поля в системном промпте и включите response_format:
curl https://plusvibeapi.ru/v1/chat/completions \
-H "Authorization: Bearer $PLUSVIBE_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"model": "deepseek-v4.1-flash",
"response_format": {"type": "json_object"},
"messages": [
{"role": "system", "content": "Верни JSON с полями city (строка) и date (строка в формате YYYY-MM-DD). Год 2026."},
{"role": "user", "content": "Встречаемся в Самаре 3 октября"}
]
}'
Модель вернула в content строку {"city":"Самара","date":"2026-10-03"}. Обратите внимание на две вещи. Слово «JSON» должно встречаться в сообщениях: тот же запрос без него к gpt-5.6-luna у нас вернул ошибку 400. И соблюдение полей и типов здесь никто не гарантирует. Проверять ответ на своей стороне всё равно нужно.
json_schema: ответ строго по схеме
Если поля и типы важны, передайте схему целиком. Пример — разбор отзыва покупателя:
import json
import os
from openai import OpenAI
client = OpenAI(
base_url="https://plusvibeapi.ru/v1",
api_key=os.environ["PLUSVIBE_API_KEY"],
)
schema = {
"type": "object",
"properties": {
"product": {"type": "string"},
"sentiment": {"type": "string", "enum": ["positive", "neutral", "negative"]},
"score": {"type": "integer", "minimum": 1, "maximum": 5},
"issues": {"type": "array", "items": {"type": "string"}},
},
"required": ["product", "sentiment", "score", "issues"],
"additionalProperties": False,
}
resp = client.chat.completions.create(
model="gpt-5.6-luna",
response_format={
"type": "json_schema",
"json_schema": {"name": "review", "strict": True, "schema": schema},
},
messages=[
{"role": "system", "content": "Разбери отзыв покупателя."},
{"role": "user", "content": "Наушники звучат отлично, но кейс поцарапался через неделю."},
],
)
data = json.loads(resp.choices[0].message.content)
print(data)
В нашем прогоне пришёл объект с четырьмя полями: product — «Наушники», sentiment — neutral, score — 3 и список issues с жалобой на кейс. Лишних полей не было.
Правила строгой схемы
- Все поля перечислены в
required. Если поле может отсутствовать, сделайте его тип["string", "null"]— модель вернётnull. - В каждом объекте, включая вложенные, стоит
"additionalProperties": false. enum— лучший способ ограничить значения: модель не придумает четвёртую тональность.- Поле
nameвjson_schemaобязательно. Это просто метка, на ответ оно не влияет.
Что делает шлюз со strict: true, описано в документации. PlusVibe отправляет такой запрос только на те варианты модели, которые схему действительно соблюдают, в том числе при переключении на резервный маршрут. Если подходящего варианта сейчас нет, вы получите ошибку, а не обычный текст вместо JSON.
Pydantic: схема из класса
В Python не обязательно писать схему руками. Метод parse из официального SDK строит её из Pydantic-модели и сразу возвращает готовый объект:
from typing import Literal
from pydantic import BaseModel
class Review(BaseModel):
product: str
sentiment: Literal["positive", "neutral", "negative"]
score: int
issues: list[str]
completion = client.chat.completions.parse(
model="gpt-5.6-luna",
messages=[
{"role": "system", "content": "Разбери отзыв покупателя."},
{"role": "user", "content": "Наушники звучат отлично, но кейс поцарапался через неделю."},
],
response_format=Review,
)
review = completion.choices[0].message.parsed
print(review.sentiment, review.score, review.issues)
Пример проверен с openai 2.x. Если вы используете PydanticAI, у нас есть отдельная статья про PydanticAI в России.
То же самое в Responses API
В /v1/responses схема передаётся не в response_format, а в text.format, и поля name, strict, schema лежат на одном уровне с type:
resp = client.responses.create(
model="gpt-5.6-luna",
input="Извлеки город и дату: «Встречаемся в Самаре 3 октября»",
text={"format": {
"type": "json_schema",
"name": "meeting",
"strict": True,
"schema": {
"type": "object",
"properties": {"city": {"type": "string"}, "date": {"type": "string"}},
"required": ["city", "date"],
"additionalProperties": False,
},
}},
)
print(json.loads(resp.output_text)) # {'city': 'Самара', 'date': '3 октября'}
Чем ещё Responses отличается от Chat Completions, мы разобрали в статье Responses API и Chat Completions.
Если модель не поддерживает json_schema
Не у всех моделей есть строгий режим. У DeepSeek, например, его нет: запрос с json_schema и strict: true к deepseek-v4.1-flash у нас завершился ошибкой 400. Для таких моделей два пути:
json_objectплюс описание полей в промпте и проверка ответа в коде — как в первом примере.- Вызов функции с принудительным
tool_choice: схема становится параметрами функции, а модель обязана её вызвать. Пример — в статье про function calling.
Поддержку заранее можно проверить через GET /v1/model-capabilities с вашим ключом: у каждой модели есть поле capabilities.jsonMode, а в supported_parameters указано, поддерживается ли response_format.
Частые ошибки
Ответ обрезан, JSON не парсится. Модели не хватило лимита токенов. У рассуждающих моделей в лимит входят и токены рассуждения, поэтому max_tokens ставьте с запасом или не ставьте совсем.
400 при строгой схеме. В схеме нет additionalProperties: false, не все поля перечислены в required или модель не поддерживает json_schema.
Поля на месте, но значения странные. Схема гарантирует форму, а не смысл. Добавьте в описание поля (description) пояснение, что туда класть, и сузьте значения через enum.
Итог
Для быстрого прототипа хватит json_object. В продакшене берите json_schema со strict: true на моделях GPT-5.x или вызов функции на моделях без строгого режима. Все три способа работают через один ключ PlusVibe. Модели и цены — в каталоге, формат параметров — в документации.
JSON по схеме через один API
GPT, Claude, DeepSeek и другие модели через OpenAI-совместимый API. Оплата в рублях.
Получить ключ →


