И у Google (AI Overviews), и у Яндекса генеративный ответ стоит над обычной выдачей. Человек ищет как раньше, но первое, что он видит — не десять ссылок, а готовую рекомендацию с двумя‑тремя брендами. Можно быть топ-1 по всем целевым запросам и не попасть в этот блок ни разу.

Дисциплина, которая с этим работает, называется GEO (Generative Engine Optimization). Статья про две вещи: что в ИИ‑ответе реально поддаётся измерению и как я собрал под это воркфлоу на n8n. Ссылка на GitHub в конце статьи.

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

Воркфлоу и пример отчёта
Воркфлоу и пример отчёта

Почему обычные позиции сюда не переносятся

Первое, что важно — запрос ≠ позиция.

Google в официальной документации по AI‑функциям описывает это прямым текстом: и AI Overviews, и AI Mode могут использовать технику query fan‑out — рассылать несколько связанных поисковых запросов по подтемам и источникам данных, чтобы сформировать ответ. Пока ответ генерируется, модели дополнительно ищут поддерживающие страницы, поэтому набор ссылок под ответом шире и разнообразнее, чем в классической выдаче. Там же оговорка: AI Overviews и AI Mode используют разные модели и техники, поэтому наборы ответов и ссылок у них отличаются.

Что из этого следует практически:

  • Ты ранжируешься по своей фразе, а движок ищет по своим. Топ-1 по точному запросу не гарантирует попадания в выборку по сгенерированной перефразировке.

  • В контекст уходит горстка документов, а не топ 10. Разница между 4-м и 9-м местом, за которую в классическом SEO бьются, здесь может не значить ничего: либо документ попал в контекст, либо нет.

  • Извлекаемость важнее ранга. В ответ идёт то, что цитируется одним предложением — характеристика, цифра, сравнение. Из «широкий ассортимент и низкие цены» цитировать нечего.

Что доказывает список источников, а что нет

Под ИИ‑ответом почти всегда висит список ссылок. Соблазн — прочитать его как расшифровку: раз ссылки есть, значит каждое утверждение взято оттуда.

Это разные вещи, и лучше всего это видно в документации Яндекса. Yandex Search API отдельно описывает три состояния ответа:

  • ничего не нашлось;

  • документы‑источники нашлись, но извлечь из них информацию не получилось;

  • нашлось и извлеклось, но в качестве ответа уверенности нет — тогда ответ предваряется предупреждением.

Второе состояние — ровно тот случай: источники есть, а ответ на них не опирается. Это не догадка, это задокументированное поведение сервиса.

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

  • Из выдачи (retrieval). Движок нашёл документы, извлёк оттуда названия, сослался.

  • Из памяти модели. Название дописано из того, что модель усвоила на обучении, а в блоке источников — то, что вернул поиск по теме в целом.

От этого зависит, есть ли у тебя рычаг вообще. Retrieval — быстрый: попасть в индекс, попасть в выборку, дать извлекаемый факт; горизонт на недели. Память модели — слепок веба на момент обучения; точечно повлиять нельзя, горизонт — годы, недавние правки на сайте на эту цифру не подействуют.

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

Круговая диаграмма: доля доменов-источников за прогон — какие сайты движки реально использовали, отсортированные по числу использований
Круговая диаграмма: доля доменов‑источников за прогон — какие сайты движки реально использовали, отсортированные по числу использований

Видно, что сверху не магазины, а профильные медиа и агрегаторы — и что один и тот же домен часто используют сразу несколько движков. Значит, попадание в такой обзор работает не на один движок, а на все разом.


Метрики

Позиций нет, поэтому набор другой:

Метрика

Что показывает

Mention rate

доля запросов, где назвали бренд по имени

Citation rate

доля запросов, где сослались на сайт как на источник

Разрыв между ними

каким путём мы попадаем в ответ: из выдачи или из памяти

Source share

какие домены движок подтягивает по теме — карта, куда нести контент

Разрыв между первыми двумя — самое полезное, что тут есть. Высокий mention при нулевом citation = помнят, но не находят. Обратное = находят, но не считают достаточно авторитетным, чтобы назвать. Лечится по‑разному.

Что именно я меряю: честная методология

Четыре модели в мониторинге — это два разных класса систем, и это надо проговорить, иначе выводы будут неверными.

Яндекс GenSearch — синхронный запрос к Yandex Search API с генеративным ответом: нейросеть Яндекса разбирает результаты поиска по индексу Яндекса. Близко к тому, что видит пользователь в выдаче, но формально это отдельный API‑продукт, а не тот же блок из SERP.

GPT / Gemini / Qwen — через OpenRouter, и поиск им делает не их собственный браузер, а один общий поисковик (Exa). Я задаю его принудительно.

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

Плата за это — я меряю не ChatGPT как продукт, а модель с подставленным поиском. Сравнивать модели между собой так можно, предсказать конкретный ответ ChatGPT — нет.


Воркфлоу: 43 ноды

Один из трёх воркфлоу связки. Все три сидят на одной Google‑таблице как на стейт‑сторе — 17 вкладок, от Daily_Log до AI_Visibility_History. Конфиг переиспользуется: Master_Briefs (какая категория за какой запрос отвечает) и Daily_Monitor (URL, H1, Title) заполняются один раз на всех. GEO‑мониторинг не заводит собственный список категорий, а берёт те же primary_query, по которым считается обычная SEO‑отчётность. Практический эффект: добавил категорию в общий конфиг — она сама попала и в ежедневный аудит, и в помесячный отчёт, и сюда. Заводить её в трёх местах не нужно, и цифры разных отчётов не расползаются.

                     [ ВХОД: ЕДИНЫЙ КОНФИГ ]
             Google Sheets (заполняется 1 раз)
             ┌────────────────────────────────┐
             │ • Master_Briefs (категория/запрос)
             │ • Daily_Monitor (URL, H1, Title)
             └───────────────┬────────────────┘
                             │
     ┌───────────────────────┼───────────────────────┐
     │ primary_query         │ primary_query         │ primary_query
     ▼                       ▼                       ▼
┌───────────────────┐  ┌───────────────────┐  ┌───────────────────────┐
│ 1. Daily & Weekly │  │ 2. Monthly Report │  │ 3. GEO AI Visibility  │
│    (Тех. аудит)   │  │  (+ Антиканнибал) │  │    (43 ноды)          │
├───────────────────┤  ├───────────────────┤  ├───────────────────────┤
│ • Статусы 200/404 │  │ • Δ к прошлому    │  │ • Опрос 4 движков     │
│ • Срез H1/Title   │  │   периоду и году  │  │   (Yandex, GPT,       │
│ • Индексация      │  │ • Risk score      │  │    Gemini, Qwen)      │
│ • Uptime          │  │   каннибализации  │  │ • Regex-детект        │
└─────────┬─────────┘  └─────────┬─────────┘  └───────────┬───────────┘
          │                      │                        │
          │ Запись логов         │ Запись метрик          │ Запись срезов
          ▼                      ▼                        ▼
┌─────────────────────────────────────────────────────────────────────┐
│                 ОБЩИЙ СТЕЙТ-СТОР (17 вкладок таблицы)               │
├────────────────────────┬─────────────────────┬──────────────────────┤
│ • Daily_Log            │ • Monthly_Snapshots │ • AI_Visibility_State│
│ • Audit_History        │ • Cannibal_Matrix   │ • AI_Visibility_Hist │
└────────────────────────┴─────────────────────┴──────────────────────┘

Запуск — 10-го числа месяца или вручную.

Пошаговый разбор нод воркфлоу

Вход. Config (домен, лимиты токенов, тариф) → параллельно читаются Master_Briefs и Daily_MonitorRead AI_Visibility_State подтягивает прошлый снепшот под будущую Δ.

Сборка задач. Build AI Visibility Queries разворачивает категории в плоский список задач. Жёсткий потолок — 20 категорий за прогон: страховка от того, что кривой фильтр запустит платный прогон на всю таблицу.

Фетч — четыре независимые ветки. Prepare X TasksHTTP RequestNormalize X на каждый движок. Ветки развязаны: падение Gemini не блокирует остальные три. У Яндекса тут отдельное ограничение — по умолчанию не больше одного синхронного генеративного запроса в секунду, это учтено в темпе отправки.

Хранение — два слоя, и это принципиально.

  • AI_Visibility_State — upsert по ключу «категория + движок». Актуальный срез, база для сравнения.

  • AI_Visibility_History — append‑only, никогда не перезаписывается. Строка на каждый (прогон × движок × категорию).

State отвечает на «как сейчас?», History — на «это тренд или шум?». Разовое отклонение при temperature: 0 почти наверняка шум, три прогона подряд — сигнал. Без второго слоя отличить одно от другого нельзя в принципе.

Репортинг. Collect AI Results сливает четыре ветки в один массив и считает state_hash — короткий отпечаток ответа (FNV-1a), чтобы отличать «не изменилось» от «поменялось», не сравнивая простыни текста посимвольно:

Код: быстрый FNV-1a хэш для фиксации изменени
let h = 2166136261;
for (const ch of String(s)) { h ^= ch.charCodeAt(0); h = Math.imul(h, 16777619); }
return (h >>> 0).toString(16);

Хэшируется склейка «упомянут бренд + процитирован сайт + найденные модели + текст ответа». Меняется хоть один символ — меняется весь отпечаток. Дальше веером: текстовая сводка в Telegram, три графика (матрица «категория × движок», доли упоминаний по движкам, круговая по доменам‑источникам) и HTML со всеми сырыми ответами — параллельно в Telegram и в архив на Google Drive.

Архив сырых ответов — не роскошь. Метрику можно пересчитать задним числом, если поменяется гипотеза. А сам ответ модели, если его не сохранить, не воспроизведётся уже никогда.

Детект без второй LLM

Напрашивается скормить ответ ещё одной модели: «оцени, упомянут ли бренд». Плохая идея — удваивается стоимость, и одна недетерминированная штука начинает оценивать другую. Правила проще:

Код ноды детекта: регулярки и проверка флагов веб‑поиска
const brandMentioned = /\bbrandname\b/i.test(text);

const siteCited =
  urls.some(u => u.toLowerCase().includes(domain)) ||
  new RegExp(domain.replace('.', '\\.'), 'i').test(text);

Дальше интереснее — отделить «поиск дал результат» от «поиск формально был».

Нашли» ≠ «сослались. Яндекс возвращает список источников и отдельно помечает те, что реально пошли в ответ. Считать citation по всем кандидатам — обманывать себя:»

// не все sources, а только реально использованные
const usedSourceUrls = sources.filter(s => s?.used === true).map(s => s.url);

Ответ пришёл, это ещё не значит, что модель искала. Я требую от неё сделать поиск, но требование не гарантия: модель может ответить и без него, из того, что помнит. Снаружи не отличишь — текст выглядит одинаково.

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

const webRequests = Number(usage?.server_tool_use_details?.web_search_requests || 0);
const webEvidence = annUrls.length > 0 || webRequests > 0;
const diag = !webEvidence ? 'no_web_evidence' : '';

На оценку он не влияет, но отвечает на главный вопрос: есть ли у меня быстрый рычаг на этот движок или нет.


Стоимость

Все цифры из официальных тарифов.

Яндекс. Прайс Yandex Search API: синхронный запрос с генеративным ответом — 5 080 ₽ за 1 000 запросов с НДС, то есть 5,08 ₽ за запрос. Плата за факт запроса, длина ответа не влияет. Полезная деталь: запросы, упавшие с внутренней ошибкой сервера или ошибкой авторизации, не тарифицируются поэтому в отчёте считаются только успешные вызовы.

OpenRouter. Здесь стоимость складывается из двух частей: сам поиск Exa — $0,007 за запрос в режиме auto (до 10 результатов) плюс токены LLM, включая токены подставленных в промпт результатов поиска. На прогоне из полутора десятков категорий по трём моделям выходит $0,30–0,40, и большая часть этого — как раз плата за поиск, а не за генерацию.

Отсюда конструкция промпта: ровно один поиск, max_results: 3, search_context_size: 'low', ответ — до 5 названий без пояснений, лимит 120–160 токенов, provider: { sort: 'price' }. Для метрики «упомянули / не упомянули» аргументация не добавляет сигнала, только цену.

Считается просто: на каждую категорию один запрос к Яндексу, и по одному запросу к каждой из трёх моделей через OpenRouter. Для 16 категорий это 16 запросов к Яндексу (≈ 81 ₽) и 48 к OpenRouter (≈ $0,34). Причём в этих $0,34 больше половины — плата за сам поиск Exa, а не за генерацию. Полный месячный прогон выходит дешевле чашки кофе.

Если захочется вместо списка получать развёрнутые мини‑обзоры — вырастет только токенная часть OpenRouter, пропорционально длине ответа. Тариф Яндекса не изменится: он за факт запроса.

Результаты

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

Матрица AI Visibility: строки — категории и их запросы, столбцы — Яндекс, GPT, Gemini, Qwen; цвет клетки показывает, упомянут ли бренд и процитирован ли сайт
Матрица AI Visibility: строки — категории и их запросы, столбцы — Яндекс, GPT, Gemini, Qwen; цвет клетки показывает, упомянут ли бренд и процитирован ли сайт

Из матрицы уже видно главное: цвета распределены не равномерно по строкам, а вертикальными полосами. То есть дело не в том, что какие‑то категории хорошие, а какие‑то нет, дело в движке.

Сводка по движкам:

Доля упоминаний бренда и цитирования сайта по каждому движку, с колонкой Δ к прошлому срезу
Доля упоминаний бренда и цитирования сайта по каждому движку, с колонкой Δ к прошлому срезу

Движок

Упоминание бренда

Цитирование сайта

Яндекс GenSearch

1/14 (7%)

2/14 (14%)

GPT

5/15 (33%)

7/15 (47%)

Gemini

2/15 (13%)

1/15 (7%)

Qwen

8/15 (53%)

0/15 (0%)

Знаменатель — успешные вызовы, а не попытки: у Яндекса один запрос упал, поэтому 14, а не 15. Колонка Δ пустая — это первый сохранённый срез, сравнивать пока не с чем.

Поскольку поиск у трёх моделей общий, разница между ними читается как свойство самой модели:

  • Qwen: 53% при 0%. Бренд называет чаще всех, на сайт не сослался ни разу при том, что документы ему подавались те же, что остальным. Значит, название пришло из памяти, а не из выдачи. Полировать страницы под этот профиль бессмысленно.

  • GPT: 33% / 47%. Обратная картина: цитирует чаще, чем называет. Опирается на поданные документы 0 здесь работа с источниками даст эффект в обозримый срок.

  • Домашний движок не значит лояльный. Яндекс единственный ищет по собственному индексу, и он оказался самым скупым: заметно консервативнее опирается на маркетплейсы и крупные медиа, чем на сайты отдельных магазинов.

  • Мерить один движок бессмысленно. По Яндексу вывод был бы «нас не знают», по Qwen — «да всё отлично». Разброс и есть результат.

Влияет ли обычное SEO на GEO

Короткий ответ: да, но только на одном из двух путей и с потолком.

Где связь прямая. Индексация — жёсткое условие: нет в индексе, значит никогда не попадёшь в выборку retrieval. Тематическая релевантность тоже работает: чем ты выше по близким формулировкам, тем выше шанс попасть в те несколько документов, что уйдут в контекст.

Где связь рвётся. Позиции ты растишь под свой запрос, а движок ищет по своим — переписанным. И даже поднявшись с 9-го на 4-е место, можно вообще ничего не выиграть: в ответ уходит горстка документов, попал или не попал. Плюс два рычага вообще лежат вне SEO: дать модели цитируемую фразу это работа с текстом, а попасть в чужой обзор, который движок цитирует, размещение и PR.

Если совсем коротко: без SEO в ИИ‑ответ не попадёшь, но одного SEO для этого мало.

Плюсы и минусы подхода

Плюсы

  • Метрики свои. Сервисы дают сводную видимость. Разрыв mention/citation и флаг «отвечала по памяти» — то, ради чего всё затевалось не показывает никто, потому что это нестандартные метрики. Здесь я их считаю как считаю нужным.

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

  • Управляемость. Список запросов, набор движков, частота прогона, глубина поиска — всё меняется мной, а не тарифом. Новый движок добавляется веткой за полчаса.

  • Корректное сравнение моделей. Один принудительный поиск на всех, того же из коробки не даёт ни один интерфейс.

  • Сырые данные остаются у меня. Метрику можно пересчитать задним числом, если поменяется гипотеза.

  • Детект без чёрного ящика. Regex объясним и воспроизводим, LLM‑судья — нет.

  • Бюджетно. Меньше доллара за полный месячный прогон против $100+/мес за платформу.

Ограничения самого метода — они одинаковы у любого GEO‑инструмента, платного в том числе:

  • Одна точка в месяц на категорию — это не распределение. Лечится только накопленной историей, для того и append‑only лог.

  • Меряется только primary_query. Fan‑out означает, что реальная выборка движка шире любой, которую задашь руками.

  • Нет связи с деньгами. Попадание в ИИ‑ответ ≠ трафик ≠ продажи. Это метрика присутствия, и пока её не закрывает ни один инструмент на рынке.

Что можно улучшить в моей реализации:

  • Regex по имени бренда — самое слабое место. Не поймает опечатку, нестандартную транслитерацию или упоминание бренда через описание. Очевидная точка роста.

  • Прокси вместо продукта. Модель + Exa ≠ ChatGPT с собственным браузингом. Решается подключением нативного поиска ценой потери сопоставимости между моделями.

  • Хрупкость к API. Провайдер меняет формат ответа правишь Normalize— ноду руками. Тестов на схему ответа пока нет.

Итог: это не замена GEO‑платформе, а дешёвый и прозрачный измеритель. Его достаточно, чтобы понять, каким путём тебя находят.

Код

Репозиторий: n8n‑seo‑monitor‑suite. Три воркфлоу, у каждого свой README с точными форматами отчётов и схемой вкладок.

  • ai-visibility/ — воркфлоу из этой статьи. Промпты для всех четырёх движков, вкладки AI_Visibility_State / AI_Visibility_History, разбор стоимости прогона.

  • daily-weekly/ — ежедневно (07:00) проверка статусов, редиректов, noindex и дрейфа H1/Title/Description против конфига; еженедельно (пн 09:00) добавляется аудит контента — количество товаров, JSON‑LD разметка, ALT у картинок — плюс снимок Яндекс.Вебмастера и uptime за 7 дней.

  • monthly-anticannibal/ — два прогона в одном воркфлоу: 1-го числа помесячный отчёт по категориям (сравнение с прошлым периодом и с прошлым годом, с поправкой на общий тренд сайта), еженедельно — скоринг каннибализации с risk score 0–100: какая страница перехватывает запросы у назначенного владельца.

  • SEO_Monitor_template.xlsx — пустой шаблон общей таблицы: все 17 вкладок с готовыми заголовками.

Импорт стандартный: закинуть JSON в n8n, подставить свои секреты и ID таблицы в Config‑нодах (плейсхолдеры перечислены в .env.example).

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