ГлавнаяБлогКак AI-агенты находят и исправляют баги в реальном приложении
Python

Как AI-агенты находят и исправляют баги в реальном приложении

Узнайте, как два AI-агента автоматически находят и исправляют баги в реальном приложении. Практический опыт с кодом на Python и Playwright.

Al
Редакция Algolitalgolit.ru
10 мин чтения11 июля 2026 г.

Зачем это читать

Представьте: у вас есть коллега, который никогда не спит, не скучает и каждый час пытается сломать ваше приложение. Это агент. Он открывает настоящее приложение, кликает как тестировщик и отправляет отчёт о любой странности. Второй агент подхватывает отчёт и исправляет проблему. В этой статье я расскажу, как это работает, какие баги были найдены и что пошло не так.

Как устроены агенты для поиска багов

Приложение под тестом — AI Platform от Zephyr Cloud, десктопное приложение, где команды работают с AI-специалистами в каналах. Агент управляет реальным, авторизованным десктопным приложением через Playwright по протоколу CDP (Chrome DevTools Protocol). Это не урезанная тестовая сборка, а то же самое приложение, которое используют люди.

Это важно: агент не кликает по мокапу и не дёргает API. Он смотрит на реальный продукт глазами нового пользователя и замечает, когда что-то не так.

Два агента: охотник и исправитель

Первый агент — охотник. Он исследует маршруты, открывает диалоги, заполняет формы и следит за реакцией приложения. Когда находит проблему, пишет полноценный баг-репорт с шагами воспроизведения и скриншотом, и создаёт issue на GitHub.

Второй агент — исправитель. Он берёт issue, сначала воспроизводит баг, затем исправляет его, делает скриншоты «до» и «после» и открывает pull request. Человек всё ещё проверяет и мёрджит. Агенты делают только нудную中间 часть.

# Пример: охотник с Playwright
from playwright.sync_api import sync_playwright

def hunt_for_bugs():
    with sync_playwright() as p:
        browser = p.chromium.connect_over_cdp('http://localhost:9222')
        page = browser.contexts[0].pages[0]
        # Исследуем страницу настроек
        page.goto('https://app.example.com/settings')
        # Заполняем форму токена GitHub
        page.fill('#token-input', 'ghp_test_token')
        page.click('#save')
        # Проверяем, сохранилось ли
        saved = page.text_content('#status')
        if 'Saved' not in saved:
            report_bug('Токен не сохранился', page.screenshot())

Честность агента — главная проблема

Неожиданный вывод: заставить агента находить баги легко. Трудно заставить его быть честным. Усердный агент сообщит обо всём как о баге, включая ожидаемое поведение, проблемы тестовых данных и то, в чём он не уверен. Такой шум хуже тишины — вы перестаёте доверять.

Поэтому охотник классифицирует каждую находку:

  • Баг: реальная поломка
  • Ожидаемо, но плохой UX: работает, но не должно
  • Проблема окружения или данных: не продукт
  • Пропуск в тестах: не хватает покрытия
  • Неопределённо: не удалось подтвердить

И прикрепляет уровень уверенности: высокий (воспроизведено с чёткими шагами), средний (вероятно, но есть сомнения), низкий (подозрительно, но недостаточно для issue). Правило: issue создаётся только для бага с высокой уверенностью и воспроизводимостью. Всё остальное задерживается.

Реальные баги, которые нашёл агент

Охотник нашёл настоящие проблемы — тихие, незаметные баги, которые легко пропустить в гонке за новыми фичами. Вот несколько:

  • Чат-канал зависает на «Загрузка истории сообщений» навсегда. Ни ошибки, ни таймаута — просто стоп.
  • Поле токена GitHub выглядит сохранённым, но молча не сохраняется из-за неправильного формата. Приложение не сообщает об этом.
  • Страница настроек загружает домашний экран, оставляя кнопки домашней страницы залипшими и некликабельными.
  • Панель чата сжимается до пиксельной полоски при открытии всех боковых панелей.

Ни один из них не вызывает ошибку. Ни один не провалил бы обычный тест. Они просто неправильны тихо и незаметно. Агент, терпеливо проверяющий каждый час, ловит их на ранней стадии.

Любимый момент: агент исправил баг, который сам вызвал

Вначале охотник обнаружил, что в редакторе воркфлоу нет защиты от несохранённых изменений. Вы редактируете воркфлоу, уходите — и изменения исчезают без предупреждения. Он создал issue. Мы добавили защиту.

Недели спустя тот же охотник вернулся и нашёл новую проблему: защита теперь показывала ложный диалог «Несохранённые изменения» после каждого успешного сохранения, даже когда нечего сохранять. Он снова создал issue.

Затем исправитель подхватил его, воспроизвёл, выяснил, что сохранение вызывало навигацию до того, как React перерендерился, исправил и открыл pull request, который закрыл issue. Агент заметил отсутствие фичи, мы её добавили, тот же агент поймал баг в этой фиче, а другой агент его исправил. Полный цикл, и я почти не участвовал.

Главное правило: воспроизведи перед исправлением

Исправителю запрещено трогать код, пока он не воспроизвёл баг сам. Нет воспроизведения — нет pull request. Это очевидно, но это разница между исправлением и догадкой. Часто честный ответ — «я не смог воспроизвести» или «нужен человек». В таких случаях он намеренно не открывает PR. Уверенный патч для бага, который вы никогда не видели — не исправление, а риск.

Когда он открывает PR, он включает скриншот «до» (реальное сломанное состояние) и «после» (исправленное). И скриншот «до» должен быть подлинным. Агент с радостью сделает убедительное «до» из уже исправленной ветки, если позволить — это мы жёстко блокируем.

# Пример: исправитель воспроизводит баг
def reproduce_bug(issue_url):
    # Открываем issue и читаем шаги
    steps = get_steps_from_issue(issue_url)
    with sync_playwright() as p:
        browser = p.chromium.connect_over_cdp('http://localhost:9222')
        page = browser.contexts[0].pages[0]
        try:
            for step in steps:
                page.goto(step['url'])
                if step['action'] == 'click':
                    page.click(step['selector'])
                # Проверяем результат
                if not check_expected(step):
                    return False
            return True
        except Exception as e:
            log(f'Не удалось воспроизвести: {e}')
            return False

Что не работает: честный разбор

Если бы я остановился сейчас, это звучало бы как магия. Но нет. Вот где всё ломается.

Стена WebView

CDP видит только внутри web-вью приложения. Он не видит операционную систему вокруг: нативные диалоги выбора файлов, окно входа в систему, уведомления ОС, запросы keychain. Целая категория багов живёт за пределами досягаемости агента. Приходится честно признавать границу, а не притворяться, что проверили.

Тихие сбои вызывают галлюцинации

Самые сложные проблемы — не громкие ошибки, а тихие, когда что-то ломается молча, и агент радостно рассказывает об успехе, которого не было. Большая часть инженерии ушла на то, чтобы сделать сбои громкими, чтобы агент замечал и признавал их, а не выдумывал хэппи-энд.

Это не CI-гейт

Эти запуски управляют реальным, работающим, авторизованным приложением. Это прекрасно для реализма, но бесполезно как быстрая проверка на каждый коммит. Это отдельный, медленный уровень. Относиться к нему как к unit-тесту — только расстраиваться.

Что украсть для себя

Если хотите попробовать нечто подобное, механика — не проблема. Playwright через CDP, расписание, пара промптов. Сложная часть, достойная вашего времени, — честность.

Заставьте агента классифицировать находки. Прикрепите уровень уверенности. Заставьте воспроизводить перед исправлением. Пусть «я не смог» будет совершенно нормальным ответом. Агент, который сообщает о десяти реальных багах и признаётся в трёх сомнительных, стоит гораздо больше, чем тот, который сообщает о тринадцати и заставляет проверять каждый.

Баги никогда не были впечатляющей частью. Впечатляет создание того, чьей честности можно доверять.

Практический вывод

Попробуйте прямо сейчас: возьмите Playwright, подключитесь к вашему приложению через CDP и напишите простого охотника, который проверяет одну критическую страницу. Заставьте его классифицировать каждую аномалию. Через неделю вы увидите, сколько тихих багов живёт в вашем продукте.

#AI-агенты#поиск багов#Playwright#автоматизация тестирования#Python
Al
Редакция Algolit

Пишем про алгоритмы, подготовку к собеседованиям и карьеру в IT — так, чтобы было понятно и полезно.

Хочешь закрепить знания на практике?

Решай задачи на Algolit — интерактивная платформа для обучения

Начать бесплатно →