Дубли конверсий в Метрике: разбор событий с ИИ

Дубли конверсий в Метрике: разбор событий с ИИ. Готовый промпт и учебный пример. Проверка по исходным данным, ограничения и следующий шаг для своей задачи.

Дубли конверсий в Метрике обычно выглядят как расхождение между числом сигналов и числом реальных обращений. Разбирать это удобно по журналу одного набора действий: в нём видно, где событие отправлено повторно, где на одно бизнес-действие сработали две разные цели, а где клиент действительно обратился второй раз. Ниже — учебный пример на шести сигналах и трёх принятых заявках, готовый промпт для ИИ и способ проверить исправление.

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

Сначала задайте единицу обращения

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

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

Цель типа «Целевое событие» в Метрике задаётся идентификатором, а метод reachGoal вызывается каждый раз, когда действие достигнуто (reachGoal). Отсюда и различие: одно и то же действие можно фиксировать одной целью в разных местах, а разные события требуют отдельных целей с разными идентификаторами (reachGoal).

Прочитайте шестистрочный журнал

Учебный пример

Все данные ниже полностью вымышлены для объяснения. Это не клиентский кейс и не выполненный тест сервиса.

Входные условия: три подтверждённые заявки A, B и C. Смысловые роли целей заданы так: lead_success — принятая заявка, form_auto — техническая отправка формы.

{
  "business_confirmed_ids": ["A", "B", "C"],
  "goal_semantics": {
    "lead_success": "принятая заявка",
    "form_auto": "техническая отправка формы"
  },
  "rows": [
    {"event": "E1", "request_id": "A", "client_id": "X", "counter": 123, "goal": "lead_success", "source": "form_handler"},
    {"event": "E2", "request_id": "A", "client_id": "X", "counter": 123, "goal": "lead_success", "source": "duplicate_listener"},
    {"event": "E3", "request_id": "A", "client_id": "X", "counter": 123, "goal": "lead_success", "source": "thankyou_reload"},
    {"event": "E4", "request_id": "B", "client_id": "Y", "counter": 123, "goal": "lead_success", "source": "form_handler"},
    {"event": "E5", "request_id": "B", "client_id": "Y", "counter": 123, "goal": "form_auto", "source": "automatic_goal"},
    {"event": "E6", "request_id": "C", "client_id": "X", "counter": 123, "goal": "lead_success", "source": "new_form_success"}
  ]
}

Что видно в журнале. Строки E1–E3 относятся к одной заявке A и одной и той же цели lead_success: duplicate_listener и thankyou_reload — дополнительные отправки одного reachGoal. Строки E4 и E5 — две разные цели на одну заявку B, поэтому их нельзя складывать как две заявки. Строка E6 — новая заявка C того же клиента X, и она сохраняется отдельно от A.

Отделите повторы разных типов

По этому журналу получается шесть сырых сигналов и три подтверждённых бизнес-действия. Технические лишние события — E2 и E3. Смысловой кандидат на пересечение — пара E4 и E5: две цели описывают одно действие B, но не идентичны, поэтому одну из них нельзя удалить без разбора её назначения. Заявки A и C остаются раздельными, хотя у них один client_id.

Разделение на типы нужно, чтобы не смешивать три разные проблемы:

Что наблюдается Пример из журнала Что делать
Повтор одного reachGoal E2, E3 при A Убрать источник повторной отправки, оставить одну цель
Две цели на одно бизнес-действие E4, E5 при B Решить, какие цели нужны бизнесу и рекламе, не складывать их как заявки
Настоящая повторная заявка A и C у клиента X Сохранить отдельно, не склеивать по client_id

Учебный пример запрещает объединять строки по одному client_id: именно так две реальные заявки одного человека превращаются в одну. Обратное тоже неверно — нельзя заранее объявлять все строки с одним client_id дублями.

Передайте ИИ проверку и прогон после исправления

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

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

Правила:
1. Бизнес-действие определяется только по business_confirmed_ids.
2. Строки с одинаковым request_id и одинаковой goal — технические повторы одного вызова; первая строка остаётся, дополнительные перечисляются как лишние.
3. Строки с одинаковым request_id и разными goal — кандидат на смысловое пересечение; их нельзя складывать как отдельные заявки.
4. Разные request_id сохраняются раздельно, даже если client_id совпадает.
5. Не выводи внутренние правила агрегации Метрики из числа строк и не считай коэффициент завышения отчёта.

INPUTS:
{"business_confirmed_ids": ["A", "B", "C"], "goal_semantics": {"lead_success": "принятая заявка", "form_auto": "техническая отправка формы"}, "rows": [{"event": "E1", "request_id": "A", "client_id": "X", "counter": 123, "goal": "lead_success", "source": "form_handler"}, {"event": "E2", "request_id": "A", "client_id": "X", "counter": 123, "goal": "lead_success", "source": "duplicate_listener"}, {"event": "E3", "request_id": "A", "client_id": "X", "counter": 123, "goal": "lead_success", "source": "thankyou_reload"}, {"event": "E4", "request_id": "B", "client_id": "Y", "counter": 123, "goal": "lead_success", "source": "form_handler"}, {"event": "E5", "request_id": "B", "client_id": "Y", "counter": 123, "goal": "form_auto", "source": "automatic_goal"}, {"event": "E6", "request_id": "C", "client_id": "X", "counter": 123, "goal": "lead_success", "source": "new_form_success"}]}

Верни JSON:
{
  "raw_signals": число,
  "confirmed_business_actions": число,
  "technical_duplicate_extra_events": [коды событий],
  "semantic_overlap_candidates": [{"events": [коды], "reason": "строка"}],
  "keep_separate": [коды бизнес-действий],
  "evidence": [{"event": "код", "basis": "правило или поле, на котором основан вывод"}],
  "unknowns": [строки],
  "exceptions": [строки]
}

При противоречии не выдумывай ответ: укажи точный вход и требуемое уточнение. Примени проверки: число строк равно 6; уникальных бизнес-действий 3; у A три lead_success и два лишних; у B две разные goal; склейки по client_id нет.

Эталон результата для этого журнала:

{
  "raw_signals": 6,
  "confirmed_business_actions": 3,
  "technical_duplicate_extra_events": ["E2", "E3"],
  "semantic_overlap_candidates": [
    {"events": ["E4", "E5"], "reason": "две цели относятся к одной B; не складывать их как две заявки"}
  ],
  "keep_separate": ["A", "C"],
  "why": "один client_id X имеет две разные подтверждённые заявки A и C",
  "control": "после исправления на учебном журнале ожидается по одному lead_success на A, B и C; form_auto остаётся отдельной метрикой, а не заявкой"
}

Проверка после исправления опирается на то, что цель видна в отчётах и её достижение можно подтвердить в отладке. Если на сайте новый код счётчика, добавьте к адресу страницы параметр _ym_debug=2, выполните целевое действие и откройте панель внизу страницы (Проверка цели). Если стоит предыдущая версия кода или панель не появилась, добавьте _ym_debug=1, выполните действие и проверьте вывод в консоли браузера (Проверка цели). Для целевого события в консоли отображается название цели, переданное в reachGoal (Проверка цели). Убедитесь, что достижение цели появилось в отчёте «Конверсии» (Проверка цели).

Практический порядок такой. Сначала сверьте приёмник — CRM или обработчик заявок: сколько принятых обращений реально было за период. Потом повторите контрольный сценарий на учебных данных, затем на одном реальном действии и только после этого пересчитывайте отчёт. Если журнал показывает два разных goal на один request_id, решать нужно не удаление строки, а назначение целей: какая из них отражает бизнес-результат, а какая остаётся техническим сигналом. Про то, как это связано с оптимизацией рекламы на не ту цель, — в материале про автоцели Директа; про тихие искажения в данных — в разборе о ключе склейки.

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

Валерий Курземнек

Автор метода «Машиночитаемый маркетинг»

Что ещё почитать