Разбор

ИИ пишет объявления для Яндекс.Директ: 50 вариантов за 3 минуты

Копирайтер берёт 5–15 тыс. руб. и работает 2–3 дня. Claude API делает 50 вариантов за 3 минуты за 80–150 рублей с валидацией символов и проверкой запрещённых слов. Python-код, реальные примеры для «Ремонт квартир в Москве», разбор ограничений Директа.

• 7 мин чтения

Типичный кейс: директолог сдаёт проект клиенту — он уже сверстал кампании, собрал семантику, настроил аудитории. Осталось написать объявления. Он открывает таблицу, смотрит на 8 групп объявлений и 10 нужных вариантов на каждую — итого 80 текстов — и мысленно прощается с двумя днями своей жизни. Либо звонит копирайтеру и прощается с 10 000 рублями.

3 мин
столько занимает генерация 50 вариантов объявлений через Claude API вместо 2–3 дней ручной работы

Я не говорю, что ИИ заменит всё. Скажу точнее: для задачи «дать 10–20 вариантов на группу, чтобы было что тестировать» — ручная работа проигрывает вчистую.

Почему копирайтер берёт так дорого

5 000–15 000 рублей за пакет объявлений — это не жадность. Хороший специалист погружается в продукт, изучает конкурентов, формулирует УТП, пишет несколько версий, правит по фидбеку. На весь цикл уходит 2–3 дня. Это честная цена за честную работу.

Проблема в другом: большинство агентств и директологов не могут позволить себе такой процесс на каждый проект. Особенно когда надо сделать 8 кампаний, 6 групп в каждой и минимум 10 вариантов на группу. На выходе получается 3–5 вариантов «на отвали» — потому что больше просто не успеть.

ИИ здесь не делает работу лучше копирайтера. Он делает работу копирайтера быстрее и дешевле там, где нужен объём, а не шедевр. 50 вариантов за 3 минуты — это сырой материал для A/B теста. Среди них найдётся 5–7 рабочих формулировок, которые никто бы не придумал за два часа мозгового штурма.

Сравнение способов создания объявлений
Копирайтер (базовый)
2–3 дня / 10 000 ₽
Сам директолог
4–6 ч / бесплатно
ИИ + финальная правка
30 мин / 80–150 ₽
Оценка по реальному кейсу: кампания «Ремонт квартир в Москве», 5 групп объявлений, 10 вариантов на группу.

Правила Директа: что нужно знать перед генерацией

Прежде чем писать промпт — надо понять ограничения. Claude будет делать ровно то, что вы скажете. Если не объяснить ему лимиты, получите объявления которые не пройдут валидацию.

Актуальные технические ограничения для текстово-графических объявлений:

ПолеЛимитПримечание
Заголовок 156 символовОдно слово не более 22 знаков. Обязателен
Заголовок 230 символовПоказ не гарантирован — не вкладывай туда главное УТП
Текст объявления81 символ+ до 15 знаков препинания, одно слово до 23 знаков
Быстрая ссылка (заголовок)30 символовОписание быстрой ссылки — до 60 символов
Уточнение25 символовСуммарно — 132 знака на десктопе, 66 на мобайле

Есть ещё запрещённые конструкции: прямой призыв «нажми», слова-превосходства без подтверждения («лучший в России»), контактные данные в тексте. ИИ нужно предупреждать об этом явно — иначе он в 20–30% случаев вставит телефон в текст или напишет «лучшая цена в Москве» без оговорок.

Как устроен промпт: структура запроса

Весь трюк — в том как вы передаёте данные. Claude работает хорошо когда получает чёткую структуру:

  • Что за продукт и его сильные стороны
  • Кто целевая аудитория (конкретно, не «все»)
  • Список ключевых фраз для этой группы
  • Технические ограничения с точными цифрами
  • Что запрещено
  • Формат вывода (JSON — самый удобный)

Главный принцип: не объяснять что такое Директ — Claude это знает. Объяснять специфику вашего продукта и ограничения конкретной платформы прямо сейчас.

Код: генерация с валидацией

🐍 generate_ads.py — pip install anthropic
import anthropic
import json
import re

CLAUDE_API_KEY = "YOUR_CLAUDE_KEY"

# Запрещённые слова (сокращённый список для примера)
FORBIDDEN_WORDS = [
  "бесплатно", "гарантия 100%", "лучший в России",
  "нажмите", "кликайте", "номер телефона"
]

LIMITS = {
  "h1": 56,   # заголовок 1
  "h2": 30,   # заголовок 2
  "text": 81, # текст объявления
  "sitelink": 30,  # заголовок быстрой ссылки
  "callout": 25,   # уточнение
}

def validate_ad(ad: dict) -> tuple[bool, list[str]]:
  """Проверяем длину полей и запрещённые слова."""
  errors = []
  fields = {
      "h1":   ad.get("title1", ""),
      "h2":   ad.get("title2", ""),
      "text": ad.get("text", ""),
  }
  for field, limit in [("h1", LIMITS["h1"]), ("h2", LIMITS["h2"]), ("text", LIMITS["text"])]:
      val = fields[field]
      if len(val) > limit:
          errors.append(f"{field}: {len(val)} символов (лимит {limit})")

  full_text = " ".join(fields.values()).lower()
  for word in FORBIDDEN_WORDS:
      if word in full_text:
          errors.append(f"запрещённое слово: «{word}»")

  return len(errors) == 0, errors

def generate_ads(product: dict, keywords: list[str], count: int = 10) -> list[dict]:
  """Генерируем объявления для одной группы."""
  client = anthropic.Anthropic(api_key=CLAUDE_API_KEY)

  prompt = f"""Ты специалист по контекстной рекламе в Яндекс.Директ.
Напиши {count} вариантов объявления для группы.

ПРОДУКТ: {product['name']}
УТП: {'; '.join(product['usp'])}
АУДИТОРИЯ: {product['audience']}
КЛЮЧЕВЫЕ ФРАЗЫ ГРУППЫ: {', '.join(keywords)}

СТРОГИЕ ЛИМИТЫ (не превышать ни при каких условиях):
- title1: до 56 символов (считай перед ответом)
- title2: до 30 символов
- text: до 81 символа
- sitelinks: заголовок до 30 символов, 4 штуки
- callouts: до 25 символов каждое, 4 штуки

ЗАПРЕЩЕНО: прямой призыв "нажми/кликай", превосходства без доказательств ("лучший в России"),
контактные данные в тексте, слово "бесплатно" без реального обоснования.

Верни ТОЛЬКО валидный JSON-массив без пояснений:
[
{{
  "title1": "Ремонт квартир в Москве",
  "title2": "Сроки от 7 дней",
  "text": "Работаем без предоплаты. Гарантия 2 года. Выезд замерщика бесплатно.",
  "sitelinks": ["Цены", "Портфолио", "Акции", "О компании"],
  "callouts": ["Без предоплаты", "Гарантия 2 года", "Выезд за 2 часа", "Скидка 10%"]
}}
]"""

  message = client.messages.create(
      model="claude-sonnet-4-5",
      max_tokens=4096,
      messages=[{"role": "user", "content": prompt}]
  )

  raw = message.content[0].text.strip()
  # Извлекаем JSON даже если модель добавила пояснения
  match = re.search(r'\[.*\]', raw, re.DOTALL)
  if not match:
      raise ValueError("Модель не вернула JSON-массив")

  ads = json.loads(match.group())

  # Валидируем каждый вариант
  valid_ads = []
  for ad in ads:
      ok, errors = validate_ad(ad)
      if ok:
          valid_ads.append(ad)
      else:
          print(f"  Отбракован: {errors}")

  return valid_ads

# Пример: «Ремонт квартир в Москве»
product = {
  "name": "Ремонт квартир в Москве — компания СтройМастер",
  "usp": [
      "работаем без предоплаты",
      "гарантия 2 года на все виды работ",
      "выезд замерщика в день обращения",
      "фиксированная смета без скрытых доплат",
  ],
  "audience": "владельцы квартир в Москве, планирующие косметический или капитальный ремонт",
}

keywords_group1 = [
  "ремонт квартир москва",
  "ремонт квартир под ключ",
  "ремонт квартиры цена",
  "ремонт квартир недорого москва",
]

if __name__ == "__main__":
  print("Генерируем объявления...")
  ads = generate_ads(product, keywords_group1, count=10)
  print(f"\nВалидных объявлений: {len(ads)}/10")
  for i, ad in enumerate(ads, 1):
      print(f"\n#{i}")
      print(f"  Заголовок 1 ({len(ad['title1'])} симв): {ad['title1']}")
      print(f"  Заголовок 2 ({len(ad['title2'])} симв): {ad['title2']}")
      print(f"  Текст ({len(ad['text'])} симв): {ad['text']}")

Несколько деталей которые важны:

Формат re.search(r'\\[.*\\]', raw, re.DOTALL) — это защита от ситуации когда модель добавляет объяснение перед JSON. Без этого скрипт будет падать раз в 10–15 запусков.

Счётчик символов в Python считает unicode-символы, Директ считает так же. Кириллица занимает 1 символ, а не 2. Так что len("Ремонт квартир") вернёт то же самое что видит Директ.

Валидация стоит делать и в промпте (через явные инструкции), и в коде. Промпт справляется в 85–90% случаев. Код ловит остальное.

Реальный пример: 5 объявлений для «Ремонт квартир в Москве»

Вот что получается на выходе. Не лучшие из 50 — просто первые 5 из одного прогона.

#1
Ремонт квартир без предоплаты
Гарантия 2 года
Фиксированная смета, выезд замерщика сегодня. Работаем по Москве с 2014 года.
#2
Квартира под ключ от 7 дней
Без скрытых доплат
Смета фиксируется до начала работ. Замер и проект бесплатно. Звоните — приедем сегодня.
#3
Ремонт в Москве — гарантия 2 года
Выезд в день звонка
Косметический от 2 500 ₽/м², капитальный от 4 800 ₽/м². Предоплата 0 рублей.
#4
Ремонт квартиры: цена за м² с гарантией
Смета за 24 часа
Работаем строго по договору. Сдаём в срок или возвращаем деньги. Москва и область.
#5
Ремонт без предоплаты — Москва
Замерщик приедет сегодня
Фиксированная стоимость в договоре. 10 лет опыта. Более 500 сданных объектов.

Обратите внимание: все 5 вариантов разные. Первый бьёт по «без предоплаты», второй по скорости, третий даёт цены прямо в тексте, четвёртый апеллирует к договору и гарантии возврата, пятый — на опыт и цифры. Это и есть ценность — разные крюки для разных сегментов аудитории.

Ни один из них не идеален. Но среди 50 таких вариантов найдётся 5–7 которые стоит тестировать.

Квиз: сколько вы тратите на тексты объявлений

Быстрый расчёт

3 вопроса — посчитаем сколько уходит на тексты

Вопрос 1 из 3
Сколько новых кампаний вы запускаете в месяц?
Вопрос 2 из 3
Сколько групп объявлений в среднем в одной кампании?
Вопрос 3 из 3
Кто сейчас пишет тексты объявлений?

Как выбрать лучшие из 50 вариантов

Генерация — только первый шаг. 50 вариантов нельзя запустить все одновременно: Директ не показывает равномерно больше 3–5 объявлений на группу, остальные просто не получат трафика.

Вот рабочая схема отбора:

Шаг 1. Личная фильтрация. Пройтись по всем 50 вариантам и выбрать 7–10 которые кажутся сильными. Критерий — конкретика. «Ремонт без предоплаты, гарантия 2 года» лучше чем «Качественный ремонт по доступным ценам». Второе ничего не говорит.

Шаг 2. Запуск теста. 5–7 отобранных вариантов добавляем в группу с равномерным показом (настройка «Оптимизация показов» должна быть выключена на время теста). Ждём 100–200 кликов на каждое объявление.

Шаг 3. Анализ. Смотреть не только на CTR — он показывает насколько заголовок привлекает внимание. Смотреть на CR (отношение конверсий к кликам). Высокий CTR при низком CR = заголовок обещает одно, лендинг даёт другое. Это отдельная проблема.

Шаг 4. Итерация. Оставить 2–3 победителя. Написать ещё 10 вариантов по образцу лучшего. Повторить цикл через 3–4 недели.

До: написал сам за 3 часа
Заголовок 1
Ремонт квартир в Москве
Заголовок 2
Качественно и быстро
Текст
Профессиональный ремонт квартир под ключ. Работаем по всей Москве. Звоните!
Вариантов на группу
3 варианта (устал)
После: ИИ + 20 мин правки
Заголовок 1
Ремонт без предоплаты — Москва
Заголовок 2
Гарантия 2 года
Текст
Фиксированная смета, выезд замерщика сегодня. 500+ объектов сдано.
Вариантов на группу
10 вариантов за 3 минуты

Чего ИИ не умеет

Честно о границах, потому что их недооценивают.

Региональный сленг. В Москве «ремонт» — нейтральное слово. В Екатеринбурге есть свои локальные маркеры доверия. Объявление для Краснодара с упором на «московский стандарт» может оттолкнуть, а не привлечь. ИИ пишет нейтрально — хорошо для большинства случаев, но не для нишевых рынков с сильной местной идентичностью.

Скрытые УТП. Если вы знаете что у вашего клиента — единственный в городе станок для конкретного вида работ, или что их прораб — бывший технадзор — это надо вам сказать модели явно. ИИ не знает вашего бизнеса, он работает только с тем что вы передали.

Эмоциональный резонанс. Формула «без предоплаты + гарантия 2 года + смета фиксирована» — рациональная. Она работает. Но объявление которое цепляет потому что угадывает конкретный страх или желание конкретного человека — это пока сильнее у хорошего копирайтера который знает аудиторию изнутри.

A/B финальный выбор. ИИ создаёт варианты, но решение что тестировать — ваше. Он не знает что работало в прошлых кампаниях, не видит конкурентов в реальном времени, не чувствует сезонность в вашей нише.

Поэтому схема такая: ИИ делает 80% работы (объём, скорость, разнообразие), человек делает 20% (отбор, контекстная правка, итерация по результатам). Это честнее чем «ИИ заменяет копирайтера».


3 минуты на генерацию — это не про скорость. Это про то что вместо одного пакета объявлений из 3 вариантов «на отвали» у вас теперь 50 вариантов из которых можно выбрать. Одно из этих 50 окажется в два раза лучше остальных по CTR. Вы бы до него никогда не додумались за три часа мозгового штурма — просто потому что мозг устаёт и начинает повторяться. А Claude не устаёт.

Похожие кейсы

Источники

Источники

Часто задаваемые вопросы

Сколько символов в заголовке 1 в Яндекс.Директ?
Заголовок 1 (основной) — 56 символов, одно слово не более 22 знаков. Заголовок 2 (дополнительный) — 30 символов, показ не гарантирован. Текст объявления — 81 символ и до 15 знаков препинания. Это ограничения на 2025–2026 год по официальной документации Директа.
Сколько стоит сгенерировать 50 объявлений через Claude API?
80–150 рублей за одну генерацию на claude-sonnet-4-5. Точная стоимость зависит от длины промпта и объёма входных данных о продукте. Для сравнения: копирайтер за один пакет объявлений (4–5 групп, 10 вариантов) берёт от 5 000 до 15 000 рублей.
Как ИИ проверяет запрещённые слова в объявлениях Директа?
В промпт передаётся список запрещённых слов и конструкций. Дополнительно Python-скрипт проверяет длину каждого поля после генерации. Если вариант нарушает ограничение — он помечается как invalid и не попадает в финальный список. Итоговый JSON содержит только валидные объявления.
Что не умеет ИИ при написании объявлений?
ИИ плохо чувствует региональный сленг и местные реалии — объявление «Ремонт в Москве» будет нейтральным, без местного колорита. Он не знает скрытых УТП которые только вы знаете о своём продукте. Эмоциональный резонанс — то что цепляет сердце конкретного человека — пока сильнее у опытного копирайтера. ИИ даёт объём и скорость, человек добавляет точность.
Как выбрать лучшие объявления из 50 вариантов?
Запустить 5–7 лучших вариантов в A/B тест в одной группе объявлений с равномерным показом. Через 100–200 кликов сравнивать CTR и CR. Через 2–3 недели оставить 2–3 победителя, написать ещё 10 вариантов по образцу лучшего — и повторить цикл. Один сильный заголовок + слабый текст хуже среднего заголовка + сильного текста.
Нужно ли программирование для автоматизации написания объявлений?
Базовый Python достаточно. Установить anthropic через pip, вставить API-ключ, запустить скрипт. Вся логика генерации — в промпте, который можно менять под любую нишу. Готовый JSON с объявлениями можно загрузить в Директ через Direct Commander или вручную.
Обсуждение

    Пока без комментариев. Будьте первым.

    Войдите, чтобы отправить комментарий

    Вы сможете комментировать статьи, сохранять материалы

    или войдите по email

    Бесплатная диагностика · 30 минут · без обязательств

    Маркетинг работает, но продажи не растут?

    Отвечу на 3–5 вопросов о вашем бизнесе — и мы вместе разберём, где именно теряются клиенты и что с этим делать.

    Без продаж. Без навязчивых звонков.