Товарная кампания и смарт-баннеры Яндекс Директа не дают редактировать текст объявления в интерфейсе. Заголовок Директ берёт из тега <name> товарного фида, описание — из <description>, и оба тега писал сайт: под карточку товара, а не под рекламную ленту. В галерее видно около 35 знаков заголовка, жёсткий предел — 56, дальше Директ обрезает по символам. «Печеные яблоки, фаршированные медом и грецкими орехами» в объявлении выглядят как «Печеные яблоки, фаршированные медо».

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

Текст пригодится, если у вас уже крутятся товарная кампания или смарт-баннеры на YML-фиде и заголовки в них выглядят как строки из накладной. Если товарных форматов ещё нет — эта статья про инженерную часть, не про запуск с нуля.

Откуда в товарных форматах берётся текст

В обычной кампании РСЯ заголовок и текст пишет человек в интерфейсе. В товарной кампании и смарт-баннерах Директ собирает карточку сам: <name> → заголовок, <description> → текст, плюс цена, картинка и ссылка из своих тегов фида. Удобно ровно до того момента, когда читаешь получившиеся заголовки глазами покупателя в ленте.

Каталожное имя товара и рекламный заголовок делают разную работу. «Пирог с рубленной говядиной», «Сет мини-чебуреков из 12 шт», «Пирожок с капустой» — на сайте, рядом с фото и в своём разделе, это норма. В галерее, где заголовок несёт половину клика, такой текст проваливается. Описание из карточки — про начинку и тесто; в объявлении на этом месте нужнее ответ на вопрос, почему заказывать здесь, а не у соседа.

Плюс лимит, который ломает даже удачные названия: заголовок обрезается по 56 знакам, а в карточке галереи и вовсе читаются первые ~35. Длинные «вкусные» названия теряют хвост — ровно тот, где обычно стоит суть.

Вывод, из которого выросло всё остальное: текст товарного объявления живёт не в Директе и не в голове копирайтера, а в двух тегах фида. Кто управляет фидом — управляет объявлением.

Два очевидных хода, которые мы отбросили

Переименовать товары на сайте. Раз Директ читает из фида, а фид собирает сайт — казалось бы, поправить надо там. Отказались быстро: карточка ранжируется в поиске и участвует в чеке, рекламный заголовок останавливает взгляд в ленте за полторы секунды. Смешаешь эти две задачи в одном поле — испортишь обе. Плюс каждая правка на чужом проде — это тикет, релиз и регресс-риск ради текста объявления.

Собрать свой фид руками в таблице. Живёт до первого обновления ассортимента. Около пятисот позиций, цены и наличие меняются каждый день, новинки выходят под праздники. Через неделю такой фид врёт про цену и наличие, а это уже вопрос к модерации Директа и к доверию покупателя, который увидел одну цену в объявлении и другую на сайте.

Оставался третий вариант: оставить сайт как есть и надеть на его фид преобразователь.

Прослойка: один процесс на Node, без базы

Сервис получился намеренно скучным. Один процесс на нашем сервере, без базы данных: всё состояние — это последний собранный фид на диске. Раз в полчаса процесс скачивает YML сайта, сравнивает со снимком прошлой сборки и, если что-то поменялось, пересобирает свой фид. Директ забирает результат по отдельной ссылке — сайтовый фид он больше не видит.

Ключевое инженерное правило — хирургическая подмена. В каждом опубликованном <offer> заменяются ровно два тега: <name> и <description>. Всё остальное проходит байт-в-байт. Сервис сознательно не знает, какие ещё теги лежат в фиде: он их не парсит и не нормализует, а копирует как есть. Появится завтра в сайтовом фиде новый тег — он доедет до Директа нетронутым, без правок кода на нашей стороне. Меньше знаешь про чужую схему — меньше ломаешь при её изменении.

Два инварианта, на которых держится безопасность

Ещё до первой строки генератора мы зафиксировали два правила. Оба — про то, чтобы автоматика не наделала того, что потом придётся руками разгребать в кабинете.

Инвариант 1. Новинка не попадает в рекламу без человека. 17 августа в начале седьмого вечера на сайте появились два новых десерта. Сервис сгенерировал им заголовки, положил в статус «на проверке» и прислал редактору две карточки в телеграм-бот: фото, цена, наш заголовок, кнопки «Опубликовать / Скрыть». До утра десерты лежали вне публикуемого фида. Утром редактор нажал две кнопки. Автогенерация без ревью на живом рекламном кабинете — это способ однажды показать покупателю заголовок, который никто не читал.

Инвариант 2. Сбой на пути фида не снимает рекламу. Сайт отдал битый или пустой XML, не ответил вовремя, генератор промолчал — публикуемый фид не трогается, Директ получает последнюю рабочую версию. Только на третьем сбое подряд сервис пишет в бот. Почему это критично: пустой фид Директ трактует буквально — снимает объявления, а на возврате прогоняет их заново через модерацию и разгон. Один сетевой таймаут не должен стоить кампании перезапуска обучения. Fail-safe здесь дороже свежести: лучше показать вчерашний валидный заголовок, чем сегодняшнюю пустоту.

LLM в клетке валидатора

Заголовки пишет нейросеть, но не «свободным творчеством». Самое неудобное правило Директа оказалось и самым полезным каркасом: модерация сверяет текст объявления со страницей перехода. «Аппетитные» эпитеты нельзя выдумать — только взять из описания карточки; «Хит!» ставится, только если хитовость заявлена на сайте. Это превращает генерацию из «придумай красиво» в «перепиши в рамках того, что уже есть на странице».

Поэтому модель работает в жёсткой клетке правил, и на выходе стоит валидатор:

  • заголовок — до 56 знаков при цели 35 (чтобы пережить обрезку галереи);

  • описание — до 81 знака, законченной фразой;

  • без капса, эмодзи и стоп-слов вроде «акция», «скидка», «лучший» (частые причины отклонения на модерации);

  • ответ проходит через валидатор; брак — второй заход с явным объяснением, что именно забраковано.

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

Описание мы у товара забрали целиком. В объявлении оно отвечает не на «из чего сделано», а на «почему заказывать здесь»: вместо текста карточки идёт шаблон категории, который продаёт саму доставку и пекарню — собственное производство, традиционные рецепты, доставка по городу, у каждой категории со своим акцентом. Начинку и тесто покупатель дочитает уже в карточке, после клика.

Обучение на правках редактора без дообучения

Дальше мы сделали то, чего от генератора не дождёшься сам по себе. Владелец продаёт эту еду пятнадцать лет и знает, на какие слова откликается его покупатель, — поэтому интерфейс и строился под ручную правку прямо в строке товара, без выгрузок и таблиц. За первые дни он переписал руками 180 заголовков из пятисот.

И каждая правка не пропала. Она пишется в журнал в формате «было → стало», и до двенадцати последних правок по категории подмешиваются в промпт следующей генерации — вместе с инструкцией категории вроде «каждый заголовок здесь начинается со слова „Постный“». По сути это few-shot на живых примерах редактора: модель без дообучения подхватывает его стиль и формулировки. За один заход человек «обучил» генератор своему языку, и новые позиции выходят уже в нём. Дёшево, прозрачно (примеры видно глазами), и откатывается правкой журнала, а не переобучением.

Грабли Директа, которых нет в справке

Две вещи, на которых легко потерять день, если не знать заранее.

Ручное управление текстами в ЕПК. Для товарной группы нужно явно включить ручное управление текстами: заголовок из name, текст из description. В автоматическом режиме Директ берёт «текст по умолчанию» — и вся работа с фидом становится невидимой. Первую проверку «а почему в объявлениях не наши заголовки» проходишь именно здесь.

Директ перечитывает фид примерно раз в сутки, и форсировать переобход нельзя. Сервис держит свой фид свежим каждые полчаса, но эффект правки заголовка виден только назавтра. Привычное «утром поменял — вечером посмотрел» на фиде не работает; цикл проверки гипотез тут сутки, это надо закладывать в планирование.

Первые цифры (и почему это пока сигнал, а не статистика)

Товарную кампанию переключили с сайтового фида на свой 15 августа: тот же аккаунт, тот же тип кампании, окна по четыре дня подряд. Методологически сравниваем одинаковые сущности до/после, меняется только источник текста.

Кликабельность не сдвинулась — около 1,2–1,3% на обоих фидах. Это ожидаемо и, скорее, признак чистоты замера: в товарной галерее клик делают картинка и цена, а их мы не трогали. Если бы CTR прыгнул, я бы сначала искал ошибку в разметке эксперимента.

Изменилось поведение после клика:

  • доля переходов, дошедших до корзины, выросла с 0,8% до 2% — вдвое с лишним;

  • корзина обошлась примерно в два с половиной раза дешевле;

  • клик подешевел примерно на десятую часть;

  • отказы в Метрике опустились почти с половины визитов до чуть более двух из пяти.

Читаю это так. «Постные чебуреки со шпинатом, 3 шт» с описанием про собственную пекарню и доставку приводят человека, который уже понимает, куда идёт. «Чебуреки со шпинатом и зеленью 3 шт» с описанием из карточки про тесто и начинку приводили в среднем менее готового. Текст в фиде отработал не на клике, а на том, что происходит после него.

Смарт-баннеры на новом фиде за первые два дня дали покупку примерно втрое дешевле, чем основная кампания РСЯ за предыдущие две недели. Направление то же.

Честная оговорка про эти числа: окна короткие — четыре дня на товарную кампанию и два на смарты. Это сигнал, а не статистика: сезонность, день недели и разгон кампаний я тут не развёл, доверительных интервалов на таких окнах нет. Через месяц накопим данные и дополним — если тренд развернётся, напишу и об этом.

Где подход не работает

Границы честные, и их видно уже сейчас.

Аппрув каждой новинки требует редактора в тот же день. На пятистах позициях это минуты, на десятках тысяч SKU — уже нет: там нужна другая политика публикации (например, автопубликация внутри доверенных категорий с постфактум-ревью, а не блокирующий аппрув на каждую позицию). Мы этот случай пока не решали и выводов про него не делаю.

Прослойка не заменяет ведение кампаний. Фид живой, ассортимент живой, правила модерации меняются — сервис снимает ручную рутину с текста, но не думает за директолога. Генерация здесь экономит время редактора, а не заменяет его.

И это не универсальный «коннектор». Он написан под конкретную пару «этот сайтовый YML → этот кабинет»: две подменяемые сущности (name, description), шаблоны описаний под реальные категории магазина, стоп-слова под его модерацию. Перенос на другой проект — это не деплой, а новая настройка правил.

Если у вас похожая связка

Три проверки на вечер, если товарные кампании у вас уже крутятся:

  1. Прочитайте пять объявлений галереи глазами покупателя — понятно ли по первым ~35 знакам, что за товар и почему его брать.

  2. Проверьте, включено ли в ЕПК ручное управление текстами (иначе всё, что ниже, — впустую).

  3. Сравните отказы и глубину визита из товарной кампании с обычной РСЯ. Если после клика люди из товарной уходят быстрее — это почти наверняка проблема текста в фиде, и ставками она не лечится.

А как вы решаете текст в товарных фидах — генерите, правите руками, гоняете шаблоны категорий? И где ещё модерация Директа ломала вам автогенерацию заголовков? Любопытно сверить грабли — расскажите в комментариях.

Комментарии (0)