Темы писем с ИИ обсуждают чаще всего там, где спорят об open rate. При включённой защите почты Apple письмо может загружать удалённый контент в фоне при получении, а не в момент просмотра Protect email privacy in Mail on Mac. Значит, загрузка пикселя — событие доставки контента, а не подтверждённое чтение. Ниже — как готовить варианты темы и оценивать наблюдаемые отправки, не превращая счётчик открытий в доказательство интереса.
Сразу оговорюсь о статусе материала. Учебный пример ниже полностью вымышлен: это не клиентский кейс и не выполненный тест нейросети или почтового сервиса. Генерация тем через ИИ описана как приём, а не как проверенный результат. Все числа получены из приведённого журнала на 12 строк, и ни одно из них не подтверждает превосходство одной темы над другой.
Уточните, что измерено
Open rate считают по загрузке пикселя. Apple описывает, что при включённой защите удалённый контент загружается в фоне при получении сообщения Protect email privacy in Mail on Mac. Для метрики это означает: пиксель мог сработать без того, чтобы человек открыл и прочитал письмо.
Из этого не следует, что защита включена у всех получателей или что каждый пиксель всегда загружается. Описание Apple говорит об одном режиме работы, а не о доле аудитории. Поэтому в журнале ниже открытие называется raw-open — загрузка пикселя, и не приравнивается к чтению.
Разведите четыре разных события: raw-open (загрузка пикселя), подтверждённое чтение (его в наборе нет), уникальный клик по ссылке и целевое действие вроде заявки или покупки. Клик ближе к интересу, чем загрузка картинки, но и он не гарантирует человека. Считать клики к открытиям нельзя: у них разные знаменатели и разные смыслы.
Передайте полный журнал и правило темы
Журнал состоит из двух отправок по 6 получателей. Это учебные строки с вымышленными ID, без реальных адресов и URL.
| id | send_id | delivery | raw_open | click_events | known_machine_click | window_mature |
|---|---|---|---|---|---|---|
| A1 | A | delivered | true | 2 | false | true |
| A2 | A | delivered | true | 1 | true | true |
| A3 | A | delivered | true | 1 | false | true |
| A4 | A | delivered | true | 0 | false | true |
| A5 | A | bounced | false | 0 | false | true |
| A6 | A | unknown | false | 0 | false | true |
| B1 | B | delivered | true | 1 | false | true |
| B2 | B | delivered | true | 0 | false | true |
| B3 | B | delivered | false | 0 | false | true |
| B4 | B | delivered | false | 0 | false | true |
| B5 | B | bounced | false | 0 | false | true |
| B6 | B | unknown | false | 0 | false | true |
Правила чтения журнала:
- Доли считать только среди delivery=delivered. Bounced и unknown показывать отдельно, unknown не означает ни подтверждённую доставку, ни подтверждённый отказ.
- raw-open — событие загрузки пикселя, а не подтверждённое чтение.
- raw_unique_clicks — получатели со статусом delivered и click_events > 0. adjusted_unique_clicks дополнительно исключает строки с known_machine_click=true. Отсутствие такой метки не доказывает, что клик человеческий.
- Не делить клики на открытия. При нулевом знаменателе результат — null, а не 0%.
- Без случайного назначения и заранее согласованного плана не объявлять тему причинным победителем.
- Темы создавать только по бизнес-факту. Данных о заявках и продажах нет, conversion_rate = null.
Бизнес-факт для обеих тем: «В отчёт добавлена колонка «Источник». Иные свойства, польза, сроки и цены неизвестны.» Исходные темы: A — «В отчёте появилась колонка «Источник»»; B — «Новая колонка отчёта: «Источник»».
Условия отправок: A ушла 2026-10-01 в 09:00 +03:00 по списку A, B — 2026-10-08 в 09:00 +03:00 по другому списку B. Рандомизации нет. Тело, CTA и определение событий в учебном условии одинаковые, но разные списки и даты причинную сопоставимость не обеспечивают. Окно — первые 24 часа после delivery_at, строки уже собраны на зрелом окне. Каждый id — отдельный получатель в данной отправке; повторные click_events число получателей не увеличивают.
Скопируйте запрос
Промпт ниже самодостаточен: в нём есть задача, данные, правила, нулевой контроль и схема ответа. Его можно передать модели вместе с журналом, но ничего не отправляйте и не запускайте рассылку по результату.
Задача: по всем переданным inputs создай 2 новых кандидата тем без новых фактов, затем по rows посчитай A/B по rules: sent/delivered/bounced/unknown, raw_open, raw_unique_clicks, известные исключения, adjusted_click_rate. Верни основания исключений с ID и причинный decision. human_read_count / human_click_count / conversion_rate = null. Отдельно рассмотри контроль с нулём доставок. Ничего не отправляй.
Данные:
fictional: true
business_fact: "В отчёт добавлена колонка «Источник». Иные свойства, польза, сроки и цены неизвестны."
sent_subjects:
A: "В отчёте появилась колонка «Источник»"
B: "Новая колонка отчёта: «Источник»"
sends:
A: {at: "2026-10-01T09:00:00+03:00", cohort: "Список A"}
B: {at: "2026-10-08T09:00:00+03:00", cohort: "Другой список B"}
randomization: false
same_body: "Учебное условие: одинаковое тело, CTA и определение событий. Списки и даты разные, причинная сопоставимость не установлена."
window: "Первые 24 часа после delivery_at, строки уже собраны на полном зрелом окне. Каждый id — отдельный получатель в данной отправке; повторные click_events не увеличивают число получателей."
rows:
- {id: "A1", send_id: "A", delivery: "delivered", raw_open: true, click_events: 2, known_machine_click: false, window_mature: true}
- {id: "A2", send_id: "A", delivery: "delivered", raw_open: true, click_events: 1, known_machine_click: true, window_mature: true}
- {id: "A3", send_id: "A", delivery: "delivered", raw_open: true, click_events: 1, known_machine_click: false, window_mature: true}
- {id: "A4", send_id: "A", delivery: "delivered", raw_open: true, click_events: 0, known_machine_click: false, window_mature: true}
- {id: "A5", send_id: "A", delivery: "bounced", raw_open: false, click_events: 0, known_machine_click: false, window_mature: true}
- {id: "A6", send_id: "A", delivery: "unknown", raw_open: false, click_events: 0, known_machine_click: false, window_mature: true}
- {id: "B1", send_id: "B", delivery: "delivered", raw_open: true, click_events: 1, known_machine_click: false, window_mature: true}
- {id: "B2", send_id: "B", delivery: "delivered", raw_open: true, click_events: 0, known_machine_click: false, window_mature: true}
- {id: "B3", send_id: "B", delivery: "delivered", raw_open: false, click_events: 0, known_machine_click: false, window_mature: true}
- {id: "B4", send_id: "B", delivery: "delivered", raw_open: false, click_events: 0, known_machine_click: false, window_mature: true}
- {id: "B5", send_id: "B", delivery: "bounced", raw_open: false, click_events: 0, known_machine_click: false, window_mature: true}
- {id: "B6", send_id: "B", delivery: "unknown", raw_open: false, click_events: 0, known_machine_click: false, window_mature: true}
Правила:
1. Доли считать только среди delivery=delivered; bounced и unknown показывать отдельно. unknown не означает подтверждённую доставку или подтверждённый недоставленный статус.
2. raw-open — событие загрузки пикселя, не подтверждённое чтение.
3. raw_unique_clicks — delivered с click_events>0; adjusted_unique_clicks дополнительно исключает known_machine_click=true. Отсутствие такой метки не доказывает человека.
4. Не делить клики на open. Нулевой знаменатель даёт null. Без случайного назначения и согласованного плана не объявлять причинного победителя тем.
5. Создать 2 новых кандидата тем только по business_fact. Не обещать эффект и не выполнять отправку.
6. Данных о заявках и продажах нет; conversion_rate = null.
Нулевой контроль: sent 1, delivered 0, clicks 0.
Схема ответа: JSON с полями new_subject_candidates, A, B, excluded_ids, decision, unknowns, zero_denominator_control. Все расчётные поля и знаменатели указывать явно.
Эталон ответа для сверки. Новые кандидаты: «Колонка «Источник» теперь в отчёте» и «В отчёте — новая колонка «Источник»». Обе опираются только на бизнес-факт и не добавляют выгод, сроков или цен.
A: sent 6, delivered 4, bounced 1, delivery_unknown 1, raw_opens 4, raw_open_rate 1.0, raw_unique_clicks 3, known_machine_excluded 1, adjusted_unique_clicks 2, adjusted_click_rate 0.5.
B: sent 6, delivered 4, bounced 1, delivery_unknown 1, raw_opens 2, raw_open_rate 0.5, raw_unique_clicks 1, known_machine_excluded 0, adjusted_unique_clicks 1, adjusted_click_rate 0.25.
Decision: описательно у A больше зарегистрированных кликов после заданного исключения, но причинный победитель темы неизвестен — разные даты и списки, рандомизации нет. human_read_count, human_click_count и conversion_rate — null. Нулевой контроль: sent 1, delivered 0, clicks 0, click_rate null, долю не рассчитывать.
Сверка расчёта руками: 12 строк — это 2×6, в каждой отправке 4 delivered, 1 bounced и 1 unknown. У A пиксель загрузился у A1, A2, A3 и A4 — 4 из 4 доставленных. Кликали A1, A2 и A3, то есть 3 уникальных получателя. A1 кликнул дважды, но это по-прежнему один получатель. A2 несёт известную машинную метку и выбывает, остаются 2 из 4. У B пиксель загрузился у B1 и B2 — 2 из 4, кликал один B1, машинных меток нет, итог 1 из 4.
Сверьте знаменатель и все клики
Начните с доставки. Доля считается только от delivered, поэтому у A и B знаменатель 4, а не 6. Один bounced и один unknown в каждой отправке остаются в отчёте отдельной строкой и в знаменатель не попадают. Если unknown записать в доставленные, изменится сам знаменатель выбранной доли; если приписать ему неподтверждённый отказ, пострадают счётчики статусов, но сами доли от этого не обязательно изменятся. Unknown остаётся unknown.
Дальше разберите клики по получателям, а не по событиям. A1 с двумя click_events даёт одного уникального кликнувшего. Сложение событий завысило бы число людей, поэтому в журнале и в расчёте считают уникальные ID. Для A выходит 3 уникальных кликнувших на 4 доставки.
Теперь исключите известный машинный клик. A2 имеет known_machine_click=true, и это единственная строка, которую правило убирает: 3 − 1 = 2 уникальных получателя из 4, то есть 0.5. У B исключать нечего: 1 из 4, то есть 0.25. A1 в исключения не попадает, его второй клик просто не добавляет нового получателя.
Открытия покажите рядом с кликами и не смешивайте. У A raw_open_rate 4/4 = 1.0, у B 2/4 = 0.5. Это загрузки пикселя, а не прочтения. Конверсии неизвестны: в журнале нет ни заявок, ни оплат, поэтому conversion_rate = null.
Отдельно проверьте нулевой знаменатель. Если отправлено одно письмо, доставленных ноль и кликов ноль, доля не равна 0% — она не определена, click_rate = null. Такой набор отбрасывают для любых выводов, а не заносят как нулевой результат.
Негативный контроль: утверждение «A выиграла: 100% людей прочитали письмо, каждый клик настоящий» отклоняется. Raw-open не равно чтению, у A есть известный машинный клик, отсутствие метки не подтверждает человека, а отправки неслучайные.
Не объявляйте победителя по несопоставимым отправкам
Сравнение двух отправок не позволяет назвать лучшую тему, когда различаются даты и списки, а случайного назначения не было. Описательно у A больше уникальных кликов после исключения, но разница может объясняться составом аудитории, днём отправки или случайностью набора из нескольких строк. Причинной связи между текстом темы и кликами этот журнал не устанавливает.
Есть и содержательная граница. Отсутствие метки known_machine_click не доказывает, что клик человеческий, а машинная метка в наборе — учебное условие, а не обещание, что фильтр почтового сервиса ловит роботов полностью. Поэтому human_click_count остаётся null: число кликов, которые точно сделали люди, из этих строк не выводится.
Размер набора тоже ограничивает вывод. 12 строк хватает, чтобы показать арифметику, дедупликацию и неизвестные поля, но не чтобы говорить о статистической значимости или устойчивости доли.
Если понадобится настоящий тест тем, нужен отдельный план: случайное назначение получателей по вариантам, одинаковые условия отправки, заранее зафиксированное окно, определение целевого события и правило остановки. Здесь такой план не составляется, размер выборки не рассчитывается и победитель не объявляется.
Практический порядок для ваших будущих отправок: зафиксируйте бизнес-факт и создайте 2–3 темы без обещаний, которых нет в факте; соберите журнал получателей со статусами доставки и окном; дедуплицируйте клики по получателям; отделите известные машинные строки и покажите их отдельно; считайте доли только от доставленных и оставляйте null там, где знаменатель неизвестен или нулевой. В документации GigaChat сказано, что при составлении запроса на письмо нужно указать, кому оно адресовано и о чём должно говориться Генерация текста с помощью ГигаЧат. Это рекомендация, а не обязательное требование провайдера и не проверенный тест модели. Как устроена генерация текстов письма, разобрано в материале Email-рассылка с нейросетью. Как свести такие журналы в общий отчёт без потери знаменателей — в разборе Анализ маркетинговых данных с нейросетью.

