Кто честнее с JSON: OpenAI, Gemini и xAI прошли тесты на соблюдение схем
Разработчики Habr провели adversarial-тесты Structured Outputs у OpenAI, Gemini и xAI, чтобы проверить, как честно они соблюдают JSON Schema. Просили моделей сп

Разработчики Habr провели исследование, которое проверило, как на самом деле работают Structured Outputs у трёх ведущих LLM-провайдеров: OpenAI, Gemini и xAI. Вместо прочтения документации они использовали метод adversarial-тестирования — специально ломали схемы, чтобы посмотреть, где каждый провайдер держит строку, а где сдаётся.
Как проверяли соблюдение схем Авторы не просто просили модели вернуть валидный JSON.
Они специально конструировали подсказки, пытаясь заставить модель нарушить собственную JSON Schema. Просили положить значение неправильного типа в поле, добавить лишние ключи, использовать недопустимые enum-значения, нарушить минимальную или максимальную длину строки, выйти за пределы числового диапазона. Смотрели, где модель подчиняется strict: true, а где прорывается и выдаёт невалидный JSON. Отдельно тестировали сложные конструкции: anyOf, oneOf, allOf — комбинаторные правила, которые сложнее всего реализовать в LLM. На практике многие системы эти конструкции упрощают, игнорируют или реализуют вполсилы. Авторы проверили, как именно каждый провайдер трактует эти правила.
Что выяснилось о разных провайдерах
Результаты неожиданные: у каждого провайдера свой набор жёстких и мягких ограничений. OpenAI удерживает строгость лучше всего, особенно когда включён strict: true. Gemini допускает больше вольностей с enum и вложенными объектами. xAI показывает стабильность на средних сложностях, но имеет слепые пятна на allOf-конструкциях и условных полях. Матрица ограничений из статьи показывает: OpenAI: надёжен на примитивных типах (string, number, boolean), иногда скользит на сложных nested структурах Gemini: свободнее интерпретирует anyOf и oneOf, может добавить лишние ключи в объект, менее строг с enum-значениями * xAI: хорош на средних сложностях и базовых rules, слабее на multi-level validation и patternProperties Даже strict: true не гарантирует 100% соблюдение. Это переводит ответственность обратно на разработчика.
Практические выводы для production
Если вы строите систему, которая дёргает несколько LLM-провайдеров параллельно, эти различия критичны. Нельзя просто переключиться с OpenAI на Gemini, ожидая точно такого же форматированного ответа. JSON Schema остаётся одна и та же, а поведение модели — кардинально разное. Для production-сценариев авторы рекомендуют: всегда добавляйте валидацию ответа после модели, даже если провайдер обещает strict: true. Используйте jsonschema-библиотеку, которая перепроверит результат независимо. И добавляйте fallback-логику на случай, если формат неожиданно поехал: переспросить модель, использовать default-значение или вернуть ошибку пользователю. Один случайный enum-отступ от модели может убить весь pipeline.
Что это значит Structured Outputs — полезная фича, но не панацея.
Тестирование Habr показало, что полностью надеяться на провайдера ошибочно. Если вы критичны к формату ответа, инвестируйте в валидацию на стороне клиента.