Я не умел делать A/B-тесты. AI-агент построил аналитику и теперь сам её анализирует
У нас было три варианта нового экрана сканирования ценника.
Все три выглядели достаточно разумно. Claude Design подготовил макеты, я показал их коллегам и устроил голосование. Но проблема голосованием не решилась: явного лидера не оказалось.
Тогда я предложил:
Раз мы сами не можем решить, пусть решат пользователи.
Так в обычной Android-задаче неожиданно появился A/B/C-тест.
С этого момента для меня началась гораздо более интересная часть истории. Новый экран и все три варианта интерфейса AI-агент написал сам, но именно это оказалось самым простым.
Я никогда до этого не проводил A/B-тестирование.
Я читал статьи, смотрел видео и примерно представлял общую идею: делим пользователей на группы, показываем разные варианты, собираем метрики и сравниваем.
Но между этим описанием и реальным экспериментом в production лежит довольно большая пропасть.
Какие события отправлять?
Какие параметры у них должны быть?
Как отличить нормальную попытку сканирования от закрытого экрана?
Как измерять время?
Как понять, что код не распознался потому, что пользователь ушёл, а не потому, что приложение упало?
Как сравнивать магазины с разным количеством сканирований?
Как не сломать QR-сценарий, улучшая обычный штрихкод?
И наконец: как потом вообще анализировать всё это в Firebase?
Я решил не изучать ещё один набор абстрактных примеров, а попробовать пройти весь путь на своей реальной задаче вместе с агентом.
Первая моя идея оказалась неправильной
Когда я начал думать об аналитике сканера, моя первая интуиция была простой:
чем больше действий нужно анализировать, тем больше событий надо отправлять.
Я начал размечать много разных событий.
Логика казалась естественной: отдельно открытие, отдельно успешное сканирование, отдельно ошибка, отдельно «поднесите ближе», отдельно какие-то действия пользователя.
Агент предложил совершенно другую модель.
Для эксперимента ему в основном понадобились два события:
- barcode_scan_scanner_session_start
- barcode_scan_scanner_session_finish
Зато каждое событие получило контекст.
У сессии появился `session_id`, вариант интерфейса, магазин, устройство, источник запуска и другие параметры.
А при завершении — результат, тип кода, длительность сканирования, информация про TooFar, количество несовпадений при двойном подтверждении, использование фокуса, зума, фонарика, признак распознавания с первой попытки и другие характеристики.
Для меня это был первый важный результат эксперимента ещё до появления любых цифр.
Я бы сам так аналитику не спроектировал.
До этого я воспринимал аналитику скорее как набор событий: произошло действие — отправили event.
А здесь агент фактически спроектировал сущность «сессия сканирования».
События стали только способом передать начало и результат этой сессии.
И дальше уже можно было задавать вопросы не к отдельным кликам, а к попытке сканирования целиком.
Firebase оказался только источником данных
Следующая проблема обнаружилась довольно быстро.
Собирать события в Firebase Analytics несложно. Но анализировать такой эксперимент прямо в интерфейсе Firebase уже неудобно.
Start и finish — разные события.
Параметры лежат внутри вложенного `event_params`.
Нужно связывать события по `session_id`.
Нужно считать сессии, у которых есть start, но нет finish.
Нужно делать разрезы по варианту интерфейса, магазину, бизнес-юниту и модели устройства.
Нужны p50 и p75, а не только средние значения.
Нужно следить, чтобы сырые daily- и intraday-таблицы не дали дубли.
До этой задачи я никогда не работал с экспортом Firebase Analytics в BigQuery.
Агент объяснил, что для нормального анализа он нужен, а потом буквально провёл меня через настройку: куда зайти, что включить и что нажать.
Это был ещё один любопытный момент.
Обычно изучение новой технологии выглядит примерно так:
«почитать документацию → посмотреть пример → попробовать на тестовых данных → наконец применить в проекте».
Здесь всё происходило наоборот.
У меня уже была реальная задача, реальные события и реальные пользователи. А BigQuery я осваивал ровно в том объёме, который был нужен, чтобы агент мог двигаться дальше.
Потом агент предложил `scanner_ab`
Когда экспорт заработал, появилась следующая проблема.
Сырые Firebase events — не самый удобный интерфейс даже для агента.
Чтобы ответить на простой вопрос вроде:
Сколько успешных сессий было у варианта B?
нужно сначала извлечь параметры из `event_params`, найти start, найти соответствующий finish, связать их по `session_id`, обработать пропущенные завершения и только после этого считать метрику.
Если делать это в каждом запросе, огромный кусок SQL будет повторяться снова и снова.
Агент предложил отдельный dataset `scanner_ab` и подготовленный слой `scanner_ab.sessions`.
В нём одна строка соответствует одной сессии сканирования.
То есть между сырыми Firebase events и аналитическими вопросами появился промежуточный слой:
Именно здесь я начал понимать, зачем в аналитике вообще нужны такие подготовленные витрины.
Я сначала называл это для себя «нормированными событиями по сканеру», но точнее это аналитический слой данных.
Сырые события остаются сырыми событиями.
А `scanner_ab.sessions` превращает их в удобную для анализа бизнес-сущность — одну попытку сканирования.
Самое интересное началось после настройки
На этом месте можно было бы написать обычный отчёт:
«Мы подключили Firebase к BigQuery, написали несколько SQL-запросов и посчитали A/B/C».
Но именно здесь для меня началась самая интересная часть.
Я практически не пишу эти SQL-запросы.
Я задаю агенту вопросы обычным языком.
Например:
Сравни A/B/C за последние три дня.
Или:
Посмотри результаты в разрезе магазинов.
Или:
Сделай анализ по моделям устройств.
Или уже совсем инженерный вопрос:
В аналитике появился провал. Сравни его с Crashlytics.
Дальше агент сам определяет, какие данные нужны, строит SQL, выполняет запросы и возвращает результат в виде таблицы.
И вот тут особенно хорошо видна разница между пользовательским вопросом и тем, что происходит под капотом.
Один человеческий вопрос может превратиться в огромный SQL-запрос.
Там появляются:
Если бы мне пришлось делать это самому, мне сначала пришлось бы довольно серьёзно изучить BigQuery и аналитический SQL.
А для агента этот SQL — просто промежуточный технический слой.
Он не показывает мне его, если я не прошу.
Я вижу уже таблицу.
Например условно:
И могу задать следующий вопрос:
А теперь разложи B по моделям планшетов.
Или:
Покажи только два магазина, где метрика ухудшилась.
Или:
Это массовая проблема или несколько конкретных магазинов?
По сути SQL перестал быть моим интерфейсом к данным.
Мой интерфейс — агент.
Но агенту недостаточно просто уметь писать SQL
Это, пожалуй, самый важный момент.
Если бы вся история сводилась к генерации длинных запросов, она была бы не очень интересной.
LLM умеют писать SQL уже давно.
Но здесь агент сначала сам спроектировал данные, которые потом собирался анализировать.
Сначала он определил, какая телеметрия нужна.
Потом внедрил её в Android-приложение.
Потом объяснил, как получить raw events в BigQuery.
Потом предложил отдельный аналитический dataset.
Потом начал использовать его для собственных запросов.
Получился замкнутый цикл:
Это уже совсем другая степень участия агента в разработке.
Он не просто пишет код по заданному ТЗ.
Он помогает построить систему, в которой результат этого кода можно измерить на реальных пользователях.
A/B-тест быстро превратился ещё и в инструмент диагностики
У продуктовой аналитики есть ещё одно полезное свойство: она показывает не только, какой вариант интерфейса быстрее.
Она показывает, когда что-то пошло не так.
В какой-то момент в данных появился заметный провал.
И вместо запроса «какой вариант победил?» возник совсем другой:
Почему ухудшились показатели?
Дальше можно было смотреть уже не только на A/B/C.
Разложить проблему по магазинам.
Проверить магазины.
Посмотреть модели устройств.
Понять, это один продавец, один планшет или массовое изменение.
А затем сопоставить момент деградации с Crashlytics.
То есть тот же аналитический контур, который строился для продуктового эксперимента, стал частью технического расследования.
Это для меня особенно интересно.
Агент получил возможность сопоставлять сразу несколько типов контекста:
И здесь его ценность уже не в том, что он «написал запрос».
Ценность в том, что он может пройти всю цепочку от жалобы пользователя до технической гипотезы.
Всё ли теперь можно отдать агенту?
Нет.
A/B-тест хорошо показывает границу.
Например, в нашем эксперименте вариант назначается магазину.
Это значит, что тысяча сканирований в одном магазине — не то же самое, что тысяча независимых участников эксперимента.
Если один крупный магазин делает намного больше сканирований, чем остальные, нельзя просто свалить все сессии в одну таблицу и объявить вариант победителем.
Именно поэтому анализ нужно делать сначала на уровне магазина, а потом уже сравнивать варианты.
А ещё есть внешние факторы:
Агент умеет находить эти ограничения и строить правильные разрезы.
Но финальный вывод всё равно нельзя превращать в магию:
AI сказал, что B лучше.
Человек должен понимать, как был устроен эксперимент и какой вывод данные действительно позволяют сделать.
Иначе можно получить очень красивую таблицу с неправильным смыслом.
Что для меня изменилось
Сам факт, что AI-агент способен работать в области, в которой я не специалист, для меня уже давно не новость.
Я постоянно использую агентов в разработке и давно перестал воспринимать их только как автодополнение кода.
Но продуктовая аналитика подвернулась впервые.
И здесь я увидел тот же эффект в совершенно другой области.
Раньше граница задачи выглядела примерно так:
На практике получилось иначе:
Я не стал специалистом по BigQuery.
И не стал аналитиком.
Но теперь могу работать с задачей, для которой раньше сначала потребовалось бы освоить несколько новых инструментов.
Наверное, именно это для меня и есть главное изменение роли разработчика при работе с AI-агентами.
Не «теперь можно ничего не знать».
Наоборот, вопросов становится больше.
Нужно уметь сформулировать проблему.
Нужно заметить, когда метрика выглядит подозрительно.
Нужно понимать ограничения эксперимента.
Нужно не принимать красивый ответ автоматически.
Но технический путь между вопросом и данными больше не обязательно проходить вручную самому.
В моём случае он выглядит довольно буквально:
И три варианта экрана сканера оказались просто хорошим поводом это обнаружить.
Это только одна из историй о том, как я использую AI-агентов в реальной разработке. У меня накопилось уже несколько проектов: от Android-инструментов и MCP-сервисов до личных порталов, автоматизации и DSP. Я собрал их на отдельной странице — «Созвездие AI-проектов».
Там можно посмотреть, что уже сделано, какие задачи я отдавал агентам и во что эти эксперименты в итоге превратились. Если какой-то проект покажется вам особенно интересным — напишите. Вполне возможно, следующая статья будет именно о нём.