
Почему нормальный ответ не доказывает надёжность
Агент может безошибочно пройти демонстрационный сценарий и всё же испортить данные при первом сетевом сбое. Например, он отправил запрос на создание задачи, не получил ответ из-за тайм-аута и решил повторить вызов. Если первый запрос успел выполниться, повтор создаст дубликат.
Поэтому тестирование отказоустойчивости AI-агента должно проверять не только итоговый текст, но и состояние внешних систем: сколько записей создано, какие изменения сохранились и что агент сообщил пользователю. Это особенно важно для инструментов с побочными эффектами — отправки писем, выставления счетов, редактирования файлов и управления доступом.
В документации OpenAI инструменты описываются как функции, которые модель может вызвать в ходе работы. Но корректная передача аргументов сама по себе не гарантирует, что операция безопасно переживёт тайм-аут или повтор. Политики повторов, дедлайны и идемпотентность должны быть проверены отдельно.
Сначала зафиксируйте контракт действия
Выберите одну операцию и опишите её контракт до запуска тестов:
- входные данные и допустимые значения;
- ожидаемое изменение состояния;
- возможные ошибки и их смысл;
- можно ли безопасно повторить операцию;
- что агент обязан сообщить, если результат неизвестен.
Пример: инструмент `create_ticket` принимает заголовок и описание, создаёт ровно одну задачу и возвращает её идентификатор. Если соединение оборвалось после отправки запроса, результат может быть неопределённым: задача уже создана, но агент не получил подтверждение. Это не то же самое, что отказ до выполнения.
Разделите ошибки по моменту возникновения. Ошибка валидации обычно означает, что действие не произошло. Тайм-аут же часто не позволяет понять, произошло ли оно. Если свести оба случая к сообщению «инструмент недоступен», агент может принять опасное решение и повторить операцию.
Для каждого теста запишите критерии приёмки. Например: «после одного пользовательского запроса в тестовой базе не больше одной задачи; при неопределённом результате агент проверяет статус по ключу запроса или просит человека подтвердить действие».
Изолируйте агента от реальных побочных эффектов
Используйте тестовый проект, локальный сервер или подменный инструмент, а не рабочую почту и базу. У тестовой среды должны быть отдельные учётные данные и данные, которые можно удалить после проверки.
Для воспроизводимого сценария достаточно небольшого стенда:
Агент получает задачу создать запись.
Обёртка инструмента принимает вызов и фиксирует его аргументы.
3. Тестовый сервер управляемо задерживает ответ, возвращает ошибку или обрывает соединение.
4. После работы агента проверяется состояние хранилища и журнал вызовов.
Не подменяйте весь инструмент ответом «ошибка» на уровне модели: так легко пропустить важный случай, когда сервер выполнил действие, но ответ потерялся. Лучше отдельно смоделировать отказ до изменения состояния и отказ после него.
Храните для каждого прогона идентификатор сценария, входные данные, последовательность вызовов и итоговое состояние. Не сохраняйте секреты и лишние персональные данные. Такой журнал помогает сравнить поведение после смены модели, системных инструкций или кода инструмента.
Проверьте пять сценариев отказа
Инструмент сразу возвращает ошибку
Смоделируйте, например, ошибку авторизации или неверный аргумент. Проверьте, что агент не объявляет задачу выполненной, не выдумывает результат и не продолжает цепочку действий на основании отсутствующих данных.
Если ошибка исправима — скажем, аргумент не прошёл проверку схемы, — агент может запросить уточнение или скорректировать вызов. Если причина требует доступа администратора, он должен остановиться, а не перебирать произвольные параметры.
Инструмент отвечает медленнее дедлайна
Задайте задержку чуть ниже и чуть выше установленного тайм-аута. Проверяйте не только то, что запрос завершился, но и количество запущенных операций. Несогласованные тайм-ауты на уровнях клиента, шлюза и сервера могут приводить к тому, что внешний вызов уже выполняется, когда клиент начинает повтор.
Рекомендации AWS Builders’ Library подчёркивают, что тайм-ауты и повторы нельзя настраивать изолированно: повтор увеличивает нагрузку на зависимый сервис. Для агента это означает, что «попробуй ещё раз» не должно быть бесконечным или безусловным.
Ответ потерян после успешного действия
Это ключевой сценарий для операций записи. Пусть сервер создаст запись, но тестовый прокси отбросит ответ. Затем наблюдайте, что сделает агент: повторит вызов, проверит наличие результата или остановится с неопределённым статусом.
Безопасный повтор требует механизма идемпотентности или проверки состояния. Один вариант — передавать стабильный ключ операции, чтобы повтор с тем же ключом не создавал новую запись. Другой — сначала искать результат по уникальному идентификатору запроса. Если ни один механизм недоступен, повторять действие автоматически рискованно.
Повторная попытка снова завершается ошибкой
Проверьте ограничение количества повторов и паузы между ними. Политики Temporal, например, предусматривают параметры вроде интервала ожидания и максимального числа попыток; конкретную политику для своего инструмента нужно выбирать по его последствиям, а не копировать вслепую.
Для внешнего API важно учитывать его лимиты и рекомендации по повтору. Ошибки вроде ограничения частоты запросов и временной недоступности могут требовать разного поведения. Случайная небольшая задержка между повторами помогает не создавать синхронные всплески нагрузки, но не делает операцию безопасной сама по себе.
Одна часть составной задачи выполнена, другая — нет
Попросите агента выполнить два действия подряд, например создать запись и отправить уведомление. Смоделируйте сбой второго инструмента. Проверьте, сообщает ли агент о частичном успехе и не пытается ли отменить первое действие без соответствующего безопасного механизма.
Не всякое выполнение можно откатить. В тесте важно отличать компенсацию, которая действительно возвращает систему в согласованное состояние, от формального «undo», который оставляет побочные эффекты.
Как обнаружить опасный повтор
Сравнивайте три вещи: число вызовов инструмента, число фактически созданных объектов и итоговый ответ агентa. Число вызовов может быть больше одного по допустимой причине — например, агент сначала проверил статус. А вот два созданных объекта после одной команды пользователя — явный дефект.
Пример минимальной проверки:
python
result = run_agent(
«Создай задачу: проверить резервную копию»,
fault=»drop_response_after_commit»,
)
assert test_store.count_by_request_id(result.request_id) == 1
assert result.status in {«completed», «needs_confirmation»}
Это лишь схема: реальный код зависит от интерфейса агента и хранилища. Критически важно, чтобы проверка обращалась к фактическому состоянию тестовой системы, а не доверяла тексту ответа модели.
Добавьте отдельную проверку для повторного запуска того же сценария. Если система использует ключ идемпотентности, повтор с тем же ключом не должен создать вторую запись. Если ключ генерируется заново на каждом запуске, этот тест не проверит защиту от повторной доставки.
Разделите проверки модели и инфраструктуры
Нестабильность агента может возникнуть в разных слоях:
- Модель: неправильно интерпретирует ошибку или выбирает неподходящий инструмент.
- Оркестратор: повторяет вызов сверх лимита или теряет контекст результата.
- Инструмент: меняет состояние, но не возвращает надёжное подтверждение.
- Сеть: задерживает или теряет запрос либо ответ.
Чтобы не смешивать причины, сначала тестируйте инструмент отдельно с фиксированными входами и отказами. Затем проверяйте оркестратор на заранее заданных ответах инструментов. После этого запускайте полный сценарий с моделью и оценивайте, как она реагирует на те же сбои.
Такой порядок не заменяет сквозных тестов: он помогает найти слой, где возникает дефект. Для модели используйте несколько повторов одинакового сценария и сохраняйте версии модели, инструкций и инструментов. Результат одного удачного прогона — слабое свидетельство, особенно если выбор действия вероятностный.
Что считать достаточным результатом
Перед использованием агента с реальными данными проверьте как минимум:
- повтор после неопределённого результата не создаёт дубликат;
- ошибки и тайм-ауты не маскируются сообщением об успехе;
- число повторов ограничено, а задержки не создают лавину запросов;
- частичное выполнение явно отражено в ответе;
- опасная операция требует подтверждения, если её нельзя безопасно повторить или проверить;
- журнал позволяет восстановить последовательность событий без раскрытия секретов.
Тестируйте те же сценарии после изменений в модели, схеме инструмента, обработке ошибок или настройках повторов. Если агент не умеет определить, выполнилась ли операция до потери ответа, безопаснее показать статус «результат не подтверждён» и дать оператору проверить систему, чем автоматически повторять действие.










