Содержание статьи
Представим агента, которому поручили оформить подрядчика. Он создал карточку исполнителя, подготовил договор и отправил его на подпись. Сервисы приняли запросы, ошибок в журнале нет. Но по внутреннему регламенту договор можно отправлять только после проверки статуса подрядчика. Агент этот этап пропустил, а сервер позволил продолжить работу.
Похожим условным примером технический директор Workday Гейб Монрой объясняет проблему в колонке для VentureBeat.
В такой ситуации полезно проверить, какой компонент должен был остановить отправку. Если единственный ответ — «модель должна была вспомнить инструкцию», у процесса нет надёжного контроля обязательного этапа. Это можно выяснить ещё до подключения агента: достаточно отправить тот же запрос обычным API‑клиентом.
Что скрывается за успешным ответом API
Продолжим пример с подрядчиком. Допустим, компания установила такой порядок: сначала проверка статуса исполнителя, затем согласование условий договора, после этого — отправка на подпись. Пока проверка не завершена, агент может собирать сведения и готовить черновик.
У API отправки договора могут быть вполне разумные проверки: документ существует, адрес получателя заполнен, вызывающая сторона имеет право отправлять документы. Однако они не отвечают на вопрос, прошёл ли этот конкретный подрядчик обязательную проверку.
Поэтому ответ об успешной отправке подтверждает результат операции в пределах реализованных проверок. Из него нельзя заключить, что весь регламент соблюдён.
OWASP относит пропуск обязательных этапов к ошибкам бизнес‑логики. Для таких процессов организация рекомендует хранить состояние на сервере и проверять допустимость переходов между этапами.
Для нашего примера это означает простое условие: сервис отправки должен получить подтверждение проверки подрядчика и согласования договора. Переданный агентом параметр checks_passed: true не годится в качестве доказательства. Сервису нужна запись в системе, которая отвечает за эту проверку.
Такой подход помогает и без ИИ. То же ограничение должно действовать для сотрудника, интеграционного скрипта и фонового задания. Иначе агенту достаточно воспользоваться путём, на котором проверку забыли.
Где проверять действие агента
Вызов инструмента начинается с решения модели, но исполняет его приложение. Модель возвращает название инструмента и аргументы; окружающий её код решает, выполнять ли запрос.
Именно это разделение описано в документации Open Policy Agent. Перед запуском инструмента приложение передаёт запрос механизму политик, получает решение и применяет его. Сам по себе ответ механизма политик ничего не блокирует: запрет должен исполнить вызывающий код.
На этом уровне удобно ограничить набор доступных действий. Например, агенту подготовки документов разрешить поиск подрядчиков и создание черновиков, а отправку на подпись оставить отдельному процессу. Если отправка всё же входит в его задачу, приложение должно проверить соответствующие полномочия.
Дальше вступает в работу сервис договоров. Ему нужно установить, можно ли отправить выбранный документ: завершена ли проверка исполнителя, согласованы ли условия, не отозвано ли согласование. Предварительное разрешение вызвать инструмент этих вопросов не отменяет.
Здесь полезно разделить ответственность:
Компонент
За что отвечает
Приложение агента
Проверяет доступность инструмента и допустимые параметры вызова
Механизм авторизации
Определяет полномочия вызывающей стороны для конкретного действия и объекта
Сервис договоров
Контролирует состояние договора и обязательные этапы процесса
Журнал аудита
Сохраняет основания решения и результат выполнения
Это распределение обязанностей не требует четырёх отдельных сервисов. Проверки могут находиться в одном приложении или использовать общую службу политик. Существеннее другое: нельзя оставлять альтернативный путь, через который операция выполняется без них.
Например, основной API отправки проверяет согласования, а внутренний метод массовой отправки — только роль администратора. Если агенту доступен второй метод, защита первого не решает задачу. OWASP рекомендует проверять полномочия при каждом запросе, независимо от его источника.
Идентичность инициатора тоже должна поступать из доверенного контекста аутентификации. Поле user_id, которое модель самостоятельно записала в аргументы инструмента, не подтверждает право действовать от имени этого пользователя.
Почему разрешение может устареть
Предположим, все проверки уже есть. Агент запросил разрешение на отправку договора и получил положительный ответ. Затем сотрудник отозвал согласование, а агент продолжил выполнение по ранее составленному плану.
Проверка могла быть правильной в момент запроса. Проблема возникла между проверкой и действием.
Этот класс ошибок известен как time‑of‑check to time‑of‑use, или TOCTOU. В описании CWE-367 MITRE разбирает ситуации, когда состояние ресурса меняется после проверки, но до использования. Простое сокращение промежутка между этими действиями не устраняет проблему.
Для договора можно сформулировать конкретное требование: переход к отправке допустим только для той версии документа, которая прошла согласование. Если условия изменились, прежнее разрешение больше не подходит.
Когда необходимые данные находятся в одной базе, проверку состояния и его изменение можно связать транзакцией с подходящими блокировками либо условным обновлением. При этом нужно защитить все данные, от которых зависит решение: блокировка одной строки договора не поможет, если запись о согласовании параллельно меняется независимо от неё. Конкретный механизм зависит от схемы хранения и конкурентных операций. OWASP описывает несколько вариантов защиты таких переходов.
![[Перевод] ИИ‑агенту разрешили вызывать API. Кто проверит бизнес‑правила? [Перевод] ИИ‑агенту разрешили вызывать API. Кто проверит бизнес‑правила?](/wp-content/uploads/2026/10/9f05d776f2f4a44f7bd6ff312b04af47.png)
Внешняя отправка добавляет ещё одну задачу. Транзакция в собственной базе не делает атомарным запрос к стороннему сервису. Если тот отправил договор, но ответ потерялся, повторный вызов может привести к повторной отправке.
Поэтому отдельно проектируют повторные попытки: используют поддерживаемый провайдером механизм идемпотентности, сохраняют состояние операции и выясняют результат запроса с неизвестным исходом. Повтор одной операции должен опираться на её прежний идентификатор и правила внешнего API.
Что именно должен подтверждать человек
Ручное согласование полезно, только если понятно, что согласовали. Кнопка «Разрешить агенту продолжить» оставляет слишком много неопределённости: какой документ он отправит, кому и с какими условиями?
В нашем примере сотрудник должен видеть получателя и конкретную редакцию договора. Если после подтверждения агент изменит адрес или существенные условия, системе потребуется новое согласование.
Этот принцип соответствует рекомендациям OWASP по авторизации транзакций: пользователь подтверждает значимые данные операции, а система проверяет разрешение перед исполнением и учитывает изменения этих данных.
В руководстве OWASP по безопасности ИИ‑агентов это требование уточняется применительно к инструментам. Запись о согласовании должна быть связана с исполнителем, действием, целевым объектом и параметрами. Проверять её должен компонент исполнения за пределами контекста модели.
Поэтому фраза агента «пользователь подтвердил» или самостоятельно выставленный им флаг не заменяют запись о согласовании. Такая запись должна появиться в результате предусмотренного системой действия уполномоченного человека.
Промпт при этом остаётся полезным: он объясняет агенту порядок работы и помогает избежать заведомо недопустимых запросов. Но отказ в выполнении обеспечивает код, даже если модель решила продолжить.
![[Перевод] ИИ‑агенту разрешили вызывать API. Кто проверит бизнес‑правила? [Перевод] ИИ‑агенту разрешили вызывать API. Кто проверит бизнес‑правила?](/wp-content/uploads/2026/10/01bdd6b4090cf73f4fda221816a332c1.png)
Как проверить ограничения перед запуском
Для первого испытания достаточно одного процесса с понятным результатом. В нашем случае — подготовки и отправки договора. Зафиксируйте обязательные условия, найдите все доступные способы отправки и проверьте каждый из них.
Начните с прямых вызовов API без модели. Так проще установить, действительно ли ограничение действует. Затем повторите сценарии через агента: нужно проверить и защиту сервиса, и реакцию приложения на отказ.
Сценарий
Ожидаемое поведение
Подрядчик проверен, актуальная версия договора согласована
Отправка разрешена, результат записан
Проверка подрядчика пропущена
Отправка заблокирована независимо от текста запроса агента
После согласования изменился получатель или условия
Требуется новое согласование
Инициатору отозвали право отправки
Следующий запрос отклоняется с учётом установленного механизма отзыва
Отправка запрошена через другой API
Действуют те же обязательные условия
Служба политик недоступна, действительного разрешения нет
Отправка не выполняется
Ответ внешнего сервиса потерялся
Система выясняет исход операции и не отправляет документ повторно вслепую
Для отзыва полномочий отдельно проверьте кеши и срок жизни токенов. Требование «запретить немедленно» нужно реализовать в механизме авторизации: уже выданный токен или сохранённое решение могут оставаться действительными по правилам конкретной системы.
При разборе теста понадобится больше сведений, чем название инструмента и HTTP‑код. Сохраните идентификаторы задачи, агента и инициатора, объект действия, основание разрешения или отказа, версию политики и результат исполнения. Секреты и полное содержимое документов для этого обычно не нужны. Структурированные записи о решениях и действиях рекомендует и OWASP.
Первый критерий готовности такого пилота можно сформулировать без оценки качества ответов модели: договор с незавершённой проверкой не отправляется ни через один доступный агенту маршрут. После этого имеет смысл измерять, насколько быстро агент оформляет допустимые договоры и сколько работы оставляет сотруднику.
