К ленте · Россия

РоссияСтатьяМодели

ИИ-агенты в QA: как я выстроил процесс от анализа требований до CI

Содержание
  1. Матрица совместимости: как выбрать, что проверять
  2. Маршрутизируйте контекст через версионируемый QA-репозиторий
  3. PREP, EXEC и AUTO: переходы между фазами
  4. Практический кейс: gasless-переводы
  5. Превращайте сбои в версионируемые правила
  6. Чем приходится жертвовать
  7. Что изменилось на практике
  8. Масштабируйте процесс, а не полномочия агента
  9. Начните с одного рискованного пути

Как версионируемый QA-репозиторий помогает маршрутизировать контекст, повторно использовать процессы и сохранять обоснование выбора тестов.

Прежде чем поручить ИИ-агенту, работающему с кодом, написание тестов, нужно понять, как должна работать фича и какие компоненты она затрагивает. Требования, код, ограничения платформ и предыдущие решения хранятся в разных репозиториях и инструментах. Для каждой задачи приходится собирать нужные материалы и сопоставлять их.

В первой половине 2026 года я решал эту задачу, тестируя экосистему TON и TON Connect SDK.

В реестре было около 30 интеграций кошельков. К ним добавлялись несколько приложений, разные ОС, способы подключения, сети и версии SDK. Проверить все сочетания невозможно. А доступ агента ко всем источникам ещё не определяет, что именно ему нужно прочитать и проверить.

Поэтому вместо одного большого промпта со всей базой знаний использовал QA-репозиторий с указателями на нужные источники. Для каждой задачи агент получал требования, код и ограничения, которые к ней относились. Там же сохранялись выбранные проверки и обоснование выбора.

Процесс оформил как Process-as-Code: правила работы хранятся в файлах, версионируются в Git и проходят ревью, как код. В репозитории описано, что агент должен прочитать, какие ограничения учесть, как оформить результат и что проверить инженеру. Я проверял результаты и решал, можно ли переходить к следующей фазе.

Приложение и кошелёк — две стороны интеграции. dApp — приложение, которое работает с кошельком пользователя. Оно может открываться в обычном браузере, WebView Telegram Mini App или WebView внутри кошелька. Сам кошелёк — отдельное приложение, веб-клиент или расширение. Telegram здесь служит средой выполнения части интеграций.

TON Connect — протокол обмена между приложением и кошельком. Приложение получает адрес подключённого кошелька и может запросить подпись или отправку транзакции. Ключи и обработка подписи остаются на стороне кошелька. Секретный ключ приложению не передаётся.

В исходниках TON Connect SDK несколько уровней:

  • @tonconnect/protocol — форматы сообщений и правила обмена между приложением и кошельком.
  • @tonconnect/sdk — подключение, восстановление сессии и запросы к кошельку без готового интерфейса.
  • @tonconnect/ui — готовый интерфейс подключения и выбора кошелька.
  • @tonconnect/ui-react — React-обёртка с компонентами и хуками.

HTTP Bridge и JS Bridge — два способа доставки сообщений. HTTP Bridge передаёт зашифрованные сообщения через сервер-посредник. JS Bridge используется, когда кошелёк доступен из WebView или через расширение браузера: запрос передаётся через предоставленный кошельком JavaScript-интерфейс.

Также тестировал AppKit и WalletKit: клиентскую библиотеку для приложений и компоненты для реализации кошелька. Демо-приложение и демо-кошелёк помогали проверять обе стороны интеграции и готовить UI-интеграционные тесты.

Верхняя ветка — запросы и ответы TON Connect. Нижняя — работа с API блокчейна. При запросе sendTransaction кошелёк отправляет подписанную транзакцию в сеть. Запрос подписи может завершиться ответом без отправки в блокчейн.

Матрица совместимости: как выбрать, что проверять

В область работы входили основной SDK, клиентский SDK, адаптер TON Connect, демо-приложения и тестовый раннер. Запрос на подключение, подпись или перевод проходит через несколько компонентов, которые развиваются независимо друг от друга.

Модель совместимости включала девять измерений. ОС — это Android, iOS, Windows и другие системы, а версия ОС учитывается отдельно. Контекст приложения показывает, где открыт dApp: в браузере, Telegram Mini App или WebView кошелька. Контекст кошелька показывает, в каком виде работает другая сторона интеграции: нативное приложение, веб-клиент, расширение или Mini App. Остальные измерения — сам кошелёк, транспорт, сеть блокчейна, версии SDK и контракта. Ниже — шесть из этих измерений и связанные с ними риски.

Измерение

Варианты

Почему важно

Контекст приложения

Браузер (Chrome, Safari), Telegram Mini App, WebView кошелька

Один и тот же интерфейс и транспорт TON Connect работают в разных браузерах и WebView.

Контекст кошелька

Нативное приложение, веб-клиент, расширение, Telegram Mini App

Кошелёк — независимая реализация другой стороны протокола.

Транспорт

HTTP Bridge или JS Bridge

Это разные пути в коде и способы доставки запроса.

Сеть блокчейна

mainnet / testnet

Несовпадение сетей должно явно блокироваться или обрабатываться.

Версия SDK

Старая/новая версия SDK × версия интеграции кошелька

Возможность может появиться на одной стороне раньше, чем на другой.

Версия контракта

Поддерживаемые версии контрактов

Поведение кошелька зависит не только от UI, но и от версии контракта.

Для регулярного релизного тестирования использовал три основные интеграции из реестра — условно Wallet A, Wallet B и Wallet C. Остальные сочетания не считались покрытыми. В карте покрытия были отмечены непроверенные сочетания и причины их исключения.

Ручной объём удалось сократить пятью механизмами:

  • Shift left. До ручного прогона агент сопоставлял PRD, дизайн, спецификацию и фактические изменения в коде. Неясности я разбирал с разработчиком.
  • Приоритизация. Сначала проверял ключевые кошельки, ОС и пути интеграции с учётом риска.
  • Тест-дизайн. Pairwise уменьшает число комбинаций, но не определяет, какие сочетания допустимы. Отдельно учитывал ограничения. Граничные значения и случаи с разным ожидаемым результатом оставались отдельными сценариями.
  • Автоматизация. Детерминированные критичные сценарии переходили в CI и не повторялись в каждом ручном регрессе.
  • Переиспользование. Полезные тесты, инварианты и правила сохранялись в репозитории и уменьшали объём работы для следующей фичи.

Число возможных сочетаний от этого не уменьшается. Зато видно, что проверено, какие риски остаются и что ещё нужно проверить вручную.

Маршрутизируйте контекст через версионируемый QA-репозиторий

Когда в QA включается агент, инструкций в промпте недостаточно. Исходный код продукта остаётся источником истины о реализации. Отдельный версионируемый QA-репозиторий определяет, как агент собирает, маршрутизирует и возвращает доказательства.

Изменения процесса проходят ревью. Поэтому предпосылки тест-плана, команды или решения о покрытии можно увидеть в diff, связать с автором и повторно использовать между продуктовыми репозиториями.

Артефакт

Назначение

Какой риск снижает

Точка входа

Направляет агента к нужным документам по условиям

Агент загружает нерелевантный контекст и делает вывод до проверки первичных источников.

Правила агента

Фиксируют повторяющиеся ошибки и способ их избегать

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

Спецификации и инварианты

Описывают ожидаемое поведение и условия, при которых оно меняется

Ложный дефект из-за пропущенной платформы, триггера или возможности кошелька.

Контракты

Определяют, что разработка передаёт в QA и что QA возвращает

Теряются предположения, которых не видно в diff.

Скиллы и шаблоны

Стандартизируют баг-репорты, тест-кейсы, тест-планы, PR и карты покрытия

Непредсказуемые артефакты и неверная маршрутизация.

Тест-планы и матрицы

Сохраняют решение о покрытии для конкретного pull request или релиза

Объём проверки приходится восстанавливать снова и снова, а исключения остаются неявными.

В начале сессии агент должен был выполнить три действия:

## Начало сессии

1. Прочитать rules/agent-rules.md.
2. Обновить данные репозиториев рабочей области через git fetch
 до анализа веток или кода.
3. Прежде чем отвечать на вопрос о поведении фичи,
 прочитать specs/invariants.md и перечислить применимые ограничения.

Эти правила направляли агента к источникам, которые нужно проверить до вывода о поведении фичи. Скилл баг-репорта задавал шаблон результата и правила маршрутизации в нужный проект.

В этой реализации стандартные интеграции и MCP-серверы позволяют агенту читать код и документацию, работать с GitHub, Linear, Figma, Notion и Allure TestOps. Коннекторы не заменяют процесс: они дают доступ к данным и операциям, а инженер проверяет результат до перехода на следующую фазу или публикации во внешней системе. Фазовые гейты здесь были ручными: инженер проверял результаты и подтверждал переход. Часть условий перехода можно проверять автоматически, например наличие обязательных артефактов или результаты тестов.

PREP, EXEC и AUTO: переходы между фазами

Каждая фаза завершалась результатом, который можно было проверить на ревью.

PREP покрывает анализ и планирование, EXEC — ручное выполнение, AUTO — автоматизацию и CI. Агент ускорял PREP и AUTO и помогал собирать доказательства в EXEC.

Фаза

Вход

Работа агента

Инженер утверждает

Результат

PREP

PRD, макеты, материалы передачи задачи, спецификация, diff

Находит расхождения, загружает инварианты, готовит вопросы, план и черновую матрицу

Объём проверки, предположения, вопросы к разработке, тест-план

Утверждённый тест-план и карта покрытия

EXEC

Утверждённый план и окружение

Создаёт тест-кейсы, готовит черновики баг-репортов, анализирует затронутые компоненты

Результаты ручного прогона, классификацию находок и локальные исправления

Проверенные находки, доказательства, итоговая матрица

AUTO

Итоговая матрица

Готовит UI-интеграционные тесты и фикстуры, отдельные E2E-сценарии и шаги прогона

Полноту проверок в тестах, границы моков, процесс запуска в CI

Тесты в продуктовом репозитории, UI-проверки в CI и отдельные E2E-прогоны

Передача работы из разработки не должна повторять то, что агент может извлечь из кода. Она должна фиксировать то, чего в коде нет:

  • отклонения от спецификации и их обоснование;
  • предположения о внешних системах;
  • ограничения окружения и фича-флаги;
  • намеренно необработанные случаи;
  • фактический объём изменений и зоны повышенного риска.

У каждой фазы были свои условия завершения. PREP заканчивается после проверки источников, согласования объёма проверки и назначения владельца каждому открытому вопросу. EXEC начинается с утверждённого тест-плана. Переход в AUTO требует вручную классифицировать находки и зафиксировать границу теста: какое поведение использует реальную интеграцию, а какие внешние зависимости можно замокать, не потеряв проверяемый инвариант.

Тест с замоканным внешним сервисом может проверить запрос, который сформировал клиентский SDK. Но он не доказывает, что реальный сервис работает или что операция выполнилась в сети. Здесь сценарии с реальной отправкой запускаются отдельно: им нужно подтверждение человека, и они исключены из CI-гейта. Разрешения на запись во внешних системах оставались отдельным уровнем контроля.

Скилл для баг-репорта

Скилл для баг-репорта задавал требования к доказательствам, правила маршрутизации и условия остановки:

/bug <наблюдаемое поведение>

Доказательства: окружение, предусловия, воспроизведение,
фактический результат, ожидаемый результат, источник ожидания

Источники маршрутизации:
- Правила приоритетов: rules/bug-priority.md
- Карта ответственности: projects/team-ownership.md
- Карта проектов: projects/bug-routing.md

Определить: команду, проект, исполнителя, приоритет и метки.

Правила:
- Не заполнять неизвестные поля.
- Помечать корневую причину как гипотезу.
- Не создавать задачу, пока не подтверждены ожидаемый результат и маршрут.
- Если маршрут неоднозначен, остановиться и уточнить; не угадывать.

Агент собирал доказательства и готовил черновик баг-репорта. Я проверял факты и подтверждал создание задачи. Возможное исправление оставалось предложением до повторной проверки изменённой реализации.

Практический кейс: gasless-переводы

В AppKit я проверял gasless-переводы jetton — токенов в TON. В этом сценарии пользователь платил комиссию в jetton, а внешний релеер оплачивал сетевую комиссию в TON. Механика опиралась на Wallet V5.

AppKit получал конфигурацию и котировку, затем через TON Connect запрашивал подпись внутреннего сообщения. Кошелёк возвращал подписанное сообщение в формате BoC, а релеер отправлял его в сеть. Для тест-плана были важны поддержка нужного запроса кошельком, срок действия котировки и поведение при смене кошелька или сети.

PREP: от расхождений к тест-плану

Единого актуального описания фичи не было. Агент сопоставил документацию с кодом и нашёл расхождение: в документации ещё фигурировал estimateGasless, а в реализации уже использовался getGaslessQuote. Проверка истории Git показала, что API переименовали при рефакторинге. Я проверил этот вывод и оформил дефект документации.

В этой реализации требовались контракт Wallet V5 и заявленная приложением кошелька поддержка SignMessage. Одного V5 было недостаточно. Из этого условия получились два пути в тест-плане: успешный перевод с поддерживаемым кошельком и ожидаемый отказ без нужной capability.

Агент собрал расхождения и вопросы разработчику, я проверил их по коду и обсудил с разработчиком. По итогам обсуждения разработчик доработал несколько связанных мест:

  • после ошибки отправки старая котировка инвалидировалась, чтобы повторная попытка получала новую;
  • выбор токена для комиссии учитывал асинхронную загрузку конфигурации;
  • ошибки парсинга возвращались как типизированные ошибки;
  • при смене кошелька или сети режим gasless отключался.

После проверки соответствующих коммитов эти переходы вошли в тест-план. К ручному прогону были согласованы ожидания для успешного перевода, отказов и повторных попыток.

EXEC: ручной прогон и подготовка автоматизации

Протестированная версия независимого кошелька использовала контракт V5, но не заявляла SignMessage. Gasless оставался недоступным — это соответствовало ожидаемому поведению.

Для успешного пути я использовал контролируемый демо-кошелёк с поддержкой SignMessage. Вручную прошёл сценарий от включения gasless в dApp до подписи и проверки результата в mainnet. Перевод и комиссия списались в jetton, баланс TON не уменьшился.

Повторяемую подготовку между проверками выполняли скрипты, подключавшиеся к уже открытому Chrome через Chrome DevTools Protocol (CDP). В браузере сохранялось установленное по QR подключение к кошельку. Скрипты выполняли промежуточные действия, а подпись, критичные переходы UI и итог операции проверял вручную.

Дополнительные проверки на Playwright покрывали вёрстку на разных размерах экрана, состояние без подключённого кошелька, отображение ошибок релеера, XSS через замоканный ответ и отсутствие секретов в консоли. Эти результаты учитывались отдельно от ручного E2E-прогона. Одноразовые скрипты подготовки не считались самостоятельными тест-кейсами.

По итогам EXEC я уточнил матрицу автоматизации с учётом проверенных сценариев, доступного окружения и фикстур. Она определяла, какие проверки можно повторять в CI и какие требуют отдельного прогона с реальной отправкой.

AUTO: из матрицы в CI-тесты

Для UI-интеграционных проверок в CI я выбрал фикстуру из двух вкладок: тестируемый dApp и контролируемый демо-кошелёк. Между ними работал реальный TON Connect, кошелёк подписывал сообщение локально. Мок релеера перехватывал запросы конфигурации, котировки и отправки.

Тесты по согласованной матрице помог реализовать агент. На ревью я проверял ассерты и границы моков. В набор вошли, например, обновление котировки после смены токена комиссии, восстановление формы после отказа от подписи и отсутствие повторного запроса отправки.

Один из тестов выполнял локальную подпись и проверял запрос к релееру. Сокращённый фрагмент:

const capture: SendCapture = { requests: [] };
await mockGaslessConfig(app, { assets: [USDT_MASTER] });
await mockGaslessEstimateOk(app);
await mockGaslessSendOk(app, { capture });

await connectWallet({ widget, wallet });
await minter.openTransfer(USDT_MASTER);
await minter.enableGasless();
await minter.fillTransfer(DEFAULT_RECIPIENT, TRANSFER_AMOUNT);

await minter.sendButton.click();
await wallet.signMessage(true);

await expect.poll(() => capture.requests.length).toBe(1);
expect(capture.requests[0]?.boc).toBeTruthy();
expect(capture.requests[0]?.wallet_public_key).toBeTruthy();

Здесь проверялись однократность запроса и наличие BoC и публичного ключа. Доставку транзакции и её выполнение в блокчейне подтверждал отдельный E2E-прогон с реальной отправкой. TON Connect в CI оставался реальным, поэтому сетевые зависимости сохранялись.

E2E-сценарии с реальной отправкой исключались из обычного CI-прогона фильтром:

npx playwright test --config e2e.config.ts \
 --grep-invert "@real-send"

UI-интеграционные тесты из матрицы остались в продуктовом репозитории и запускались в CI на релевантных изменениях PR. Человекочитаемые шаги получались из тестового кода и публиковались в TestOps. Автоматизированные сценарии не дублировались отдельными ручными тест-кейсами.

Превращайте сбои в версионируемые правила

Повторяющиеся ошибки становились основой новых правил для агента. Например:

R2 — Проверяй утверждения «не затронуто» по ветке

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

Чем приходится жертвовать

Эта архитектура не максимизирует автономность агента. Она ограничивает его полномочия, чтобы результаты оставались проверяемыми.

Решение

Польза

Цена и риск

Отдельный репозиторий QA-процесса

Переиспользуемые правила и единый control plane для продуктов

Процесс может отставать от кода; агент обязан читать актуальную ветку и diff до вывода.

Ручной гейт между PREP, EXEC и AUTO

Снижает риск выдуманных фактов, неверных границ проверки и слабых проверок в тестах

Инженер остаётся узким местом: пропускная способность процесса не масштабируется автоматически.

Отбор комбинаций с учётом рисков

Объём тестирования остаётся управляемым

Непроверенные комбинации всё ещё риск; их нужно фиксировать явно.

Моки внешних API в CI

Повторяемый CI-гейт без реальной отправки операций во внешнюю систему

CI не доказывает поведение реального кошелька или внешнего сервиса.

Отдельный путь для проверки реальной интеграции

Проверяет выбранный сквозной путь интеграции

Нужны ручной запуск, контролируемое окружение и явное одобрение.

Скиллы с маршрутизацией

Стандартизируют результат и место хранения

Маршрутизацию нужно поддерживать по мере изменений проектов и инструментов.

Что изменилось на практике

Это практические оценки для задач с SDK сопоставимого масштаба на основе моей работы как основного QA-практика. Это не универсальные бенчмарки и не результаты контролируемого эксперимента.

Фаза QA

Без процесса с ИИ

Process-as-Code + агент

Комментарий

PREP: анализ, планирование, декомпозиция, аудит

8–14 ч

2–4 ч

Агент готовит черновик с опорой на доказательства; инженер его валидирует.

EXEC: ручное выполнение

4–8 ч

4–8 ч

Надёжная ручная проверка не становится существенно быстрее.

AUTO: автотесты и CI

16–32 ч

6–14 ч

Агент ускоряет реализацию и рефакторинг; инженер оценивает полноту покрытия и достаточность проверок.

Итого

28–54 ч

12–26 ч

Операционные оценки для сопоставимых фич.

На момент этих оценок подход был внедрён недавно и глубоко применён только к ограниченной части продукта. Эти оценки не стоит читать как доказательство полного покрытия или измеренного снижения количества дефектов, ушедших в прод.

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

Масштабируйте процесс, а не полномочия агента

Чтобы использовать этот подход в команде, нужно:

  • назначить владельцев правилам, спецификациям и инвариантам;
  • версионировать контракты скиллов и правила маршрутизации, а для каждого сохранённого артефакта фиксировать использованную редакцию процесса;
  • обновлять процесс по повторяющимся сбоям и переделкам после ревью.

В публичном companion-репозитории есть обобщённая версия структуры.

Начните с одного рискованного пути

Не начинайте с программы «автономный QA для всей компании».

  • Выберите одну фичу, которая проходит через несколько систем и регулярно требует ручного регресса.
  • Соберите минимальный полезный control plane: индекс контекста, несколько инвариантов, один контракт передачи работы, один скилл и матрицу покрытия.
  • Определите фазовые гейты до добавления автономности. Зафиксируйте, что агент вправе подготовить, что должен одобрить человек и где границу обеспечивают права учётных записей или защита веток.
  • Разделите детерминированные CI-проверки и результаты сквозных проверок с реальной интеграцией. Явно напишите, что доказывает каждый путь — и чего он не доказывает.
  • Считайте каждый повторяющийся сбой запросом на изменение control plane.

Цель — не автономный QA-агент. Цель — QA-система, которая может принять больше работы агента, не отдавая ему инженерные полномочия.

Английская версия: Building a Control Plane for AI Agents in Software QA

Источник: Хабр · статьиПубликуется с разрешения правообладателя, подтверждённого редакцией.Оригинал: ИИ-агенты в QA: как я выстроил процесс от анализа требований до CI ↗

Есть кому отправить?

Скопируется постоянная ссылка на этот материал.

Комментарии

0

Обсудите материал с другими читателями.

Загружаем комментарии…

Ваш комментарий

Для публикации потребуется вход через Яндекс ID.