В спецификации JSON Schema Draft 2020-12 отдельно описаны правила самого языка схем, но это не означает, что каждый модельный API принимает весь стандарт целиком в официальном описании Draft 2020-12. Поэтому совместимость моделей с JSON Schema следует принимать не по факту успешного первого запроса, а по зафиксированному набору конструкций, преобразователю и одинаковым тестовым примерам. Бизнес-уровень можно сделать общим, исходный файл — нет: для OpenAI, Gemini и Claude потребуются проверяемые варианты схем.
План действий на эту неделю: сначала закрепить каноническую схему и её версию, затем составить матрицу поддерживаемых ключевых слов по документации трёх API, после этого прогнать положительные и отрицательные примеры через отдельные адаптеры. Если хотя бы один адаптер молча удаляет ограничение, влияющее на смысл операции, выпуск следует заблокировать.
Кому нужен такой регламент
Этот материал предназначен платформенным инженерам, которые поддерживают слой адаптации между несколькими модельными API и должны заранее определить границу преобразования схемы.
Тестировщикам он помогает сравнивать ответы на одной входной выборке, а авторам Schema — не перегружать общий контракт глубокой вложенностью и расширениями конкретного поставщика.
Сначала фиксируется граница общего бизнес-контракта
JSON Schema — это язык описания структуры и правил проверки данных, а не единый профиль для всех генеративных интерфейсов. Официальная спецификация содержит больше возможностей, чем конкретный режим структурированного ответа или вызова инструмента может принять. Обзор редакций и назначения спецификаций опубликован на официальной странице JSON Schema.
Для платформенной команды каноническая схема должна отвечать на вопрос: какие ограничения действительно являются частью бизнес-контракта? В базовое ядро обычно попадают:
- объектные и примитивные типы;
- обязательные поля через
required; - перечисления через
enum, если набор значений действительно закрыт; - массивы с явно заданным типом элементов;
- понятные ограничения строк, чисел и количества элементов;
- запрет неизвестных свойств, если расширение объекта недопустимо;
- ссылки на переиспользуемые определения только там, где их можно одинаково развернуть и проверить.
Каждый элемент должен иметь назначение. Например, additionalProperties: false полезен для команды, которая хочет остановить опечатку в имени поля, но может быть ошибкой для события с версионируемыми расширениями. enum хорошо защищает конечный набор состояний, однако создаёт миграционную нагрузку, если бизнес регулярно добавляет новые значения. Глубокая вложенность усложняет преобразование, диагностику и чтение отказов, поэтому её следует оставлять только при наличии реальной иерархии данных.
Нужно также отдельно записать версию диалекта, идентификатор схемы и политику совместимости. Ссылка на Draft 2020-12 подтверждает намерение автора, но не заставляет провайдера поддерживать все конструкции этого диалекта. В отчёте должны храниться:
- имя канонической схемы;
- её неизменяемая версия;
- версия интерфейса каждого API;
- дата проверки;
- перечень разрешённых и запрещённых конструкций;
- ожидаемое поведение при отказе.
Так появляется проверяемая JSON Schema совместимость, а не устное обещание «формат общий».
Затем сравнивается реальная поддержка трёх интерфейсов
На уровне поставщика нужно проверять не название функции, а конкретный способ передачи схемы. OpenAI описывает Structured Outputs и ограничения строгого режима в официальном руководстве OpenAI Structured Outputs. Gemini публикует собственный перечень возможностей Structured Output в документации Gemini API. Эти документы следует читать как независимые контракты, а не складывать в один предполагаемый стандарт.
Для OpenAI Structured Outputs адаптер должен отдельно проверять, какие поля обязательны в строгом режиме, как передаётся объект схемы и какие ограничения накладываются на дополнительные свойства. Если исходный контракт допускает необязательное поле, а целевой режим ожидает обязательные ключи, адаптеру нужна явная политика: использовать значение null, разделить варианты схемы или изменить бизнес-обработчик. Простое удаление поля required меняет контракт и не считается безопасной совместимостью.
Для Gemini Structured Output нужно сохранить отдельную проверку формата запроса и заявленного подмножества. Даже если конструкция синтаксически выглядит допустимой в JSON Schema, это не доказывает, что конкретный метод генерации, тип MIME и параметр схемы обработают её одинаково. Сверка должна проводиться с официальным описанием метода генерации Gemini, а не с примером из другого интерфейса.
Claude Structured Outputs в рассматриваемой архитектуре нельзя автоматически приравнивать к режиму строгого ответа OpenAI. Claude часто используется через описание входной схемы инструмента; правила для input_schema, вызова инструмента и последующей проверки нужно сопоставлять с официальным обзором использования инструментов Claude. Если исполнитель получает структурированные аргументы, это всё равно не делает операцию безопасной и не гарантирует истинность значений.
Адаптеры должны выдавать не только преобразованный JSON, но и журнал изменений:
- какое ключевое слово было сохранено;
- какое заменено эквивалентным правилом;
- какое вынесено в постпроверку;
- какое запрещено для данного интерфейса;
- почему изменение не меняет или, наоборот, меняет бизнес-смысл.
Если преобразователь незаметно убрал ограничение диапазона, закрытый enum или обязательную связь между полями, результат нельзя считать совместимым. В таком случае корректные варианты — остановить сборку, использовать поставщикоспецифичную схему или разделить рабочий процесс.
После адаптера вводится единый набор тестов
Один успешный пример проверяет только счастливый путь. Тестовая команда должна подготовить коллекцию, в которой каждая запись содержит вход, ожидаемую структурную реакцию и ожидаемое бизнес-решение. Минимальный набор включает:
- нормальный объект со всеми обязательными полями;
- объект без каждого обязательного поля по отдельности;
- неправильный тип в строковом, числовом и логическом поле;
- неизвестное свойство;
- пустой и предельно длинный массив;
- глубокую вложенность;
- неизвестное значение перечисления;
- конфликтующие или взаимозависимые поля;
- повторную отправку одного и того же запроса.
Последний пример особенно важен для инструментов: схема может принять ключ идемпотентности как строку, но только исполнитель способен проверить, не была ли операция уже выполнена. Для каждого прогона сохраняются исходная схема, версия адаптера, название модели, версия интерфейса, параметры запроса, статус ответа, полученный JSON и результаты последующих валидаторов. В описании работы валидатора JSON Schema показано, что структурная проверка сопоставляет данные с правилами схемы; это не равно проверке фактов и прав доступа.
Проверка должна идти несколькими независимыми слоями:
- синтаксический: ответ действительно разбирается как JSON;
- структурный: типы, обязательность, перечисления и свойства соответствуют целевой схеме;
- контрактный: преобразователь не потерял значимое ограничение;
- бизнесовый: поля согласуются между собой и с данными системы;
- операционный: действие разрешено для конкретного субъекта и ресурса.
Так тестовая команда сравнивает не красоту ответа и не текстовое сходство, а последствия его использования.
Безопасность отделяется от формальной валидности
Даже полностью валидный объект не должен напрямую запускать опасный инструмент. Перед исполнением проверяются как минимум субъект и его права, идентификатор ресурса, допустимый бизнес-контур, срок действия запроса, идемпотентный ключ и наличие актуального состояния в базе данных.
Например, поле resource_id может быть строкой нужного формата, но это не доказывает, что ресурс принадлежит текущему пользователю. Поле action может пройти enum, однако право на это действие могло быть отозвано между генерацией и исполнением. Число может удовлетворять типу и диапазону, но нарушать лимит конкретного договора.
Для опасных инструментов нужен режим, в котором модель только предлагает аргументы, а отдельный исполнитель:
- повторно валидирует JSON;
- проверяет авторизацию;
- загружает ресурс из доверенного источника;
- применяет серверные ограничения;
- требует подтверждение для необратимого действия;
- записывает решение и причину отказа.
Это особенно важно при переносе между OpenAI Structured Outputs, Gemini Structured Output и Claude Structured Outputs: различия в форме ответа не должны становиться различиями в уровне защиты.
FAQ: вопросы, которые следует закрыть до выпуска
Можно ли использовать одну JSON Schema сразу с OpenAI, Gemini и Claude?
Общий бизнес-контракт использовать можно, но исходный файл не следует без проверки передавать во все интерфейсы. У каждого провайдера собственный заявленный набор поддерживаемых конструкций, режим строгости и способ упаковки схемы. Надёжная архитектура хранит каноническое ядро, создаёт отдельные версии для провайдеров и сравнивает их на одном наборе входных примеров.
Поддерживают ли модели полный стандарт JSON Schema 2020-12?
Нельзя считать, что OpenAI, Gemini и Claude реализуют полный Draft 2020-12. Спецификация описывает общий язык валидации, а документация каждого API определяет собственный поднабор или формат применения. Поэтому идентификатор версии в исходном документе не является доказательством совместимости: поддерживаемые ключевые слова нужно проверять по документации и фактическими запросами.
Какие конструкции обычно приходится убирать из Structured Outputs?
Проблемными становятся не только редкие ключевые слова, но и сочетания ссылок, условных ограничений, свободных дополнительных свойств и глубокой вложенности. OpenAI отдельно описывает ограничения строгого режима, Gemini — поддерживаемый поднабор, а Claude применяет схему в контексте инструментов. Удалять ограничение молча нельзя: сначала фиксируется его бизнес-смысл и правило замены.
Как автоматизировать проверку JSON Schema между разными моделями?
Нужен единый набор положительных и отрицательных примеров, а не один успешный вызов. Для каждого API сохраняются версия модели, версия интерфейса, сериализованная схема, параметры запроса, статус ответа, результат синтаксической валидации и бизнес-проверки. В конвейере сравниваются не только тексты JSON, но и обязательные поля, типы, неизвестные свойства и итоговое решение исполнителя.
Почему правильная по схеме модель всё равно возвращает ошибочные данные?
JSON Schema проверяет форму, типы и часть ограничений, но не подтверждает истинность факта и не понимает весь контекст операции. Значение может соответствовать строковому формату, однако указывать не на тот ресурс; сумма может быть числом, но не проходить бухгалтерское правило. Поэтому после структурной проверки нужны авторизация, проверка базы данных, диапазонов, связей и идемпотентности.
Затем фиксируется решение о выпуске
Перед итоговым решением полезно применять условный список, где каждый пункт ведёт к конкретному действию:
- Если все конструкции канонического ядра подтверждены документацией и тестами каждого интерфейса, то разрешается общий бизнес-контракт с отдельными сериализаторами.
- Если структура одинакова, но один поставщик требует другой упаковки или обязательности полей, то выбирается поставщикоспецифичная схема, связанная с канонической версией.
- Если ограничение можно перенести в независимую серверную проверку без потери безопасности, то оно исключается из модельной схемы только с записью такого решения и тестом поствалидации.
- Если преобразование удаляет смысловое правило, меняет допустимые значения или нарушает безопасность, то выпуск блокируется до исправления адаптера.
- Если модели по-разному интерпретируют взаимосвязанные поля, то рабочий процесс разделяется на этапы: извлечение данных, проверка, подтверждение и исполнение.
- Если ответ структурно валиден, но не проходит проверку фактов, прав или базы данных, то результат отклоняется, даже при успешной синтаксической валидации.
Итоговый отчёт должен ссылаться на фиксированные версии схемы, адаптера, интерфейса и тестового набора. Для каждого отказа указываются воспроизводимый запрос, ответ, слой проверки и правило блокировки. Если документация одного из API обновляет заявленный поднабор, весь набор примеров запускается повторно, а не только изменившийся тест.
Чек-лист ответственности команды
Автор схемы
- [ ] Зафиксирован диалект и версия канонической схемы.
- [ ] Каждое обязательное поле связано с бизнес-требованием.
- [ ]
enumиспользуется только для действительно закрытого набора. - [ ] Политика
additionalPropertiesобъяснена, а не добавлена автоматически. - [ ] Глубокая вложенность и ссылки имеют измеримую пользу.
- [ ] Условия, которые модель не обязана проверять, вынесены в бизнесовый слой.
Разработчик адаптера
- [ ] Для каждого API есть отдельное преобразование упаковки и режима строгости.
- [ ] Все неподдерживаемые конструкции выявляются до отправки запроса.
- [ ] Потеря ограничения превращается в ошибку или явно записывается как постпроверка.
- [ ] Изменения схемы можно сопоставить с версией канонического контракта.
- [ ] Преобразователь не подменяет отказ молчаливым удалением ключевого правила.
Тестировщик
- [ ] Используются нормальные и отрицательные примеры.
- [ ] Проверяются отсутствие полей, неправильные типы, неизвестные свойства и вложенность.
- [ ] В журнал попадают версия API, версия схемы и параметры запроса.
- [ ] Сравниваются структурный результат и бизнесовое решение.
- [ ] Повторные вызовы и идемпотентность проверяются отдельно.
Владелец исполнителя и потребитель данных
- [ ] Проверяются полномочия и принадлежность ресурса.
- [ ] Значения сверяются с базой данных и бизнес-ограничениями.
- [ ] Опасные действия не запускаются только на основании ответа модели.
- [ ] Факты, суммы, статусы и связи проходят независимую проверку.
- [ ] Для отказа определены повтор, ручное подтверждение или остановка процесса.
Для команд, которым приходится выполнять такие прогоны в нескольких средах, удалённый Mac может быть удобен как воспроизводимый узел для API-тестов, браузерной автоматизации и проверки клиентских интеграций. Однако он не заменяет серверный валидатор: Mac запускает сценарии, а контроль схемы, прав и бизнес-правил должен оставаться в CI и на стороне сервиса. Перед выбором площадки стоит проверить варианты аренды Mac mini, а сведения о самой инфраструктуре — сверить с разделом о Vuncloud и доступных средах.
Если текущая схема проверяется вручную на одной рабочей станции, команда сталкивается с неповторяемым окружением, разными версиями инструментов и невозможностью параллельно прогонять несколько адаптеров. Если тесты выполняются только в облачном Linux-окружении, могут отсутствовать нужные macOS-клиенты, Xcode-зависимости или реальные сценарии интеграции. Для пакетной проверки кросс-модельных контрактов разумнее отделить каноническую схему и CI от временного Mac-узла: аренда Mac у Vuncloud даёт более управляемый способ получить тестовую среду без покупки отдельного оборудования, когда требуется именно временная проверка, а не постоянная тяжёлая нагрузка или физический доступ к периферии.
Проверьте совместимость API в рабочем окружении Vuncloud
Арендуйте Mac в Vuncloud для воспроизводимого тестирования JSON Schema и модельных API.
Используйте удалённый Mac как единое окружение для проверок, интеграционных тестов и приёмки релизов.