A/B двух заголовков попапа без второго скрипта: как я сделала это на одном embed
В прошлой статье разбирала, почему «один промпт — и готовый попап» разваливается, и как устроен пайплайн из парсера и трёх вызовов Yandex GPT. В конце обещала отдельно рассказать про A/B двух заголовков на одном embed. Дошла.
Сервис тот же — ИИ-conversion. Текст снова не про «купите», а про инженерную задачу: как сравнить два оффера на живом трафике, не вешая на сайт второй счётчик, второй виджет и вторую админку.
Зачем вообще A/B, если ИИ уже «придумал хороший текст»
Генерация убирает чистый лист. Она не говорит, какой заголовок реально соберёт заявки.
Типичная развилка после генерации:
- вариант A: «Рассчитать стоимость за 2 минуты»
- вариант B: «Бесплатный расчёт — без предоплаты»
Оба звучат нормально. Оба закрывают разные страхи. «Нравится глазами» — плохой критерий. Нужны показы, клики и заявки на одном и том же трафике.
Классический путь маркетолога: Google Optimize / свой AB-сервис / два разных скрипта / UTM на две страницы. Для владельца сайта на Tilda это часто «потом». Я хотела, чтобы тест запускался из того же кабинета, куда уже вставили одну строку кода.
Что нельзя было ломать
Ограничения были жёсткие:
- Один script на сайт. Клиент уже поставил виджет — не просим «ещё один для эксперимента».
- Один посетитель = один вариант. Иначе человек видит то A, то B, а в статистике каша.
- Метрики те же, что и без теста: показ, клик, заявка. Без отдельной «магии A/B».
- Победитель выключается одной кнопкой: проигравший перестаёт показываться, скрипт пересобирается.
Если решение усложняет онбординг — оно проиграет даже самому умному сплиту.
Модель данных проще, чем кажется
Не стала городить «варианты внутри одного попапа» с ветвлением полей. Сделала иначе:
- два обычных попапа на одном домене (два заголовка, можно разные буллиты и CTA);
- сущность experiment: ссылки на A и B, доля трафика на A (split_a, по умолчанию 50), статус running / completed;
- на сайте по-прежнему один embed, внутри которого живут оба варианта.
Плюс: редактирование как у обычного попапа. Минус: нельзя случайно завести два теста на одном сайте или кинуть в тест колесо фортуны — на это стоят проверки.
Как виджет решает, что показать
В JS уходит компактный конфиг: id эксперимента, id варианта A, id варианта B, split_a.
Перед показом виджет смотрит в localStorage по ключу эксперимента. Если вариант уже выбран — показывает его. Если нет — бросает монетку по split_a, сохраняет выбор и показывает только «свой» попап. Второй в бандле молчит.
Почему localStorage, а не cookie на бэкенде:
- нет лишнего round-trip до первого показа;
- конфиг уже в скрипте, не нужно ждать API;
- sticky на устройстве без серверной сессии.
Минусы честно: инкогнито и смена устройства = новый бросок монетки. Для сравнения заголовков на лендинге этого обычно достаточно. Для кросс-девайс атрибуции — нет; у меня задача другая.
Один скрипт, два попапа — как это не конфликтует
Самый скользкий момент: на сайте один файл, а вариантов два.
Решение: при старте и остановке теста оба виджета пересобираются. В payload активного теста попадает один и тот же ab_experiment. Оба скрипта «знают» про сплит, но на экране оказывается только тот, чей id вытянул выбор.
Когда тест завершают и выбирают победителя:
- статус становится completed;
- проигравший попап деактивируется;
- оба скрипта пересобираются уже без конфига эксперимента.
Клиенту не нужно трогать код на сайте. Это было важным условием: иначе тест «запустили» и забыли навсегда с двумя конфликтующими окнами.
На какие цифры смотрю в тесте
В кабинете по каждому варианту: показы, клики, заявки, CTR и доля заявок от показов.
Подсказка «кто лидирует» — сначала по заявкам, при равенстве по CTR. Это не p-value и не байесовский калькулятор. Для трафика малого бизнеса важнее не «статзначимость на 10 тысяч», а не оставить слабый оффер на месяцы, когда разница уже видна по заявкам.
Ошибка, которую видела у себя и у клиентов: останавливать тест на 30 показах, потому что «B впереди на 2%». Шум. Я для себя держу правило: не трогать, пока по каждому варианту не набралось осмысленное число заявок для ниши. На B2B-лендинге это может быть долго — тогда лучше сузить гипотезу, а не крутить спиннер.
Какие гипотезы тестировать имеет смысл
Бессмысленно A/B «синий фон vs зелёный», пока не закрыт оффер. Имеет смысл менять одно:
- Формулировка выгоды: срок vs цена vs «без обязательств».
- Сила CTA: «Оставить заявку» vs «Получить расчёт».
- Один буллит с доказательством: цифра со страницы vs снятие риска.
Плохая практика — одновременно новый заголовок, другая картинка и exit-intent вместо таймера. Потом непонятно, что сработало. ИИ как раз провоцирует «перегенерировать всё»; для теста я копирую попап и меняю одно поле.
Что ломалось
Два активных теста на одном домене. Посетитель мог попасть в логический тупик. Запретила на уровне API: один running-experiment на сайт.
Варианты с разных сайтов. Казалось бы, «ну почти тот же лендинг». Нет: разный трафик = бессмысленное сравнение. Оба попапа должны совпадать по нормализованному домену.
Забыли выключить проигравшего. Люди оставляли оба активными «на всякий случай». При завершении теста проигравший гасится автоматически — иначе снова два окна.
Ожидание, что A/B починит слабый продукт. Если на странице нет ответа «зачем мне оставлять телефон за 5 секунд», победит лишь менее раздражающий заголовок. Об этом писала в первой заметке
Что бы повторила
1. Варианты = полноценные сущности, не JSON-ветки внутри одной записи.
2. Sticky assignment на клиенте, конфиг — в том же embed.
3. Пересборка виджетов при старте и финише теста — без ручного «обновите код на сайте».
4. Метрики теста = обычные события продукта, без второй аналитики.
5. Одна гипотеза за раз — даже если генератор умеет написать пять текстов подряд.
A/B здесь не про «научный маркетинг ради науки». Про то, чтобы после генерации не спорить вкусом, а дать трафику один голос.
Если интересно — в следующий раз могу разобрать few-shot по нишам: почему два примера из той же отрасли бьют temperature, и как я храню примеры, чтобы модель не утаскивала чужие цифры в чужой попап.
А вы гоняете заголовки попапов в тесте или выбираете «на глаз»? Напишите в комментариях, сколько показов обычно ждёте перед решением — сравним подходы.
P.S. A/B — часть ИИ-conversion ; живой виджет можно посмотреть на glm-dev.ru. Пишу по опыту разработки, это не пресс-релиз.