Ошибки function calling: валидация аргументов и повторные попытки
Модель предлагает, приложение проверяет
Разделяйте повтор генерации и повтор действия
Авторская схема CALL-GATE-7
Подтверждение результата до нового вызова

$ tool --contract CALL-GATE-7
> parse: allowlisted call
> validate: arguments / rights
> execute: stable operation ID
> route: verify / reconcile / reviewFunction calling превращает предложение модели в действие приложения. Модель может выбрать подходящий инструмент, но передать неверный ID, обратиться к чужой заявке или повторить запись после тайм-аута. Промпт помогает описать интерфейс; проверка аргументов, прав, выполнения и результата остаётся за приложением.
Здесь разбираем узкую задачу function calling error handling. Форму инструмента объясняет tool schema design, форму ответа — structured outputs. Более широкий выбор решения описан на странице prompt engineering и в гайде по AI-специалисту в Армении.
Проблема и требования
Учебный сценарий: помощник вызывает createFollowUp(ticketId, assigneeId, dueAt) для заявки поддержки. Модель только предлагает аргументы. Приложение проверяет существование заявки, права пользователя, принадлежность исполнителя команде и дату. Валидный JSON ничего из этого не доказывает.
Контракт фиксирует имя и версию инструмента, типы и границы аргументов, клиента и пользователя, чтение или запись, а также подтверждение результата. Для записи заранее создают устойчивый operation ID. Правило обработки неизвестного исхода определяют до включения повторов.
Авторская архитектура CALL-GATE-7
Это проектный шаблон, а не измеренный показатель.
01 PROPOSE модель предлагает инструмент и аргументы 02 PARSE разобрать один ограниченный объект из белого списка 03 VALIDATE проверить схему, ссылки и бизнес-правила 04 AUTHORIZE проверить пользователя, клиента и право на действие 05 EXECUTE выполнить один раз с operation ID и тайм-аутом 06 RECONCILE при неизвестном исходе прочитать состояние назначения 07 ROUTE вернуть подтверждение, ограниченный повтор или review
Ключ операции и учётные данные создаёт runtime, не модель. При новом предложении права проверяют снова: прежнее разрешение не действует бессрочно. Диагностические записи ограничивают правилами хранения и приватности проекта.
Минимальный псевдокод
const call = parseOneToolCall(modelOutput, allowedTools); const args = schemas[call.name].parse(call.arguments); const actor = await loadActor(request.actorId); await authorize(actor, call.name, args.ticketId); const operationId = stableId(request.id, call.name, args); const known = await findReceipt(operationId); if (known) return known; try { const receipt = await executeOnce(call.name, args, operationId); return verifyReceipt(receipt, args); } catch (error) { if (isUnknownOutcome(error)) return reconcileOrReview(operationId); if (isTransientBeforeSend(error)) return boundedRetry(operationId); return rejectWithClass(error); }
Это псевдокод. stableId, executeOnce и reconcileOrReview должны учитывать реальные гарантии системы назначения. Нельзя строить ключ повтора из изменяемого текста модели. Если система не поддерживает идемпотентность и поиск результата, после тайм-аута записи может потребоваться ручная проверка.
Ошибки и маршруты
| Сбой | Реакция |
|---|---|
| Неизвестный инструмент или лишнее поле | Отклонить и записать версию контракта |
| Неверный тип или дата | Отклонить до вызова; допустим один ограниченный новый ответ модели |
| Корректная форма, но чужая заявка | Запретить и не раскрывать её содержимое модели |
| Лимит или недоступность до отправки | Повторить с задержкой в пределах бюджета |
| Тайм-аут после отправки, исход неизвестен | Сверить по operation ID, не повторять запись вслепую |
| Уже есть подтверждение операции | Вернуть прежний результат без новой записи |
| Повторное расхождение или нет способа сверки | Остановить и передать человеку |
Повторы должны быть частью явной машины состояний. У повторной генерации аргументов и сетевого повтора разные лимиты. Для временных ошибок используют задержку с разбросом и общий срок ожидания. Ошибку прав, плохие аргументы и постоянный отказ нельзя превращать в бесконечные повторы.
Тестирование и production-проверка
Проверьте обычную заявку, чужого клиента, удалённую заявку, неверную дату, лишнее поле, повторное предложение, сбой до отправки, тайм-аут после отправки, позднее подтверждение и конфликт состояния. Проверяйте не только ответ пользователю, но и отсутствие второй записи. Управляемый имитатор системы назначения должен воспроизводить каждый сбой; сценарий только с успешным ответом не проверит безопасность повторов.
До выпуска версионируйте схему инструмента, сопоставьте классы ошибок с маршрутами, назначьте владельца проверки прав, ограничьте время и повторы, проверьте поиск подтверждения и ручное восстановление. Раздельно наблюдайте ошибки аргументов, запреты, неизвестные исходы, сверки и подавленные дубли. Это категории диагностики, не заявленные KPI.
Для разбора существующего процесса запросите технический аудит. Более широкий контекст — автоматизация с AI.
const args = schema.parse(call.arguments);
await authorize(actor, call.name, args.ticketId);
const id = stableId(request.id, call.name, args);
return executeOnceOrReconcile(id, args);