Материал предназначен для разработчиков и эксплуатационных команд, которые расследуют ошибки JSON в AI Agent, сбои Function Calling и потерю контекста между вызовами. Разбор построен по всей цепочке: входной контракт, генерация, ответ API, валидация, выполнение инструмента и возврат результата.
Нужно искать ошибки JSON в AI Agent не по тексту последнего исключения, а по всей цепочке: «входной контракт — генерация — ответ API — разбор и валидация — выполнение инструмента — возврат результата». Если платформа поддерживает строгий структурированный вывод, сначала включается этот режим, а затем сохраняется отдельная проверка бизнес-правил.
Эта схема подходит backend-разработчикам, которые расследуют ошибки парсинга и пропавшие поля, инженерам многошаговых Agent-систем, проверяющим состояние между вызовами, и эксплуатационным командам, которым нужны связанные логи вместо бесконечных повторных запросов.
Точка отказа в цепочке данных
Типичный сбой выглядит обманчиво. Инструмент сообщает, что получил неверный параметр, разработчик видит исключение парсера, а команда делает вывод, что модель «сломала JSON». На практике проблема могла возникнуть раньше или позже:
- платформа отклонила саму Schema, поэтому ожидаемый режим вывода не был активирован;
- модель вернула отказ или незавершённый поток, а приложение приняло текст за готовый документ;
- потоковые фрагменты были склеены с потерей символа, поля или завершающего объекта;
- валидатор использует другую версию диалекта JSON Schema;
- JSON синтаксически корректен, но путь, учётная запись, заказ или разрешение не существуют;
- адаптер истории не вернул исходный вызов инструмента вместе с его результатом.
Для расследования полезно разделять минимум шесть артефактов:
- Schema и фактические параметры запроса.
- Сырые фрагменты ответа и собранное сообщение.
- Статус завершения, причина остановки или отказа.
- Ошибка синтаксического и структурного валидатора.
- Нормализованные аргументы, переданные инструменту.
- Результат выполнения и сообщение, возвращённое в следующий шаг Agent.
Пока эти артефакты не разделены, один общий лог «JSON invalid» почти бесполезен: он не показывает, где именно нарушился контракт.
Входной контракт и ограничения Schema
Первой проверяется не модель, а входная Schema. Разные платформы поддерживают не весь стандарт JSON Schema, а определённое подмножество. Ограничения могут касаться ссылок, рекурсивных конструкций, форматов, объединений типов, дополнительных свойств и расположения обязательных полей.
Для начала создаётся минимальный контракт:
{
"$schema": "https://json-schema.org/draft/2020-12/schema",
"type": "object",
"properties": {
"path": {
"type": "string"
}
},
"required": ["path"],
"additionalProperties": false
}
Это не универсальная Schema для любой платформы, а диагностический образец. Перед использованием следует сверить поддерживаемые конструкции с официальным описанием версий спецификации JSON Schema и назначения поля $schema.
Далее выполняются такие проверки:
$schemaявно указан или платформа применяет собственный диалект;- имя корневого типа соответствует ожидаемому объекту или массиву;
- каждое обязательное свойство действительно перечислено в
required; - названия полей совпадают с теми, которые читает исполнитель;
- лишние поля разрешены или запрещены осознанно;
- ссылки разрешаются в том окружении, где выполняется запрос;
- сложные вложенные конструкции добавляются постепенно, после успешного минимального теста.
Нельзя одновременно менять промпт, Schema, модель и код адаптера. Иначе команда получит новый результат, но не узнает, какая перемена устранила проблему. Сначала фиксируется минимальная рабочая Schema, затем возвращаются ограничения по одному.
Отказ, обрыв и незавершённый ответ
Даже строгий режим не означает, что каждый ответ содержит готовый JSON. Запрос может быть отклонён политикой или параметрами, генерация может завершиться ограничением длины, поток может оборваться до закрывающей скобки, а API может вернуть ошибку вместо содержимого.
Поэтому обработчик должен выглядеть как развилка, а не как безусловная последовательность:
получить ответ API
├─ ошибка транспорта или API → записать запрос и завершить ветвь
├─ отказ → сохранить статус и причину, не запускать парсер
├─ незавершённый ответ → пометить как incomplete, не выполнять инструмент
└─ завершённый ответ → собрать содержимое и перейти к валидации
В потоковом режиме приложение не должно считать каждый полученный фрагмент самостоятельным JSON. Сначала сохраняются части в исходном порядке, затем проверяется финальное состояние ответа. Документация по состояниям отказа в потоковом ответе показывает, почему поле с текстом и состояние завершения нельзя рассматривать как одно и то же.
Практический порядок действий:
- сохранить признак завершения и причину остановки;
- отличить пустое содержимое от отказа;
- проверить, закрыты ли все потоковые структуры;
- убедиться, что серверная ошибка не была преобразована SDK в обычную строку;
- запретить запуск инструмента при любом незавершённом состоянии;
- отправлять на повтор только ошибки, которые действительно могут быть временными.
Повторный запрос не исправляет неподдерживаемую Schema, потерянный идентификатор вызова или неверное бизнес-значение. В таких случаях ретрай лишь создаёт дополнительные побочные эффекты и затрудняет расследование.
Несовпадение валидатора и диалекта
JSON может быть корректным, но проверка Schema в разработке и производстве даст разные результаты. Причина часто находится в библиотеке валидатора, её версии, выбранном диалекте или наборе включённых форматов.
В журнале рядом с каждой проверкой фиксируются:
- версия валидатора;
- активный диалект;
- идентификатор Schema или её хеш;
- режим проверки форматов;
- нормализованный текст ошибки;
- окружение, в котором выполнялась проверка.
Отдельно проверяется различие между синтаксическим разбором и валидацией. Первый отвечает на вопрос, можно ли прочитать JSON как документ. Второй проверяет типы, обязательные свойства, ограничения строк и структуру. Третий, прикладной слой проверяет уже не Schema, а смысл: существует ли ресурс и разрешено ли действие.
Если серверная платформа принимает только часть конструкции, приложение не должно молча подменять её другой. Лучше хранить совместимую версию контракта, явно маркировать её в логах и иметь тест, который прогоняет один и тот же набор примеров через серверный и локальный путь.
JSON Schema не заменяет бизнес-проверку
Корректная структура ещё не означает корректный вызов. Например, поле path может иметь тип string, но указывать на отсутствующий файл. account_id может соответствовать шаблону, но принадлежать другому проекту. Параметр amount может быть числом, однако нарушать лимит операции.
После структурной валидации добавляется прикладной слой:
- существует ли указанный объект;
- принадлежит ли он текущему пользователю или проекту;
- хватает ли разрешений на действие;
- согласованы ли поля между собой;
- находится ли значение в допустимом диапазоне;
- можно ли повторить операцию без двойного списания или иной побочной операции;
- требуется ли подтверждение перед опасным действием.
Именно здесь становится видна разница между Function Calling и фактическим выполнением функции. Вызов может быть сформирован правильно, но исполнитель обязан самостоятельно проверить доступ, состояние ресурса и последствия операции. Официальное описание Function Calling и цикла вызова инструмента полезно использовать как основу для разделения шага генерации и шага исполнения.
Structured Output помогает получить предсказуемую форму, но не проверяет наличие заказа в базе, доступность файла или право на изменение записи. В официальном руководстве по структурированному выводу также следует сверять поддерживаемые ограничения, а не переносить предположения от одной платформы к другой.
Потеря идентификатора и истории вызова
В многошаговом Agent результат инструмента связан не только с полезной нагрузкой. Важны тип сообщения, идентификатор вызова, имя инструмента и контекст, в котором этот вызов был создан. Если промежуточный сервис оставляет только текст результата, следующая модель может не понять, к какому действию относится ответ.
Проверка строится вокруг пары:
- что именно было отправлено исполнителю;
- что именно было возвращено модели после исполнения.
При сравнении учитываются:
- исходное имя инструмента;
- идентификатор вызова;
- полный набор аргументов;
- результат, ошибка или частичный результат;
- порядок сообщений;
- системный и пользовательский контекст;
- версия схемы, действовавшая во время вызова.
Нельзя унифицировать правила состояния для всех интерфейсов. Один API может требовать передачи отдельных элементов ответа, другой — полного набора сообщений, третий — специальной связи между вызовом и результатом. Для протокола инструментов следует отдельно сверяться с описанием MCP-инструментов и общей спецификацией протокола.
Проверочный список состояния
- [ ] Сохранён исходный идентификатор вызова.
- [ ] Результат связан с тем же инструментом, а не только с похожим текстом.
- [ ] История не пересобирается из сокращённого представления.
- [ ] Адаптер не удаляет пустые, но обязательные поля.
- [ ] Сообщения передаются в требуемом порядке.
- [ ] После возврата результата сохраняется нужный контекст для следующего шага.
- [ ] Ошибка инструмента не маскируется под успешный ответ.
Диагностическая матрица решения
Когда команда видит сбой, полезно выбирать действие по месту отказа, а не по удобству конкретного разработчика.
Если платформа отклоняет Schema:
- оставить минимальный контракт;
- убрать неподдерживаемые конструкции;
- проверить
$schema, обязательные поля и ссылки; - затем постепенно вернуть бизнес-ограничения.
Если ответ отклонён или оборван:
- не отправлять содержимое в парсер;
- записать статус и причину завершения;
- проверить лимит ответа и транспорт;
- повторять только после классификации ошибки.
Если JSON не проходит локальную проверку:
- сравнить диалект и версию валидатора;
- проверить, не изменил ли SDK имена или типы;
- прогнать сырой ответ без промежуточной нормализации;
- добавить контрактный тест для окружений.
Если JSON проходит проверку, но инструмент не работает:
- проверить существование ресурса;
- проверить разрешения и область действия;
- проверить отношения между полями;
- добавить безопасный режим без фактического изменения данных.
Если контекст исчез после вызова:
- сопоставить идентификаторы;
- восстановить полный цикл сообщений;
- проверить сериализацию и обрезку истории;
- не исправлять проблему увеличением числа повторов.
Такой список является решающим инструментом для дежурной команды: каждая ветвь указывает следующий проверяемый артефакт и запрещает переходить к случайным изменениям промпта.
Минимальное воспроизведение и единый журнал
Устойчивое исправление начинается с минимального воспроизведения. Из производственного запроса удаляются персональные данные, секреты, содержимое документов и идентификаторы клиентов, но сохраняется структура, достаточная для повторения сбоя.
В обезличенном наборе должны остаться:
- входные сообщения;
- версия модели и интерфейса;
- точная Schema;
- параметры генерации, влияющие на формат;
- сырые события ответа;
- статус завершения;
- ошибка парсера или валидатора;
- нормализованные аргументы;
- результат исполнения инструмента;
- идентификатор корреляции;
- версия SDK и валидатора.
Каждая запись должна позволять пройти путь от входного запроса до результата инструмента. Логи не должны содержать токены доступа, персональные данные и секреты из переменных окружения. Для разных этапов полезно использовать один корреляционный идентификатор и отдельные поля schema_version, response_state, validation_error, tool_call_id и execution_result.
После фиксации кейса создаются тесты на отдельные классы отказа:
- неподдерживаемая Schema;
- отказ модели;
- обрыв потоковой сборки;
- отсутствие обязательного поля;
- неверный тип;
- неизвестное значение;
- корректный JSON с отсутствующим ресурсом;
- потеря связи между вызовом и результатом.
Тест должен проверять не только финальное исключение, но и правильную ветвь обработки. Если отказ ошибочно попадает в парсер, тест считается проваленным даже тогда, когда приложение в итоге показывает понятное сообщение.
Частые вопросы по диагностике
AI Agent постоянно возвращает невалидный JSON
Начинать следует с проверки статуса ответа и принятия Schema, а не с изменения температуры или промпта. Если платформа отвергла контракт, генерация не могла гарантировать нужную структуру. Если ответ оборван, парсер получает неполный документ. Только после исключения этих причин проверяются потоковая сборка, валидатор и фактический текст.
В параметрах Function Calling отсутствует поле
Сравниваются три версии данных: Schema в исходной конфигурации, Schema в реальном запросе и аргументы, полученные исполнителем. Такое сравнение показывает, исчезло ли поле на стороне платформы, модели, SDK или собственного преобразователя. Отдельно проверяются required, точное имя свойства и сериализация пустых значений.
Structured Output снова завершился ошибкой
Structured Output не отменяет обработку отказа, обрыва, серверной ошибки и неподдерживаемой конструкции Schema. Кроме того, успешная структурная проверка не означает прохождение бизнес-валидации. В официальной документации Structured Output для другого API и в рекомендациях по проверке и обработке ошибок нужно сверять именно ограничения используемого интерфейса.
После результата инструмента исчезает контекст
Нужно проверить полный набор сообщений и идентификаторов, а не только строку результата. Если адаптер заменяет вызов и ответ одним текстовым блоком, связь с инструментом теряется. Историю следует сравнить до и после каждого промежуточного сервиса, включая фильтры, очереди, сериализаторы и ограничители размера контекста.
JSON корректен, но действие не выполняется
Синтаксис и JSON Schema не подтверждают существование ресурса, право доступа и допустимость операции. Инструменту нужны отдельные проверки авторизации, состояния объекта, связей между полями и идемпотентности. Поэтому успешный разбор должен переводить запрос не сразу в выполнение, а в контролируемый прикладной шлюз.
Порядок исправления в рабочей среде
При производственном инциденте сначала фиксируется исходный запрос и корреляционный идентификатор, затем замораживается текущая Schema и версия исполнителя. После этого команда классифицирует сбой: контракт, состояние ответа, разбор, бизнес-проверка или возврат истории.
Следующий порядок снижает риск побочных изменений:
- Отделить транспортную ошибку от содержимого ответа.
- Проверить отказ и состояние завершения.
- Повторно отправить минимальную Schema без лишних ограничений.
- Сравнить серверный и локальный валидатор.
- Проверить аргументы непосредственно перед инструментом.
- Проверить ресурс и разрешения без выполнения опасного действия.
- Восстановить идентификаторы и порядок сообщений.
- Добавить тест, который воспроизводит конкретную причину.
- Только после этого рассматривать ограниченный повтор запроса.
- Выпустить исправление с наблюдаемыми логами по каждому этапу.
Команде следует также зафиксировать, какие изменения требуют повторной проверки: обновление SDK, смена модели, изменение диалекта Schema, переход между потоковым и обычным ответом, а также изменение формата сообщений инструментов.
Для изолированного воспроизведения удобно отделять рабочую систему от среды, где можно менять версии SDK, валидатора и системные зависимости. Если текущая команда использует общий рабочий компьютер, это создаёт расхождения окружения, усложняет параллельные проверки, оставляет локальные секреты рядом с тестовыми данными и не всегда позволяет воспроизвести macOS-специфичный сценарий. В таких случаях панель управления удалённой средой помогает организовать отдельный тестовый контур, а раздел помощи по эксплуатации стоит использовать для уточнения процедур доступа и настройки.
Для долгого стабильного тяжёлого прогона собственная машина может быть рациональнее аренды, особенно когда требуются постоянные фоновые процессы, локальные физические интерфейсы или предсказуемый доступ без ограничений. Но для временной проверки, сравнительного теста и изоляции инцидента общий рабочий компьютер обычно проигрывает: зависимости смешиваются, окружение трудно зафиксировать, а повторяемость падает. В такой ситуации аренда Mac у nuvcloud позволяет получить отдельную среду для воспроизведения без покупки дополнительного устройства; условия и доступные варианты следует проверить на странице тарифов nuvcloud.
Проверьте AI Agent в стабильной среде macOS
Арендуйте удалённый Mac в nuvcloud для воспроизводимого тестирования генерации JSON и Function Calling.
Изолируйте выполнение инструментов и наблюдайте за каждым этапом обмена данными через удалённый доступ.