GEO своими руками: собираем трекинг видимости бренда в ИИ‑ответах на n8n [+ воркфлоу]. ai overviews.. ai overviews. Generative Engine Optimization.. ai overviews. Generative Engine Optimization. geo.. ai overviews. Generative Engine Optimization. geo. llm.. ai overviews. Generative Engine Optimization. geo. llm. n8n.. ai overviews. Generative Engine Optimization. geo. llm. n8n. openrouter.. ai overviews. Generative Engine Optimization. geo. llm. n8n. openrouter. seo.. ai overviews. Generative Engine Optimization. geo. llm. n8n. openrouter. seo. видимость бренда.. ai overviews. Generative Engine Optimization. geo. llm. n8n. openrouter. seo. видимость бренда. искусственный интеллект.. ai overviews. Generative Engine Optimization. geo. llm. n8n. openrouter. seo. видимость бренда. искусственный интеллект. мониторинг.. ai overviews. Generative Engine Optimization. geo. llm. n8n. openrouter. seo. видимость бренда. искусственный интеллект. мониторинг. Поисковая оптимизация.. ai overviews. Generative Engine Optimization. geo. llm. n8n. openrouter. seo. видимость бренда. искусственный интеллект. мониторинг. Поисковая оптимизация. Разработка под e-commerce.. ai overviews. Generative Engine Optimization. geo. llm. n8n. openrouter. seo. видимость бренда. искусственный интеллект. мониторинг. Поисковая оптимизация. Разработка под e-commerce. яндекс gensearch.

И у 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 = /bbrandnameb/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).

Автор: Dimazzina

Источник