Получение строгого JSON

Когда ответ модели нужен не человеку, а коду, он должен быть машиночитаемым — обычно это JSON.

Структурированный вывод — режим, в котором модель обязана вернуть данные в заданном формате (JSON по схеме), а не свободный текст.

Зачем строгий JSON

Если LLM извлекает из письма имя, email и сумму, вам нужен объект {"name": ..., "email": ..., "amount": ...}, который код тут же распарсит. Свободный текст «Имя клиента — Иван, почта...» придётся разбирать регулярками — хрупко и ненадёжно.

Способ 1: попросить в промпте (слабый)

Самый простой путь — попросить в системном промпте: «верни только JSON по схеме». Работает, но не гарантирует: модель может добавить пояснение, обернуть в Markdown-блок ```json, ошибиться в кавычках. Поэтому ответ всё равно надо валидировать.

system = (
    "Извлеки данные из текста. Верни ТОЛЬКО JSON-объект с полями "
    "name (строка), email (строка), amount (число). Без пояснений и markdown."
)

Способ 2: structured outputs / схема (надёжный)

Провайдеры дают режим, гарантирующий валидный JSON по JSON-схеме. У Anthropic это output_config.format со схемой, у OpenAI — response_format с JSON-схемой. Модель физически не может отступить от структуры.

response = client.messages.create(
    model="claude-opus-4-8",
    max_tokens=512,
    messages=[{"role": "user", "content": "Иван, [email protected], заказ на 1500."}],
    output_config={
        "format": {
            "type": "json_schema",
            "schema": {
                "type": "object",
                "properties": {
                    "name": {"type": "string"},
                    "email": {"type": "string"},
                    "amount": {"type": "number"}
                },
                "required": ["name", "email", "amount"],
                "additionalProperties": False
            }
        }
    },
)

Способ 3: инструмент со схемой

Ещё один приём — определить «инструмент» с нужной схемой входа и заставить модель его «вызвать»: аргументы вызова и будут вашим структурированным объектом. Это мост к следующему уроку про tool use.

Валидация — всё равно обязательна

Даже с гарантированным форматом проверяйте ответ перед использованием: схема может не описывать все ограничения (диапазоны, бизнес-правила), а при свободном промпте парсинг тем более может упасть.

Валидация JSON по схеме полей (запускаемо)

Простой валидатор: парсим строку и проверяем наличие и типы полей — чистый Python:

import json

# Строка, которую вернула модель
model_text = '{"name": "Иван", "age": 30, "city": "Москва"}'

REQUIRED = {"name": str, "age": int, "city": str}

def validate(text, required):
    try:
        data = json.loads(text)
    except json.JSONDecodeError as e:
        return None, f"не JSON: {e}"
    for key, typ in required.items():
        if key not in data:
            return None, f"нет поля {key}"
        if not isinstance(data[key], typ):
            return None, f"поле {key} должно быть {typ.__name__}"
    return data, None

data, err = validate(model_text, REQUIRED)
if err:
    print("Ошибка валидации:", err)
else:
    print("Валидно. Имя:", data["name"], "| Возраст:", data["age"])

# Плохой случай: возраст строкой
bad, err = validate('{"name": "Иван", "age": "тридцать"}', REQUIRED)
print("Плохой ввод ->", err)

Вывод:

Валидно. Имя: Иван | Возраст: 30
Плохой ввод -> поле age должно быть int

Итог

  • Для кода нужен машиночитаемый ответ — обычно строгий JSON.
  • Просьба в промпте не гарантирует формат; output_config.format / response_format со схемой — гарантирует.
  • Валидируйте ответ всегда: формат не покрывает бизнес-ограничения.
Проверьте себя
1. Почему просьбы «верни только JSON» в промпте недостаточно?
AМодель не понимает слово JSON
BБез гарантирующего режима модель может добавить пояснение или markdown и нарушить формат, поэтому ответ всё равно валидируют
CJSON нельзя получить от LLM
DЭто всегда вызывает ошибку 400
2. Какой механизм Anthropic гарантирует валидный JSON по схеме?
Atemperature = 0
Boutput_config.format с json_schema
Cstop_sequences
Dmax_tokens
3. Нужно ли валидировать ответ, если включён гарантированный формат?
AНет, формат покрывает всё
BДа: схема не описывает бизнес-ограничения (диапазоны, правила), их проверяют в коде
CНет, валидация замедляет работу
DДа, но только для OpenAI
Поддержать проект