Чем больше задач отдаём AI-агентам, тем чаще сталкиваемся с одной проблемой: агент уверенно рапортует об успехе, а мы не всегда понимаем, что он действительно проверил. Давайте оденем шапочку детектива и внедрим подход к разработке, чтобы минимальными усилиями прогонять все под лупой. Суть подхода Evidence-Driven Development - принимать работу агента не по его отчёту, а по проверяемым доказательствам.
Хороший пример из Swift Concurrency.
Есть
@MainActor ViewModel, которая загружает данные при обновлении экрана.Пользователь дважды запускает обновление:
Запрос A стартует первым.
Запрос B стартует позже, но завершается раньше.
Запрос A возвращается последним и перезаписывает свежие данные.
Никакого нарушения actor isolation. Strict Concurrency Checking доволен, Thread Sanitizer тоже может ничего не найти. Но поведение неправильное.
Агент добавил проверку идентификатора запроса и сообщил: "Исправлено"
Как понять, что действительно исправлено?
🟢1. Сначала формулируем ожидаемое поведение. Не просто исправь race condition, а если A завершился после B, результат A не должен заменить данные B
🟢2. Требуем тест, воспроизводящий проблему. В XCTest можно использовать
withCheckedThrowingContinuation, чтобы вручную управлять порядком завершения запросов. Это гораздо надёжнее, чем пытаться поймать баг через Task.sleep🟢3. Проверяем, что тест действительно ловит баг. На старой реализации тест должен падать, на исправленной — проходить. Иначе непонятно, что именно он проверяет
🟢4. Просим доказательства запуска. Не «All tests passed», а конкретный
xcodebuild test, выбранные scheme, simulator, количество выполненных тестов, exit code и .xcresult🟢5. Убеждаемся, что проверяли финальный код. Если после успешного теста агент ещё что-то поправил, старый результат уже не обязательно относится к текущей реализации
🟢6. Фиксируем, что осталось непроверенным. Например, отмена запросов, ошибки сети или ситуация с тремя одновременными обновлениями
А ещё я бы добавил это в инструкции для агентов:
После завершения задачи предоставь список изменений, результаты проверок с командами и артефактами, сценарии, которые остались непроверенными, и риски. Не называй проверку успешной, если она не запускалась или завершилась ошибкой.
И тут важно не уйти в другую крайность. Гонять весь набор тестов после изменения текста на кнопке — сомнительная идея. Проверки должны соответствовать риску: для UI это может быть скриншот и проверка локализации, для авторизации — уже полноценные тесты состояний и интеграций
Мне нравится сама идея сменить критерий готовности задачи на агент доказал, что работает. Похожую идею я уже пилотирую на исправлении багов:
🟢1. Первый агент уходит писать тест, воспроизводящий баг
🟢2. Второй агент, не зная о существовании теста пытается поправить
🟢3. После репортинга успеха, первый агент прогоняет тест и верифицирует изменение второго
Теперь я знаю что у этого подхода есть название. А вы уже заставляете своих агентов самостоятельно доказывать корректность изменений или пока ограничиваетесь ревью diff?