Как тестировать ИИ-агентов, если «правильно» не детерминировано
GitHub предложил метод валидации агентов, который не требует жёстких скриптов и не верит агенту на слово. Разбираем, как работает Trust Layer и почему это важно для CI/CD.
Если ваш CI падает не из-за бага в коде, а потому что ИИ-агент выбрал другой путь к правильному результату — пора менять подход к тестированию. Классические тесты заточены под детерминированное ПО: на входе X, на выходе Y, посередине строго определённая последовательность шагов. Но агенты с функцией Computer Use работают с настоящими интерфейсами, где загрузка может длиться на полсекунды дольше, а кнопка оказаться в другом месте. GitHub недавно предложил способ отличать реальные ошибки от такого «шума» — независимый Trust Layer, который учится на примерах успешных запусков.
В этой статье разберём, почему стандартные assert-тесты и record-and-replay плохо справляются с автономными агентами, как теория графов помогает выделить обязательные этапы задачи и что из этого следует для российских команд, которые уже пробуют GitHub Copilot или собственных агентов в CI/CD.
Исследование, опубликованное 6 мая 2026 года в блоге GitHub, описывает метод валидации агентского поведения, который не требует ручного написания скриптов для каждого сценария и не верит агенту на слово. Вместо этого он строит модель «ground truth» из 2–10 успешных выполнений и проверяет новые запуски по структуре, а не по совпадению шагов.
Ключевые выводы
- ИИ-агенты с
Computer Useнедетерминированы: один и тот же задача может решаться разными путями. - GitHub предлагает Trust Layer — внешний слой валидации, который учится на успешных запусках и выделяет обязательные этапы.
- В основе — Prefix Tree Acceptor (PTA) и dominator analysis из теории компиляторов.
- В эксперименте метод показал 100% accuracy, precision, recall и F1 против 82,2%, 83,3%, 60,0% и 69,8% у самооценки агента.
- Trust Layer лучше определяет «не баг, а шум»: F1 52,2% против 0% у внутренней самопроверки агента.
Современная разработка всё чаще сталкивается с ситуацией, когда «правильно» нельзя описать одной последовательностью действий. Агент может открыть поиск в VS Code через горячую клавишу или через меню, подождать загрузки или успеть до неё, кликнуть мышью или использовать клавиатуру. Для человека результат одинаков. Для классического теста — разные выполнения, одно из которых рискует быть отмечено как регрессия.
Почему классические тесты сдаются
Привычные инструменты тестирования хороши, пока путь выполнения фиксирован. Как только поведение начинает ветвиться, они начинают ломаться не от плохой инженерии, а от неверной посылки: «правильность = точное совпадение последовательности состояний».
- Assertion-based testing требует вручную прописывать каждую проверку и не терпит допустимых альтернативных путей.
- Record-and-replay чувствителен к задержкам сети, рендерингу и незначительным изменениям интерфейса.
- Visual regression сравнивает скриншоты изолированно, не понимая контекста выполнения и семантики состояний.
- ML-оракулы — чёрный ящик: нужны тысячи примеров обучения, и невозможно объяснить, почему помечен конкретный прогон как ошибочный.
В России эта проблема особенно актуальна для команд, которые используют self-hosted runners или зеркала репозиториев. Сетевые лаги, доступ к зарубежным API и особенности локальной инфраструктуры добавляют ещё больше «шума», не связанного с качеством кода. В результате CI начинает «краснеть» по чужой вине, а разработчики привыкают игнорировать падения.
Что значит «правильно» для агента
GitHub предлагает переформулировать определение корректности: не «агент повторил записанный сценарий», а «агент достиг обязательных результатов». Это разделяет поведение на три категории.
- Обязательные состояния (essential states). Этапы, без которых успех невозможен. Например, открытие диалога поиска и появление результатов.
- Опциональные вариации (optional variations). Случайный шум: спиннер загрузки, небольшая задержка, временное уведомление.
- Сходящиеся пути (convergent paths). Разные последовательности действий, которые приводят к одному и тому же итоговому состоянию.
Ключевой инсайт: если состояние «спиннер загрузки» можно пропустить в быстром прогоне, оно не может быть обязательным. А вот состояние «диалог поиска открыт» доминирует результат: без него невозможно получить список найденного. Эта идея напрямую заимствована из теории компиляторов — dominator analysis.
Как устроен Trust Layer
Метод GitHub состоит из трёх шагов: собрать успешные выполнения, построить из них единую модель и выделить в ней обязательные состояния.
От трасс к графу
Вместо линейного скрипта каждое выполнение представляется как направленный граф. Узлы — наблюдаемые состояния: скриншоты интерфейса, снапшоты кода или структуры DOM. Рёбра — действия агента: клики, нажатия клавиш, вызовы API. Несколько успешных трасс объединяются в Prefix Tree Acceptor (PTA) — дерево, которое сохраняет общие префиксы и разветвляет пути там, где выполнения действительно расходятся.
Три уровня эквивалентности
Самая сложная часть — понять, когда два разных состояния на самом деле одно и то же. GitHub использует трёхуровневую проверку.
- Визуальные метрики. Быстрые perceptual hash и SSIM ловят почти идентичные скриншоты.
- Семантический анализ через LLM. Мультимодальная модель решает, значима ли разница: timestamp или декорация окна игнорируются, пропавшая кнопка или другое сообщение об ошибке — фиксируются.
- Консервативное слияние. Состояния объединяются только при высокой уверенности, чтобы не потерять реальное расхождение.
Доминаторы выделяют суть
После слияния к графу применяется dominator analysis. Состояние A доминирует состояние B, если любой путь от начала к B проходит через A. Те состояния, которые доминируют успешное завершение задачи, становятся обязательными. Всё остальное автоматически классифицируется как опциональный шум.
При проверке нового прогона алгоритм не ищет точное совпадение. Он проверяет, что обязательные состояния появились в правильном порядке. Если эталонная последовательность A → B → C, а агент выполнил A → X → B → Y → C, тест проходит: X и Y считаются случайными вставками. Если пропущено B или нарушен порядок — фиксируется конкретная ошибка с пояснением, какое состояние не достигнуто.
Цифры: насколько это лучше
Авторы сравнили свой метод PTA (Dominator Tree) с самооценкой агента Computer-Use Agent (CUA) на наборе тестов кастомного расширения VS Code. Разница оказалась впечатляющей.
- Accuracy: CUA — 82,2%, PTA — 100% (+17,8 п. п.).
- Precision: CUA — 83,3%, PTA — 100% (+16,7 п. п.).
- Recall: CUA — 60,0%, PTA — 100% (+40,0 п. п.).
- F1-Score: CUA — 69,8%, PTA — 100% (+30,2 п. п.).
Ещё важнее метрика «не баг, а шум» (not-a-bug). Сам агент не смог корректно классифицировать такие сценарии: F1 оказался 0%. Trust Layer на основе структурного анализа достиг F1 52,2%. Это означает, что разработчики тратят меньше времени на разбор ложных падений.
We don’t need black-box models to judge other black-box models. We need structural guarantees developers can inspect, reason about, and trust.
Как это применить в своём CI/CD
Полноценная реализация Trust Layer требует исследовательского прототипа, но идеи можно перенести и в повседневную работу команд.
- Собирайте «золотые» трассы. Сохраняйте 2–10 успешных выполнений критичного сценария, чтобы у будущих прогонов была эталонная структура.
- Отделяйте «должен быть» от «может быть». Вместо проверки каждого шага фиксируйте ключевые чекпоинты: авторизация выполнена, данные сохранены, ответ получен.
- Делайте тесты толерантными к порядку. Если несколько допустимых путей ведут к одному результату, проверяйте результат и наличие обязательных промежуточных состояний, а не точную последовательность.
- Используйте семантику, а не пиксели. Визуальные регрессии должны понимать, что изменилось, а не просто считать разницу между скриншотами.
- Не верьте агенту на слово. Внешняя валидация по состояниям среды надёжнее самооценки модели, особенно в недетерминированных задачах.
Для российских команд, работающих с ограниченным доступом к зарубежным API, важный вывод: если агент зависит от внешнего сервиса, валидация должна уметь отличать проблему сети от проблемы продукта. Иначе любой transient timeout будет превращаться в красный CI.
Часто задаваемые вопросы
Что такое Trust Layer в контексте ИИ-агентов?
Это независимый слой валидации, который проверяет, достиг ли агент обязательных состояний, не опираясь на точное повторение записанного сценария и не веря агенту на слово.
Почему обычные unit-тесты не подходят для агентов?
Unit-тесты предполагают детерминированность: на один вход — один выход и один путь. Агенты в реальных интерфейсах могут выбирать между равнозначными действиями, поэтому проверять нужно результат и ключевые этапы, а не каждый шаг.
Сколько успешных запусков нужно для построения модели?
По данным GitHub, достаточно 2–10 успешных трасс, чтобы алгоритм выделил обязательные состояния и отличил их от случайного шума.
Как доминаторы помогают в тестировании?
Dominator analysis из теории компиляторов показывает, какие состояния неизбежно встречаются на всех путях к успеху. Такие состояния становятся обязательными; всё остальное — опционально.
Какие у метода ограничения?
Он учится только на успешных примерах, зависит от мультимодальной LLM для семантической проверки и пока не отслеживает временны́е ограничения вроде «загрузка должна завершиться за 5 секунд».
Выводы
ИИ-агенты переходят из демо в production, и вместе с ними должно эволюционировать тестирование. Проверять агента жёстким скриптом — всё равно что проверять водителя по тому, всегда ли он переключает передачи одной и той же рукой. Важно не это, важно — доехал ли он до пункта назначения и не нарушил ли правил.
Подход GitHub с Trust Layer, PTA и dominator analysis даёт объяснимую и лёгкую модель корректности, которую можно встроить в CI/CD. Она не требует тысяч примеров и не превращается в чёрный ящик. А главное — снижает количество ложных падений, за которыми теряются настоящие баги.
Источник: Validating agentic behavior when “correct” isn’t deterministic — The GitHub Blog.