Классический совет по каннибализации ключевых слов: нашёл две страницы, которые ранжируются по одному запросу - определи главную, а остальные подчисти или склей редиректом. Проблема в том, что данный случай - это ещё не диагноз, а вот радикальные действия могут только ухудшить ранжирование. Причиной может быть шум одной недели, естественное пересечение смежных тем, или запрос, где две твои же страницы законно делят выдачу. Настоящая каннибализация - это когда конкурирующая страница действительно забирает трафик, который должен был идти нужной, и делает это не первую неделю.
Это третий и последний воркфлоу из связки n8n-seo-monitor-suite. Про GEO-мониторинг видимости в ИИ-ответах и про ежедневный/еженедельный контент-аудит я уже писал.

Один воркфлоу, два независимых запуска
Как и в предыдущих двух, здесь общий источник правды на несколько кадансов: Daily_Monitor (те же URL категорий, что и в контент-аудите), Master_Briefs (эталонные Title/H1/границы интента) и Owner_Map - таблица "какой URL за каким запросом закреплён" читаются и помесячным отчётом, и еженедельным сканом каннибализации.
[ ОБЩИЙ КОНФИГ ] Daily_Monitor · Baseline_Metrics · Master_Briefs · Owner_Map │ ┌────────────────┴─────────────────┐ ▼ ▼ ┌────────────────────────┐ ┌──────────────────────────┐ │ ПОМЕСЯЧНЫЙ ОТЧЁТ │ │ СКАН КАННИБАЛИЗАЦИИ │ │ 1-е число месяца │ │ понедельник, 09:00 │ ├─────────────────────────┤ ├────────────────────────────┤ │ • GSC/Метрика/Вебмастер │ │ • GSC query+page, 4 среза │ │ 28д к прошлым 28д и │ │ (28д/7д × текущий/пред.)│ │ аналогичному месяцу │ │ • риск-скоринг 0-100 │ │ год назад │ │ • контроль primary-запросов│ │ • модель "ожидаемо по │ │ (не влияет на скоринг) │ │ сайту" вместо порога │ │ • Query Discovery │ │ • трекинг ручных правок │ │ • живой SerpApi — только │ │ (SEO_Change_Log) │ │ когда кэш не годится │ └───────────┬──────────────┘ └─────────────┬──────────────┘ │ │ ▼ ▼ Monthly_Log (append) Cannibalization_State / _History (upsert)
Оба режима читают и пишут в общие таблицы свежести (SEO_Run_State, SEO_Page_Snapshot) и если данные за нужный день уже собраны другим прогоном, повторный фетч GSC/Метрики не делается.
Два вида конфликта
Скан различает два сценария:
Внутренняя конкуренция категорий: по кластеру запросов вместо назначенного владельца ранжируется другая категория того же сайта.
Сквозной перехват: категорию обгоняет карточка товара, статья или любой другой URL не того типа.
Это не одна и та же проблема: если категорию обгоняет сосед-категория, то вопрос в границах интента и Title/H1 обеих. Если карточка товара обгоняет категорию - вопрос уже в перелинковке и хлебных крошках, а не в переписывании текста.
Модель риска: шесть факторов, а не "пересечение = тревога"
Ядро - Code-нода Cannibalization Engine, 1500+ строк. Для каждой пары "владелец / конкурент" по общему кластеру запросов считаются шесть компонентов, каждый с собственным потолком:
Фактор | Вес | Что меряет |
|---|---|---|
Доминирование | 0-25 | доля показов конкурента в паре; ниже 35% - 0 баллов |
Смещение позиции | 0-20 | насколько конкурент выше владельца в выдаче |
Захват кликов | 0-15 | доля кликов конкурента, если есть минимум 2 клика в паре |
Тренд периода | 0-20 | владелец падает, конкурент растёт - на 28-дневном и 7-дневном окне отдельно |
Структурное несоответствие | 0-10 | у владельца 0 показов при 10+ у конкурента, запрещённая страница, легаси-редирект |
Персистентность | 0-10 | сколько прогонов подряд конфликт держится (0 при первом появлении, максимум с третьего) |
Код: вычисление факторов риска и итогового Risk Score
// Доминирование: 0..25 const dominanceScore = compShare <= 0.35 ? 0 : clamp((compShare - 0.35) / 0.55 * 25, 0, 25); // Персистентность: 0..10 const persistenceScore = prevRuns >= 3 ? 10 : (prevRuns >= 2 ? 7 : (prevRuns >= 1 ? 4 : 0));
Сумма (максимум 100) умножается на коэффициент уверенности от 0.25 до 1.0, который понижает итоговый балл, если суммарных показов в паре мало:
let confidence = pairImp >= 300 ? 0.95 : pairImp >= 100 ? 0.85 : pairImp >= 30 ? 0.70 : pairImp >= 10 ? 0.50 : 0.30; const riskScore = Math.round(rawScore * confidence);
Итоговые пороги:
Severity | Условие |
|---|---|
| суммарно меньше 10 показов и меньше 2 кликов |
| risk_score ≥ 30 |
| risk_score ≥ 55 |
| risk_score ≥ 75, конкурент держит ≥65% показов пары, и либо 2+ прогона подряд, либо 200+ показов |
Условие для CRITICAL явно требует ИЛИ повторяемости, ИЛИ объёма - один разовый всплеск трафика конкурента, даже сильный, сам по себе не может пробить критический порог. Это прямой ответ на проблему, которую в daily-weekly решали на глаз по графику; здесь разделение сигнала от шума зашито в формулу.
Диагноз зависит от типа конфликта
Движок классифицирует характер конфликта и для каждого типа даёт свою рекомендацию:
Легаси-редирект тянет видимость: сигнал переклейки/переобхода, не повод трогать контент.
Категория против категории: сверить Title/H1/H2 и границы интента обеих, ничего не менять до подтверждения конкретного пересечения.
Товар против категории: проверить анкоры, хлебные крошки и блоки рекомендаций; фразу из карточки не убирать автоматически.
Статья против категории: возможна нормальная смешанная выдача (информационный и коммерческий интент законно уживаются) - сначала подтвердить, потом решать.
Четыре разных типа конфликта → четыре разных способа решения, а не одно радикальное решиние "объединить страницы".
Живой SERP - по расписанию кэша, а не всегда
GSC и Метрика бесплатные, живой запрос в SerpApi - нет. Поэтому вызывается он не каждый прогон:
кэш SERP-позиции живёт 14 дней (
SERP_CACHE_TTL_DAYS);на прогон - жёсткий потолок в 32 живых запроса (
SERP_LIVE_MAX_QUERIES), даже если кандидатов на проверку больше;локация и домен зашиты явно (
Moscow,Moscow,Russia,google.ru/yandex.ru) — SERP чувствителен к гео, случайный запрос без локации показал бы не ту выдачу.
Эти правила я использую под свою ситуацию, чтобы уложиться в бесплатные лимиты на 250 запросов в месяц.
Отдельный, более узкий случай - "доуточнение неизвестных позиций владельца". Если по кластеру в топ-10 уже сидит чужая страница сайта, а свежей проверки именно позиции владельца ещё не было - это тот самый неоднозначный случай, где кэш не отвечает на вопрос. Нода-планировщик собирает только такие пары:
Код: отбор запросов на доуточнение позиций владельца
// Нужно свежее доуточнение позиции владельца, только если в TOP10 уже сидит другая страница сайта if (dataErr || !found || ownerMatch) continue; const exactOk = !!er && !boolVal(er.data_error, false) && ...; if (exactOk) continue; tasks.push({ engine, slug, category, query: q, owner_url: owner, reason: 'OWNER_POSITION_UNKNOWN' });
То есть живой запрос тратится не на повторную проверку, а конкретно на пробел в доказательной базе - где без него нельзя сказать, реальный это конфликт или нет.
Query Discovery — подсказывает кластер, не назначает его
Отдельная очередь: какие запросы вообще появились в GSC, но ещё не прописаны в Owner_Map. Для каждого такого запроса нода пытается угадать владельца по маркерам-словам с проверкой на границу слова (чтобы "ложки" не сработало внутри "вилки"):
// Маркер должен начинаться на границе токена return new RegExp(`(^|[^а-яёa-z0-9])${esc}[а-яёa-z0-9-]*`, 'i').test(q);
Результат - предложение с меткой уверенности:
Метка | Уверенность | Что значит |
|---|---|---|
| высокая | точное совпадение с эталонным запросом категории |
| высокая | сработал один однозначный маркер-слово |
| низкая | сработали маркеры нескольких категорий сразу - нужна ручная проверка |
| — | запрос про конкретную модель бренда, намеренно не привязывается ни к одной категории |
| — | ни один маркер не сработал |
Разница с основным скорингом принципиальна: Discovery никогда не становится доказательством каннибализации сама по себе - это отдельная очередь на ревью, а не источник инцидентов.
Контроль важных запросов отдельно от скоринга
Кроме взвешенной оценки, у каждой категории есть primary_query из Master_Briefs - эталонный запрос, за которым следят отдельно от того, попал ли он в скоринг. Проверка сверяет, кто фактически лидирует в GSC, с кэшированным или живым SERP, и выдаёт один из статусов: подтверждён нужный URL, подтверждён конфликт, смешанный результат, владелец вне топ-10, ошибка данных или "неоднозначный запрос", если в нём есть название бренда и в выдаче участвует главная страница или карточка товара (по бренду законно ранжируется что угодно, это не конфликт категорий).
Это сознательно отдельный от скоринга слой: контроль эталонных запросов ничего не добавляет и не снимает с risk_score, это параллельная сверка "ранжируется то, что должно?", ценная сама по себе, даже когда общий скоринг ничего не подсветил.
Визуализация: граф конфликтов, а не просто список
На выходе скана - два изображения. Первое - это Graphviz DOT-граф: блок целевой категории → блок с перехваченными запросами и цветом по severity → блок конкурирующей страницы. Показываются только два самых рискованных активных конфликта, с явной пометкой "ещё N - в полном отчёте", если их больше.
Второе изображение - это обычный горизонтальный bar-чарт risk_score по всем активным инцидентам, тот же принцип, что и в контент-аудите: зелёного тут нет в принципе, чарт рисует только то, что уже прошло порог WATCH.
Помесячный отчёт: три графика, модель отклонения от сайта и AI-резюме
Отчёт 1-го числа месяца включает не только каннибализацию — у него собственный аналитический контур, сопоставимый по объёму со всей остальной системой.
Раз в месяц воркфлоу генерирует управленческий пакет:
Текстовую экспресс-сводку в Telegram (трафик, конверсии, поведение и срез после переоптимизации).
AI-интерпретацию поверх детерминированных расчётов с прогнозом (
🟡 НАБЛЮДАТЬ).Три графических среза (макротренд, матрица категорий, позиции в выдаче).
Прикреплённый файл
SEO_Categories_Monthly_YYYY-MM-DD.mdс постраничной аналитикой по всем 16 категориям и сравнением год к году.
Три графика: от макротренда к позициям в выдаче
1. История 6 месяцев (сжато) + последние 60 дней подробно с таймлайном правок
Позволяет отличить сезонный спад от технической просадки и сопоставить тренд с реальными релизами.

Линия baseline: отсечка, с которой начался регулярный мониторинг и замеры.
Маркеры правок (
SEO - 1 авг,SEO - 12 авг): точечные даты выкатки правок из таблицыSEO_Change_Log. Наглядно видно, изменился ли тренд после изменений на странице.Сведение Google и Яндекс на одну шкалу: позволяет мгновенно заметить расхождение между поисковиками.
2. Матрица изменений по категориям за последний месяц
Построчный срез в разрезе каждого раздела каталога: Яндекс-визиты, Google-клики и показы с индикаторами динамики (▲ / ▼ / ●).

Фиксация ножниц: если показы растут (
Google: 68 → 109 ▲), а клики стоят на месте (1 → 1 ●) - проблема в сниппете, кликабельности (CTR) или несоответствии интента.Категории-локомотивы: сразу показывает ядро трафика - 7 036 из 13 996 показов Google приходятся на одну категорию ("Категория 1").
3. Тепловая карта primary-запросов (Google vs Яндекс)
Срез по 16 эталонным запросам категорий с цветовой кодировкой: 🟢 топ 1-4, 🟡 топ 5-10, 🔴 >10. Стрелки месячного движения подключаются после накопления истории от 21 до 45 дней.

Алгоритмический рассинхрон: "Категория 3" сидят на #1 в Яндексе и на #5 в Google; "Категория 5" - #4 в Яндексе и >10 в Google. Это сразу отсекает текстовый переспам и указывает на ссылочные или поведенческие различия.
Изолированный контроль: статус primary-запросов не влияет на скоринг каннибализации это параллельная витрина ранжирования ключевых страниц.
Экспресс-сводка и AI-выжимка в Telegram
Бот присылает компактную сводку прямо в канал, чтобы оценить общую динамику без открытия таблиц:
Пример сообщений в Telegram: экспресс-сводка и AI-резюме
📊 SEO Сводка по Категориям (30 дней)
ТРАФИК И ДИНАМИКА • Яндекс Визиты: 140 (пред. 30 дней: 195, Δ -55 🔻) • Google Клики: 220 (пред. 30 дней: 360, Δ -140 🔻) • Google Показы: 31 500 (пред. 30 дней: 45 000, Δ -13 500 🔻)
ПОСЛЕ ПЕРЕОПТИМИЗАЦИИ (факт к ожиданию по сайту) • Яндекс: 170 → 140 🔻 -17.6% · ожидалось ~185 · хуже тренда сайта • Google клики: 350 → 220 🔻 -37.1% · ожидалось ~310 · хуже тренда сайта • Google показы: 42 000 → 31 500 🔻 -25.0% · ожидалось ~30 800 · в русле сайта
КОНФЛИКТЫ И ВЫДАЧА • 🛡️ Каннибализация категорий: 1 конфликт (ущерб низкий) • 🔀 Межтиповой перехват: 1 пересечение (ущерб низкий) • 🔎 SERP primary (16 запросов): Google 4🟢 / 4🟡 / 8🔴 · Яндекс 3🟢 / 6🟡 / 7🔴
📊 SEO-анализ категорий за месяц (AI-резюме)
Макротренд: трафик категорий снизился сильнее общего движения сайта (Яндекс по сайту +5.8%, по категориям -28.2%). При этом показы в Google просели синхронно с общим трендом каталога.
Драйверы: основной объём трафика удерживают категории сегментов "Alpha" и флагманская линейка "Бренд X". В Яндексе локальный спад затронул большинство ключевых посадочных страниц.
SERP: в Google в первой четвёрке ранжируются эталонные запросы категорий Alpha, Beta, Gamma и Delta. В Яндексе в топ-4 удерживаются коммерческие посадочные категорий Epsilon, Alpha и Zeta.
Прогноз: 🟡 НАБЛЮДАТЬ. Трафик категорий падает быстрее сайта, зафиксированы единичные пересечения интентов без подтверждённого коммерческого ущерба. Рекомендовано подготовить варианты разграничения интентов в метатегах и продолжать сбор метрик.
Модель ожиданий по сайту: почему плохой месяц — не всегда RED
Оценивать категорию в вакууме бессмысленно: если раздел упал на 15%, а весь каталог из-за сезонности просел на 30%, категория чувствует себя лучше рынка.
Система рассчитывает две оценки отклонения от ожидания: structural_residual_pct (к годовому тренду сайта) и short_residual_pct (к динамике за последний месяц). Итоговый статус балансирует оба сигнала: если годовой тренд отрицательный, но за последние 30 дней наметился разворот вверх, категория не уходит в тревогу.
Код: расчет ожиданий по сайту и калибровка статуса
const expectedFromSite = (yoyValue, siteCurrent, siteYoy) => (Number(siteYoy) > 0 ? Number(yoyValue) * Number(siteCurrent) / Number(siteYoy) : null); const residualPct = (actual, expected, minExpected = 1) => (expected !== null && Number(expected) >= minExpected ? round1((Number(actual) / Number(expected) - 1) * 100) : null); // Разворот на коротком окне смягчает застарелый негативный годовой тренд if (structural === 'CATEGORY_SPECIFIC_LOSS') { if (shortRelative === 'BETTER_THAN_SITE' || shortS === 'UP') return 'YELLOW'; return 'RED'; }
Статус | Код | Логика классификатора | В отчёте за месяц |
🟢 Норма |
| Раздел растёт или держится в русле тренда сайта | 0 категорий (весь каталог просел сильнее сайта) |
🟡 Наблюдение |
| Разнонаправленные метрики или отскок на коротком окне | 10 категорий (в т.ч. "категория 1") |
🔴 Внимание |
| Синхронное падение по месяцу и году без отскока | 0 категорий (системного краха нет) |
⚪ Мало данных |
| Меньше 10 визитов/кликов (нерепрезентативный объём) | 6 категорий (выводы отложены) |
Детальный Markdown-аудит
Вместе с графиками бот отправляет файл SEO_Categories_Monthly. В нём каждая категория расписана по визитам, отказам, времени на странице и динамике YoY. Это позволяет сразу провалиться в цифры конкретного URL, получившего статус YELLOW.
Пример полного Markdown-отчёта
# SEO-анализ категорий за месяц · 30 дней > Только категории каталога. ## 🧪 После переоптимизации - Яндекс-визиты: **79 → 56** (-29.1%); ожидалось по движению сайта ~83; **хуже общего тренда сайта**. - Google клики: **185 → 109** (-41.1%); ожидалось по движению сайта ~148; **хуже общего тренда сайта**. - Google показы: **19 906 → 14 398** (-27.7%); ожидалось по движению сайта ~14 041; **примерно в русле сайта**. ## 📊 Сводка за последние 30 дней - Яндекс-визиты: **81 → 56** (-30.9%) - Google клики: **181 → 108** (-40.3%) - Google показы: **20 011 → 13 996** (-30.1%) - Яндекс по всему сайту: **2 533 → 2 691** (+6.2%) - Google клики по всему сайту: **1 871 → 1 457** - Google показы по всему сайту: **88 831 → 60 970** ## 📅 Год к году · дополнительный контекст - Яндекс: 4 из 16 категорий · 54 → 32 (-40.7%) - Google клики: 6 из 16 · 69 → 71 (+2.9%) - Google показы: 9 из 16 · 7 506 → 12 709 (+69.3%) ## 🔎 SERP primary — позиции и динамика > Показана позиция именно назначенной категории (owner URL). Месячные стрелки появятся после накопления истории 21–45 дней. - Primary-запросов: **16** - Текущий срез: **2026-08-27** - Google: TOP 1–4 **4** · 5–10 **4** · >10 **8** - Яндекс: TOP 1–4 **3** · 5–10 **6** · >10 **7** | Категория | Primary query | Google | Δ | Яндекс | Δ | |---|---|---:|---:|---:|---:| | Категория Alpha | `купить товар alpha каталог` | #2 | — | #3 | — | | Категория Beta | `товары категории beta цена` | #4 | — | >10 | — | | Категория Gamma | `линейка оборудования gamma` | #5 | — | #1 | — | | ... | *[ещё 13 primary-запросов]* | ... | — | ... | — | ## 🛠 Изменения под наблюдением *Активных WATCH-изменений нет.* --- ## 🟢 Норма — 0 *Нет* --- ## 🟡 Требуют наблюдения — 10 ### 🔹 Категория Alpha (Флагманская линейка) **Яндекс Визиты:** **20** ├ Предыдущие 30 дней: 33 (Δ -13) 🔻 └ Год назад: 9 (Δ +11) 🔼 **Google Показы:** **7 036** ├ Предыдущие 30 дней: 8 176 (Δ -1 140) 🔻 └ Год назад: 1 430 (Δ +5 606) 🔼 **Google Клики:** **34** ├ Предыдущие 30 дней: 48 (Δ -14) 🔻 └ Год назад: 40 (Δ -6) 🔻 **Поведение** Отказы: **50%** └ Предыдущие 30 дней: 48.5% (Δ +1.5 п.п.) 🔻 Время: **1м 21с** └ Предыдущие 30 дней: 1м 4с (Δ +16с) 🔼 Глубина: **1.6** └ Предыдущие 30 дней: 1.55 (Δ +0.05) 🔼 *💡 Вывод:* За месяц показатели идут в разные стороны: локальный спад месяца на фоне долгосрочного роста к прошлому году. Яндекс снижается, Google-клики снижаются, Google-показы снижаются. --- ### 🔹 Категория Beta (Сегмент Pro / Тяжёлая серия) **Яндекс Визиты:** **6** ├ Предыдущие 30 дней: 16 (Δ -10) 🔻 └ Год назад: 32 (Δ -26) 🔻 **Google Показы:** **524** ├ Предыдущие 30 дней: 1 201 (Δ -677) 🔻 └ Год назад: 101 (Δ +423) 🔼 **Google Клики:** **8** ├ Предыдущие 30 дней: 23 (Δ -15) 🔻 └ Год назад: недостаточно данных для сравнения **Поведение** Отказы: **33.3%** └ Предыдущие 30 дней: 31.3% (Δ +2.1 п.п.) 🔻 Время: **4м 58с** └ Предыдущие 30 дней: 4м 23с (Δ +35с) 🔼 Глубина: **2** └ Предыдущие 30 дней: 3.31 (Δ -1.31) 🔻 ⚪ Поведение: выборка меньше 10 визитов из Яндекса — не используем как устойчивый сигнал. *💡 Вывод:* Категория снижается заметно сильнее общего тренда сайта. За месяц: Яндекс снижается, Google-клики снижаются, Google-показы снижаются. Требуется ручной аудит сниппетов. --- ... [остальные 8 категорий в статусе 🟡 Требуют наблюдения опущены для краткости] ... --- ## 🔴 Требуют внимания — 0 *Нет* --- ## 🟣 Проверка данных — 0 *Нет* --- ## ⚪ Мало данных — 6 ... [6 категорий каталога с выборкой менее 10 визитов/кликов опущены: выводы отложены до накопления данных] ... --- ## ⚙️ Данные - Метрика Яндекс: OK / OK / OK - GSC: OK / OK / OK - Snapshot: PAGE-V3:2026-08-30:M:2026-08-30 - Каннибализация: CANNIB:2026-08-30:YQ:2026-08-30
Отслеживание ручных правок - система не закрывает вопрос сама
Для контроля внедрений заведена таблица SEO_Change_Log. Пайплайн работы с ней выстроен так, чтобы исключить ложные выводы:
Фиксация правки (руками): заносим URL, дату релиза, суть изменения и проверяемую гипотезу со статусом
WATCH.Расчёт эффекта (n8n): нода
Analyze SEO Changes Monthlyсравнивает фактическую динамику с модельной за равные отрезки времени "до" и "после" даты внедрения, а затем строит график восстановления, когда накопится репрезентативный объём данных.Валидация результата (руками): система может показать, что трафик восстанавливается быстрее или медленнее прогноза, но перевести статус в
RESOLVEDможет только специалист.
Это осознанное ограничение автоматизации, а не недоработка: подтверждение причинно-следственной связи (помогла именно наша правка, а не апдейт выдачи или сезонный всплеск) всегда остаётся за человеком.
Почему логика детерминированная, а LLM — только рассказчик
Здесь работает тот же инженерный принцип, что и в предыдущих статьях цикла (GEO-детект без второй модели, regex вместо тяжёлого HTML-парсера в контент-аудите):
Вся аналитика строго детерминирована:
risk_score,severity,lifecycleи логика диагнозов рассчитываются исключительно математикой в Code-нодах на чистом JS.
LLM (в моём случае Qwen) получает на вход уже готовый JSON и выступает исключительно в роли интерфейса - собирает сухие цифры в связную сводку для Telegram. Замените модель на любую другую, отключите её вовсе или отдавайте сырые данные напрямую в дашборд - скоринг, вердикты и приоритеты не изменятся ни на балл.
Результаты: как именно получается 59 из 100
Собранный воркфлоу производит инцидент-карточки такого вида:
Кластер: "ложки / вилки" — HIGH 59/100 Владелец: /collection/example-a · Конкурент: /collection/example-b (категория) Confidence: HIGH (0.9) · Lifecycle: PERSISTING · Consecutive runs: 11 Показы 28д: владелец 0 / конкурент 127 (100% доля конкурента) Клики 28д: владелец 0 / конкурент 0 Пред. 28д: владелец 0 / конкурент 217 7д: владелец 0 / конкурент 14; пред. 7д: владелец 0 / конкурент 37
Разложить 59 баллов на компоненты можно прямо по формуле:
Фактор | Расчёт | Балл |
|---|---|---|
Доминирование | доля конкурента 100% (потолок) | 25 |
Смещение позиции | у владельца 0 показов, у конкурента позиция ≤20 | 20 |
Захват кликов | кликов 0 у обоих - фактор не сработал | 0 |
Тренд периода | у владельца 0 показов и до, и после - падать неоткуда, тренд не засчитан | 0 |
Структурное несоответствие | владелец 0 показов при конкуренте 10+ | 10 |
Персистентность | 11 прогонов подряд ≥ 3 | 10 |
Сырая сумма | 65 | |
Confidence | 127 показов в паре → 0.85, плюс +0.05 за 7+ запросов в кластере | ×0.90 |
Итог | round(65 × 0.90) | 59 → HIGH |
Показательный момент: у конкурента снижение показов 217 → 127 за месяц и 37 → 14 за неделю - конфликт объективно слабеет, но lifecycle всё равно остаётся PERSISTING, а не переключается в IMPROVING, потому что для IMPROVING риск-скор должен упасть минимум на 10 баллов от прошлого замера, а не просто показать снижение показов конкурента. Отдельная деталь — при confidence 0.90 и compShare 100% формально выполнены два из трёх условий CRITICAL (доля ≥65%, 11 прогонов ≥2), но сама планка risk_score ≥75 не взята: без вклада от тренда и кликов сырых 65 баллов даже с максимальным confidence не хватает. Конфликт стабильный и объёмный, но не "горит" - ровно то разделение, ради которого и городился шестифакторный подсчёт вместо одного правила "доля выше X% → тревога".
Плюсы и ограничения подхода
Область | Сильные стороны (Плюсы) | Ограничения и компромиссы |
|---|---|---|
Скоринг и аналитика | Диагноз вместо списка пересечений: шкала риска 0-100 с конкретным планом действий вместо голого факта совпадения URL. | Эвристические веса: коэффициенты (25/20/15…) и пороги подобраны инженерной оценкой, а не обучены на исторических данных бизнеса. |
Фильтрация шума | Защита от ложных тревог: уровень | Чувствительность к конфигу: модель слепо доверяет |
Инженерия и бюджет | 0 рублей на платные тарифы: двухуровневый TTL-кэш и точечные дозапросы строго удерживают SerpApi в лимите 250 запросов/мес. | Хрупкость при переносе: домен захардкожен в хелперах, а бренд ловится базовой регуляркой - при копировании на другой сайт код нужно вычищать руками. |
Валидация решений | Контроль причинности: n8n показывает динамику до/после, но статус | Человеческий фактор: система не закрывает инциденты автономно - разбор спорных кейсов и ведение лога правок требуют дисциплины оператора. |
Стоимость
GSC, Яндекс.Метрика и Яндекс.Вебмастер - бесплатные. У SerpApi для живых SERP-проверок есть бесплатный лимит - 250 запросов в месяц, дальше тарифы стартуют от $25 за 1000. Вся конструкция с TTL-кэшем и точечным дозапросом построена так, чтобы держаться в этом бесплатном лимите: свежий кэш перекрывает большинство прогонов, а живой запрос идёт только для действительно неоднозначных случаев. Весь дизайн freshness/backfill существует ровно для того, чтобы никогда не пришлось переходить на платный план.
Код
Репозиторий тот же — n8n-seo-monitor-suite. Воркфлоу из этой статьи - в monthly-anticannibal/: README с полной схемой обеих таблиц состояния, форматом карточки инцидента и списком статусов контроля primary-запросов.
Про GEO-мониторинг видимости в ИИ-ответах и про ежедневный/еженедельный контент-аудит - первые две статьи цикла.

