.png)
Когда AI-агент перестал просто писать код и начал испытывать всю систему
Как один агентный процесс связал ESP32, Android-планшет и Kotlin BFF — и почему меня удивил не написанный код.
Я давно работаю с coding agents. Прошивки для микроконтроллеров, Android-приложения, Kotlin-сервисы — всё это я уже поручал агентам по отдельности. Поэтому в этой истории меня не удивило, что AI написал код сразу для трёх технологических стеков.
Удивило другое.
Я наблюдал, как агент сам выстроил цепочку от физического Bluetooth-микрофона до серверного хранилища. Он подключал устройство к планшету, запускал запись, проверял аудиофайлы, специально разрывал Bluetooth-соединение, наблюдал за восстановлением, а затем отслеживал отправку записей на BFF.
В какой-то момент я понял, что смотрю не на генерацию кода. Передо мной шёл инженерный эксперимент, в котором агент управлял почти всем испытательным стендом.
Задача, которую нельзя проверить только тестами
В рабочем Android-приложении требовалась запись звука с внешнего Bluetooth-микрофона в течение смены. Приложение работает на планшете, в том числе в ограниченном режиме под MDM: пользователь не должен каждый раз уходить в системные настройки, чтобы подключить микрофон. Запись должна переживать временные обрывы связи, разбиваться на сегменты и передаваться на сервер.
Важная деталь: подходящего микрофона для отладки у меня сначала не было. Поэтому я решил сделать тестовый источник самостоятельно — на ESP32.
Так появились три части системы:

Рис. 1. Путь звука и инструменты управления стендом: сплошные линии показывают передачу данных, пунктир — управление и наблюдение со стороны агента.
Но сама по себе эта схема ещё ничего не доказывает. Самое интересное началось, когда агент получил возможность управлять устройствами и наблюдать результаты на каждом участке.
Сначала агент сделал себе микрофон
Мы начали с ESP32-WROOM-32 и I2S-микрофона INMP441. Агент предложил использовать Bluetooth HFP: ESP32 изображает гарнитуру, Android-планшет принимает звук через Bluetooth-аудиомаршрут.
Агент написал прошивку и отдельное Android-приложение для экспериментов. Первые проверки быстро показали, насколько реальная система отличается от схемы на бумаге.
На планшете маршрут записи выглядел корректным, но измеренный уровень сигнала оставался около −120 dBFS — фактически тишина. Проблема находилась на стыке прошивки, Bluetooth SCO и аудиоподсистемы конкретного планшета. Для рабочего звука пришлось менять обе стороны: Android-тестер открыл бесшумный обратный аудиопоток, а прошивка скорректировала передачу PCM. После этого агент сообщил об успешной записи с уровнем около −27,3 dBFS.
От команды приступить к реализации до первой работающей записи на настоящем планшете прошло примерно два часа пятьдесят минут по журналам сессии. Не «за один промпт»: с диагностикой, ошибками и изменениями на обеих сторонах соединения.
Прошивка, которая специально ломает связь
Для обычной демонстрации достаточно записать несколько секунд звука. Для реального приложения этого недостаточно: микрофон может отключиться посреди смены, Bluetooth может восстановиться не сразу, а аудиофайлы не должны оставаться повреждёнными.
Я поставил задачу научиться воспроизводить обрывы. Агент добавил в прошивку команды управления Bluetooth-радио через USB и режим, который отключал и включал связь по расписанию со случайными интервалами. Затем подготовил сбор логов с ESP32 и планшета, проверку WAV-файлов и анализатор длинных прогонов.
Это был переломный момент. Прошивка перестала быть просто источником звука. Она стала управляемым генератором неисправностей.
Агент мог запустить запись на Android, выключить Bluetooth на ESP32, дождаться потери аудиомаршрута, снова включить радио и проверить, что запись восстановилась. Он контролировал не только ожидаемый результат, но и условия, в которых этот результат должен возникнуть.
В коротком испытании прошли 20 из 20 циклов отключения и восстановления. Закрытие WAV после обрыва занимало от 1,30 до 2,26 секунды. Но короткий тест — ещё не доказательство устойчивости на протяжении смены.

Рис. 2. Управляемый обрыв связи и проверка восстановления. В коротком испытании прошли 20 из 20 циклов.
Ошибка на 45-й минуте, которую короткие тесты не нашли
Следующий эксперимент должен был длиться два часа. Агент подготовил длительный прогон с периодическими разрывами Bluetooth и сбором событий с обеих сторон.
Первый запуск остановился через 45 минут 44 секунды. Причиной завершения записи стала потеря аудиофокуса после системного уведомления. До этого момента восстановление после Bluetooth-обрывов работало, но система всё равно не выдержала длительный сценарий.
Здесь я вмешался в метод проверки: сначала воспроизвести ошибку на текущей версии, затем исправить и убедиться, что воспроизведение больше не приводит к сбою.
Агент добился воспроизведения настоящим уведомлением на планшете, изменил обработку кратковременной потери фокуса и проверил серию уведомлений. При этом окончательная потеря фокуса по-прежнему должна была останавливать запись — нельзя было просто игнорировать все события подряд.
Дальше были новые прогоны. Наконец тестовое приложение прошло двухчасовой сценарий: 15 разрывов Bluetooth и 15 восстановлений, 31 WAV-файл. После переноса тестового приложения на Kotlin аналогичный прогон тоже прошёл: 15 из 15 восстановлений, 32 WAV-файла.
Важное ограничение: это не была бесшовная запись. При обрывах терялся звук — в исследовании зафиксированы промежутки примерно 20–62 секунды. Успешный результат анализатора означал прохождение заданных проверок на конкретном стенде, а не гарантию непрерывного аудио при любых условиях.

Рис. 3. Результаты отдельных прогонов. Двухчасовые испытания прошли в тестовом приложении; прогон рабочего приложения оборвался перезагрузкой планшета примерно на 90-й минуте и не был засчитан. Причина перезагрузки осталась неизвестной.
От лабораторного приложения к рабочему
На этом можно было закончить красивую демонстрацию. Но мне нужна была функция в существующем Android-приложении, а не отдельный прототип.
Я заранее потребовал, чтобы экспериментальный код можно было переносить в рабочий проект. Агент выделил переиспользуемые модули для Bluetooth и записи, а затем изучил ограничения целевой кодовой базы. Версии Kotlin, Android Gradle Plugin, SDK и устройство сборки отличались. Поэтому перенос не был простым копированием файлов.
Агент адаптировал модули, добавил экран управления микрофоном, сопряжение внутри приложения и фоновую выгрузку сегментов. Для старых устройств понадобился отдельный путь сопряжения без API, доступных только на новых версиях Android.
Три стека в одном цикле отладки
Позже работа дошла до BFF. Android должен был отправлять WAV-сегменты по multipart HTTP, сервер — принимать их и сохранять в MinIO.
Именно здесь я увидел то, чего раньше не наблюдал в таком масштабе. В одном агентном сеансе инструментами становились сразу три мира: UART для ESP32, ADB и логи настоящего планшета, код и запуск Kotlin BFF. Агент последовательно переключался между ними, а не просто передавал готовые исходники от одного «разработчика» другому.
Он мог управлять Bluetooth-источником, запускать запись, следить за файлами, отправлять их с планшета и проверять результат на локальном сервере. Для меня это и было главным впечатлением: вся цепочка данных стала для агента единым объектом работы.
На сквозной проверке обнаружилась серверная ошибка, которую не выявила изолированная разработка обработчика: чтение тела multipart-запроса могло блокироваться. Агент исправил участок чтения с использованием Dispatchers.IO и повторил проверку с живого планшета. Исправление вошло в серверный MR незадолго до слияния.
Это не значит, что «всё происходило одновременно». Прошивка, тестовое приложение и рабочие изменения создавались в разные дни и сессии. Но потом агент действительно последовательно работал со всеми тремя стеками.
Что получилось, а что ещё не доказано
В тестовом контуре агент добился работающей записи с ESP32, сопряжения внутри приложения, нарезки на пятиминутные сегменты, восстановления после обрывов и успешных двухчасовых испытаний. В рабочем Android-проекте появились соответствующие компоненты и фоновая отправка записей. BFF научился принимать WAV и сохранять его в MinIO; сквозная проверка проводилась с реального планшета на локальный сервер.
Нет подтверждённой проверки на реальном Android 7.1.1, в целевой MDM-конфигурации и с конечной моделью коммерческого микрофона. Не проверены десятичасовая смена и все производственные режимы. Успех лабораторного стенда — важный результат, но не сертификат готовности к эксплуатации.
Чем в этой истории занимался я
Я не писал вручную каждый Bluetooth callback, не управлял каждым запуском записи и не переключался между тремя IDE. Именно эта часть работы постепенно ушла агенту.
Но я выбирал, что именно требуется доказать. Требовал настоящего планшета вместо эмулятора, воспроизведения сбоя до исправления, двухчасовых испытаний, восстановления записи после обрыва, совместимости с рабочим приложением. Останавливал неверные технические предположения, проверял интерфейс и код, предоставлял оборудование и физический доступ, слушал записанный звук — того агент сам сделать не мог.

Рис. 4. Конкретные действия агента и разработчика в этом проекте.
Это не история о том, что человек стал ненужным. Скорее о том, что изменилась граница между моей работой и работой агента.
Раньше я ожидал от агента реализации отдельной задачи: прошивки, Android-функции или серверного endpoint. Здесь он смог сам построить испытательный контур между ними, вызвать неисправность, собрать свидетельства и довести исправление через несколько систем.
Меня удивили не три проекта, написанные AI. Меня удивило, что агент начал работать с ними как с одной реальной системой.
И именно за этим я сидел и наблюдал.