Обзор модуляЧасть V · ~10 ч · Сложность: (продвинутый) · Пререквизиты: Модуль 12, 19
К моменту, когда главная модель ранжирования (Модуль 12, стадии L2/L3) выдала упорядоченный список, работа поиска ещё не закончена. Между «отсортированным по релевантности списком кандидатов» и «тем, что увидит пользователь», лежит отдельный программный слой — постранжирование (post-ranking, rearrange). Это не одна модель, а конвейер правил, которые могут переставлять документы, понижать или повышать их позицию, выбрасывать целые классы результатов, навешивать пометки и применять политики, не сводящиеся к «релевантности». Здесь живёт антиспам выдачи, контентные фильтры, юридические изъятия, «песочница» новых сайтов и — кульминация всего курса — принудительная нейтрализация манипулятивных факторов для уязвимых классов запросов.
В сквозном конвейере «обход → индекс → факторы → ранжирование → выдача → постобработка → измерение» этот модуль — стадия «постобработка». На вход он получает результат каскада (Модуль 12) и сгруппированную/диверсифицированную выдачу (Модуль 15), а на выходе отдаёт финальный список в движок выдачи. Важно понять архитектурную границу: ранжирование отвечает на вопрос «насколько документ релевантен», а постранжирование — на вопрос «должны ли мы и в каком виде это показывать». Эти вопросы разные, и смешивать их в одной формуле опасно: релевантность — это про смысл, а постранжирование — про качество, безопасность, легальность и устойчивость к манипуляциям.
В этом модуле вы научитесь проектировать фреймворк правил постранжирования с фазами исполнения и A/B-хуками; отличать мягкую пессимизацию (понижение по ML-формуле) от жёсткого удаления/бана; строить контентные и возрастные фильтры, бан-листы и «песочницу» для новых сайтов; и, главное, понимать механизм anti-SEO reset — почему для коммерческих («денежных») запросов система может принудительно обнулять блок ссылочных и манипулятивных факторов прямо на скоринге, и почему именно это делает накрутку ссылок (Модуль 7) и поведения (Модуль 11) экономически бессмысленной.
Как читать по трекамИнтуиция. Ранжирование — это судьи, которые выставили оценки выступлениям. Постранжирование — это регламент соревнования поверх оценок: дисквалифицировать за допинг (антиспам), не пускать несовершеннолетних на взрослую сцену (фильтры), не доверять баллам новичка без проверенной истории («песочница») и — в чувствительных дисциплинах — вообще не засчитывать спорный вид баллов, потому что его слишком легко накрутить (anti-SEO reset). Судьи считают «насколько хорошо». Регламент решает «что и как объявить».
- Студент CS — обязательно всё. Ядро: 16.1 (фреймворк правил как программная абстракция: фазы, регистрация, конфигурация) и 16.4 (математика принудительного обнуления факторов и его связь с теорией графа из Модуля 7). Лабы по проектированию пайплайна правил и по моделированию anti-SEO reset — делать руками.
- Инженер поиска/ML — обязательно всё, особенно инженерные заметки про порядок фаз, идемпотентность правил, аудит-лог решений, обучение ML-пессимизатора и интеграцию A/B-хуков. Это слой, в котором проще всего сломать выдачу одной строкой конфига.
- SEO-специалист — это самый важный для вас модуль курса. Обязательно 16.2 (за что понижают и банят), 16.3 («песочница» — почему новый сайт не растёт первые месяцы), и особенно 16.4 (почему ссылочная накрутка не работает на коммерческих запросах — anti-SEO reset). SEO-врезки читать дословно.
- Смешанный/руководитель — Обзор, интуиции, заблуждения, итоги; 16.2 целиком (риск-менеджмент: бан стоит трафика) и главная мысль 16.4. Формулы — по диагонали, но запомните идею «спорный фактор можно просто обнулить».
- 16.1. Фреймворк правил постранжирования (rearrange): фазы исполнения, регистрация и конфигурация правил, A/B-хуки (продвинутый)
- 16.2. Антиспам выдачи: мягкая пессимизация (понижение по ML-формуле) vs жёсткое удаление/бан (продвинутый)
- 16.3. Фильтры контента: возрастные, тематические, бан-листы; «песочница» новых сайтов (средний)
- 16.4. Анти-SEO: принудительная нейтрализация манипулятивных факторов для уязвимых классов запросов (продвинутый)
Цели обучения
После главы студент сможет:
- Объяснить, почему постранжирование вынесено в отдельный слой, а не «дописано в формулу ранжирования».
- Описать фазы исполнения конвейера правил (pre-filter → rerank → diversify → trim → annotate → post-filter) и почему порядок важен.
- Спроектировать контракт правила: вход, выход, побочные эффекты, идемпотентность, аудит-лог.
- Реализовать реестр правил (registry) и декларативную конфигурацию их применения под класс запроса/эксперимент.
- Встроить A/B-хуки так, чтобы любое правило можно было включить/выключить и измерить его эффект без релиза.
Зачем отдельный слой, а не «ещё пара признаков в модели»
Соблазн велик: «спам — это просто документ с низкой оценкой, пусть модель ранжирования сама задвинет его вниз». На практике так не делают по нескольким причинам.
Строгие причины разделения:Интуиция. Модель ранжирования обучена отвечать на вопрос «насколько релевантен», на размеченных асессорами и кликах данных. Но «удалить по требованию закона», «не показывать взрослый контент ребёнку», «забанить домен за обман» — это не вопросы релевантности. Спамный документ может быть идеально релевантным запросу (потому и попал в топ!). Запихивать политики и безопасность в loss-функцию ранкера — значит загрязнять сигнал релевантности и терять управляемость.
- Разная природа решений. Релевантность — непрерывная, обучаемая, вероятностная. Политики — часто дискретные и детерминированные («показать / не показать»), нередко с юридическими и этическими требованиями к объяснимости и воспроизводимости. ML-оценку «почему 0.73» объяснить регулятору трудно; правило «домен в бан-листе по решению X» — легко.
- Разные владельцы и циклы изменений. Формулу ранжирования меняет ML-команда раз в недели/месяцы через переобучение. Бан-лист или возрастной фильтр меняется командой качества/безопасности за минуты и не должен требовать переобучения модели.
- Управляемость и аудит. Каждое изъятие/понижение должно попадать в аудит-лог («документ D понижен правилом R по причине C на запросе Q»). Внутри весов градиентного бустинга такого лога нет.
- Композиция. Политик много, они частично конфликтуют, и порядок применения важен. Это естественно описывается конвейером правил, а не одной формулой.
Контракт правила постранжированияИнженерная заметка. Граница «ранжирование ↔ постранжирование» — это граница между обучаемым и декларативным. ML отвечает за «что релевантно» (трудно объяснить, легко улучшать данными), правила — за «что и как показать» (легко объяснить, трудно «обучить», зато мгновенно меняется конфигом). Не размывайте эту границу: как только бизнес-политика просочилась в loss ранкера, вы теряете и объяснимость, и скорость реакции.
Базовая абстракция — правило (rule): функция над текущим состоянием выдачи.
Код: Выделить всё
интерфейс Rule:
name: str # уникальное имя для реестра, логов, A/B
phase: Phase # в какой фазе исполняется
applies(ctx) -> bool # предикат активации (по интенту, региону, эксперименту)
apply(serp, ctx) -> serp' # чистое преобразование выдачи
# инварианты:
# - идемпотентность: apply(apply(s)) == apply(s) по возможности
# - детерминизм при фиксированном ctx
# - каждое изменение пишет запись в ctx.audit
Фазы исполнения: почему порядок критиченВнимание. Правило не должно «молча» менять выдачу. Каждое перемещение, понижение, удаление или пометка обязаны оставлять структурированную запись в аудит-логе: {rule, doc_id, action, reason, delta}. Без этого вы не сможете ни отладить «почему сайт пропал», ни ответить на жалобу, ни оценить эффект правила в A/B.
Конвейер постранжирования разбит на фазы (phases) — упорядоченные группы правил. Порядок не косметический: одно и то же множество правил в разном порядке даёт разную выдачу.
Код: Выделить всё
Фаза | Назначение | Примеры правил | Тип операции
----------------+---------------------------------------------------------+-----------------------------------------------------------------------+--------------------------
0. pre-filter | Жёсткие изъятия ДО любой перестановки | юридические removals, бан-домены, региональные блокировки | удаление
1. rerank | Понижение/повышение по политикам качества | мягкая пессимизация спама (16.2), boost верифицированных источников | изменение скора/позиции
2. diversify | Разнообразие, антидубли, группировка по хосту | host-crowding, дедуп, диверсификация (Модуль 15) | перестановка/схлопывание
3. trim | Обрезка до глубины выдачи, квоты вертикалей | оставить топ-k, квота на один домен | усечение
4. annotate | Навешивание пометок, не меняющих порядок | бейдж «реклама», «возрастное», «кэш», иконки | пометка
5. post-filter | Финальные проверки безопасности по уже готовому верху | safe-search по итоговому топу, проверка на «пустую выдачу» | удаление/фоллбэк
Интуиция (почему порядок важен). Если сначала обрезать до топ-10 (trim), а потом диверсифицировать, можно получить 10 страниц одного домена и нечего разнообразить — кандидаты для замены уже выброшены. Поэтому diversify идёт до trim. И наоборот: жёсткие изъятия (pre-filter) идут в самом начале — нет смысла переставлять и аннотировать документ, который потом всё равно удалят. Порядок фаз кодирует приоритеты политик.
Реестр правил и декларативная конфигурацияПример. Запрос привёл топ из 5 документов: [A, B(спам), C, D(забанен), E].
- pre-filter удаляет D (бан-домен): [A, B, C, E].
- rerank мягко пессимизирует B (спам-скор высокий) на −3 позиции: [A, C, E, B].
- diversify: A и C — один хост, второй схлопываем под спойлер: [A, E, B] (+ свёрнутый C).
- trim до топ-3: [A, E, B].
- annotate: E помечается «реклама».
- post-filter: safe-search проверяет топ — всё чисто, выдача уходит.
Поменяйте местами trim и diversify — и вы схлопнете уже обрезанный список, потеряв E.
Правила не «зашиты» в код процедурно — они регистрируются в реестре (registry) и активируются конфигурацией. Это даёт две суперспособности: менять поведение без релиза и переключать набор правил под класс запроса/эксперимент.
Код: Выделить всё
# регистрация (код пишется один раз)
registry.register(AntiSpamSoftPenalty(model="spam_v7"))
registry.register(BanlistFilter(source="legal_removals"))
registry.register(HostCrowding(max_per_host=2))
registry.register(SandboxDamping(age_threshold_days=120))
registry.register(AntiSeoReset(query_classes={"commercial", "ymyl"}))
# конфигурация применения (меняется без релиза, версионируется)
profile "commercial":
phases:
pre-filter: [BanlistFilter]
rerank: [AntiSeoReset, AntiSpamSoftPenalty, SandboxDamping]
diversify: [HostCrowding]
trim: [DepthTrim(k=10), HostQuota(1)]
annotate: [AdLabel, AgeLabel]
post-filter: [SafeSearch(mode=ctx.age_mode), EmptyResultFallback]
A/B-хуки: каждое правило измеримоИнженерная заметка. Конфиг — это версионируемый артефакт (как код, в системе контроля версий, с ревью и откатом). Он привязан к профилю (часто = классу запроса из Модуля 5: commercial, navigational, ymyl, adult…). Один и тот же реестр кода обслуживает все профили; различается только декларация «какие правила, в каких фазах, с какими параметрами». Это прямое продолжение идеи «формула под класс запроса» из Модуля 12.
Постранжирование меняет выдачу драматически (удалить домен — это минус весь его трафик). Поэтому ни одно правило не выкатывается без эксперимента. Фреймворк обязан давать A/B-хуки на уровне правила.
Механика: правило applies(ctx) смотрит на ctx.experiments. Запрос детерминированно (по хешу пользователя/сессии) попадает в контрольную или экспериментальную группу; в контроле правило не применяется, в эксперименте — применяется. Эффект меряется на метриках качества (NDCG, удовлетворённость, доля «спам в топе») и бизнес-метриках (Модуль 19: A/B-инфраструктура и метрики).
Код: Выделить всё
applies(ctx):
if not ctx.experiments.enabled("antispam_v7"):
return False # контроль: правило выключено
if ctx.experiments.variant("antispam_v7") == "control":
return False
return ctx.query_class in {"commercial", "informational"}
Внимание. A/B-хук должен переключать только применение правила, а не его наличие в логах. Даже в контрольной группе полезно в shadow-режиме посчитать, что правило сделало бы (но не применять), — это даёт оценку эффекта без влияния на пользователя. Иначе вы узнаете эффект только постфактум.
Частые заблужденияSEO-врезка. Резкое исчезновение сайта из топа без изменений на сайте — частый признак выката нового правила постранжирования (или попадания в новую группу A/B), а не «падения релевантности». Диагностический признак: упал не один запрос, а целый класс (например, все коммерческие), и упал ступенчато в один день. Это поведение конфига/правила, а не плавная динамика обучаемой модели.
Заблуждение. «Постранжирование — это просто финальная сортировка.» Нет. Это многофазный конвейер с удалениями, пессимизацией, диверсификацией, аннотацией и фоллбэками. Сортировка (rerank) — лишь одна из фаз, и часто не главная: жёсткие изъятия (pre-filter) и safe-search (post-filter) важнее для качества и легальности.
Заблуждение. «Если документ хорошо ранжируется, постранжирование его не тронет.» Тронет — и именно высоко ранжированные документы оно трогает чаще всего. Спам, манипуляция и нарушения по определению стремятся в топ; постранжирование — это слой, который смотрит на топ критическим взглядом «а заслуженно ли».
Лаба / практикаЗаблуждение. «Порядок правил не важен, результат один.» Правила не коммутативны: trim до diversify, pre-filter после rerank — это разные выдачи. Порядок фаз — часть спецификации, а не деталь реализации.
Задача. Реализовать мини-фреймворк постранжирования.
Вход: список из 12 документов с полями {id, host, score, is_spam, is_banned, age_days, is_ad}.
Шаги:
- Реализуйте интерфейс Rule и реестр.
- Реализуйте 5 правил: BanlistFilter (pre-filter), AntiSpamSoftPenalty (rerank, −X позиций при is_spam), HostCrowding (diversify, ≤2 на хост), DepthTrim(k=10) (trim), AdLabel (annotate).
- Соберите конвейер по фазам, прогоните, выведите аудит-лог каждого действия.
- Поменяйте местами diversify и trim, сравните выдачи.
Критерий «сделано»: аудит-лог объясняет каждое отличие между двумя прогонами; вы можете словами сказать, почему trim-до-diversify теряет кандидатов. Время ~60 мин.
Контрольные вопросы
- Почему политики безопасности и легальности не стоит «зашивать» в loss-функцию ранкера? Назовите три причины.
- Что должно попадать в аудит-лог при каждом действии правила и зачем?
- Приведите пару фаз, перестановка которых меняет выдачу, и объясните механизм.
- Зачем нужна декларативная конфигурация поверх реестра правил, если правила уже написаны в коде?
- Что такое shadow-режим A/B-хука и какую проблему он решает?
- Как по поведению выдачи отличить выкат нового правила постранжирования от изменения обучаемой модели?
- Почему именно высоко ранжированные документы чаще всего становятся целью постранжирования?
Цели обучения
После главы студент сможет:
- Разграничить спам-документ и нерелевантный документ: почему спам опасен именно тем, что релевантен.
- Сравнить два механизма наказания — мягкую пессимизацию (понижение скора по ML-формуле) и жёсткое удаление/бан — по их свойствам, рискам и применимости.
- Сформулировать спам-скор как выход классификатора и встроить его в фазу rerank как штраф к ранжирующему скору.
- Объяснить роль порогов, гистерезиса и апелляций в управлении ошибками первого и второго рода.
- Оценить цену ошибки обоих механизмов (ложный бан честного сайта vs пропуск спама в топ).
Что такое спам выдачи и почему он коварен
Типовые семейства спама (абстрактно, без брендов):Интуиция. Спам — это не «плохой и нерелевантный» документ. Нерелевантный документ модель ранжирования и так задвинет вниз — он не проблема. Спам — это документ, который искусственно выглядит релевантным и качественным, чтобы обмануть факторы ранжирования и пролезть в топ, не давая пользователю реальной ценности. Спам по построению оптимизирован под формулу, а не под пользователя. Именно поэтому он попадает в топ — и именно поэтому нужен отдельный слой защиты.
- Контентный спам: переспам ключевых слов (keyword stuffing), сгенерированный/склеенный текст, скрытый текст, дорвеи (doorway) — страницы под запрос с редиректом на другое.
- Ссылочный спам: покупные/обменные/PBN-ссылки, ссылочные фермы — манипуляция графом авторитета (Модуль 7).
- Поведенческий спам: накрутка кликов/дочиток для манипуляции поведенческими сигналами (Модуль 11).
- Технический/обманный: клоакинг (cloaking — показывать роботу одно, пользователю другое), маскировка редиректами, навязчивая реклама/малварь.
Есть принципиально две реакции на спам, и они различаются жёсткостью, обратимостью и риском.
Код: Выделить всё
Свойство | Мягкая пессимизация (soft demotion) | Жёсткое удаление/бан (hard removal/ban)
---------------------------+-------------------------------------------------------+--------------------------------------------
Что делает | понижает ранжирующий скор на величину штрафа | полностью убирает документ/домен из выдачи
Фаза | rerank | pre-filter
Решение | непрерывное, по ML-спам-скору | дискретное, бинарное
Обратимость | автоматическая (спам-скор упал → понижение исчезло) | требует снятия бана (вручную/по апелляции)
Риск ложного срабатывания | низкий по последствиям (документ просто ниже) | высокий (честный сайт исчезает целиком)
Кого ловит | «серую зону», умеренные манипуляции | грубые, злостные, повторные нарушения
Аналогия | штрафные очки | дисквалификация
Мягкая пессимизация: спам-скор как штрафИнтуиция. Мягкая пессимизация — это реостат: чем выше уверенность в спаме, тем сильнее понижение, плавно. Жёсткий бан — это рубильник: либо в выдаче, либо нет. Реостат прощает ошибки (чуть понизил честный сайт — не катастрофа), рубильник ошибок не прощает (стёр честный сайт — потеря трафика, репутации, повод для апелляции).
Обучается классификатор spam_score(d) ∈ [0,1] — вероятность, что документ спамный (фичи: статистика текста, аномалии ссылочного профиля, поведенческие аномалии, сигналы клоакинга, история домена). Он встраивается в фазу rerank как штраф к ранжирующему скору:
Код: Выделить всё
rank_final(q, d) = rank_rel(q, d) − λ · penalty(spam_score(d))
Код: Выделить всё
penalty(s) = 0, если s < θ_low (доверяем)
= (s − θ_low)/(θ_high−θ_low), если θ_low ≤ s ≤ θ_high (серая зона, линейно)
= 1, если s > θ_high (полный штраф)
Пример. rank_rel = 8.0, spam_score = 0.9, θ_low=0.3, θ_high=0.8, λ=5. Тогда penalty=1, rank_final = 8.0 − 5·1 = 3.0 — документ проваливается с 1-го места куда-то в конец первой страницы или дальше. Если бы spam_score=0.4, то penalty=(0.4−0.3)/0.5=0.2, rank_final=8.0−1.0=7.0 — слегка ниже, но в топе остаётся. Реостат в действии.
Жёсткое удаление/бан: рубильникИнженерная заметка. Пессимизация — сигнал, а не приговор: документ остаётся в выдаче и может подняться, если спам-скор упадёт (сайт исправился, аномалия ушла). Это делает мягкий механизм самовосстанавливающимся и снижает цену ошибки. Поэтому большинство антиспам-решений начинают именно с пессимизации, а бан держат для злостных случаев.
Бан применяется в pre-filter и убирает документ/хост/домен целиком. Поводы — грубые и однозначные нарушения: malware, клоакинг, дорвеи, злостный/повторный обман, юридические требования. Решение бинарное и заносится в бан-лист (структуру для фазы pre-filter, см. 16.3).
Управление ошибками: пороги, гистерезис, апелляцииВнимание. Цена ложного бана асимметрично велика. Понизить честный сайт на пару позиций — терпимо. Стереть его целиком — это исчезновение бизнеса из поиска, поток жалоб и репутационный ущерб поисковику. Поэтому бан требует: высокого порога уверенности, по возможности — человеческой верификации для масштабных доменов, гистерезиса (см. ниже), аудит-лога причины и процедуры апелляции/снятия.
- Пороги (θ) задают баланс ошибок: высокий порог бана → меньше ложных банов (FP), но больше пропущенного спама (FN); низкий — наоборот. Калибруется по цене ошибок и A/B.
- Гистерезис (hysteresis): порог входа в санкцию строже порога выхода из неё. Иначе документ на границе будет «дребезжать» (banned/unbanned каждый апдейт), создавая нестабильную выдачу. Вошёл в бан при s>0.9 — выходишь только при s<0.6.
- Карантин/деградация перед баном: часто перед жёстким баном применяют усиленную пессимизацию как «жёлтую карточку».
- Апелляции: ручной канал пересмотра. Снятие бана — отдельное событие в аудит-логе с актёром и причиной.
SEO-врезка. Практический вывод для оптимизатора: разные нарушения наказываются по-разному. Лёгкий переспам или сомнительная ссылка → мягкая пессимизация: трафик «просел», но сайт виден, и после исправления восстанавливается (иногда автоматически, после переобхода и пересчёта спам-скора). Грубый обман (клоакинг, дорвеи, покупка ссылок промышленным масштабом) → риск жёсткого бана: сайт исчезает целиком, восстановление — через явную чистку и апелляцию, долго и негарантированно. Эвристика: чем «механистичнее» и масштабнее манипуляция, тем ближе она к рубильнику, а не к реостату.
Частые заблужденияSEO-врезка. «Сайт просел, но не исчез» и «сайт пропал полностью» — это диагностика механизма. Первое — пессимизация (работайте над качеством, чистите сигналы, ждите пересчёта). Второе — вероятный бан/фильтр (ищите грубое нарушение, готовьте апелляцию). Не путайте их: стратегии восстановления разные.
Заблуждение. «Спам — это просто нерелевантные страницы.» Наоборот: спам притворяется релевантным, поэтому и долетает до топа. Антиспам ловит не «нерелевантность» (это работа ранжирования), а манипуляцию и обман.
Заблуждение. «Если меня понизили — значит, забанили.» Пессимизация и бан — разные механизмы. Понижение обратимо и часто временно; бан — это полное удаление, требующее снятия. Путаница ведёт к неверной стратегии восстановления.
Лаба / практикаЗаблуждение. «Достаточно одного порога — спам/не спам.» Без гистерезиса выдача «дребезжит» на границе, а единый порог не различает «серую зону» (→ пессимизация) и «злостный обман» (→ бан). Нужны разные пороги для разных реакций.
Задача. Смоделировать оба механизма антиспама.
Вход: 15 документов с rank_rel и spam_score.
Шаги:
- Реализуйте penalty(s) с порогами θ_low, θ_high и пессимизацию rank_final = rank_rel − λ·penalty.
- Постройте две выдачи: только мягкая пессимизация vs мягкая + жёсткий бан при spam_score > 0.95.
- Введите гистерезис: смоделируйте 5 «эпох» с дрожащим spam_score около порога; покажите, что без гистерезиса документ скачет в выдаче, с гистерезисом — стабилен.
- Посчитайте FP/FN при двух значениях порога бана и обсудите цену ошибки.
Критерий «сделано»: вы показали самовосстановление пессимизации, необратимость бана и стабилизирующий эффект гистерезиса. Время ~70 мин.
Контрольные вопросы
- Чем спам-документ принципиально отличается от нерелевантного? Почему это меняет, какой слой системы должен с ним бороться?
- Сравните мягкую пессимизацию и жёсткий бан по обратимости и цене ошибки.
- Запишите формулу пессимизации и объясните роль λ, θ_low, θ_high.
- Что такое гистерезис и какую проблему он решает? Приведите пример «дребезга».
- Почему ложный бан опаснее ложной пессимизации? Какие меры снижают этот риск?
- По симптому «сайт просел, но виден» — какой механизм сработал? А по «сайт исчез полностью»?
- Почему пессимизация называется самовосстанавливающейся?
- Какие семейства спама вы знаете и с какими модулями курса каждое связано?
Цели обучения
После главы студент сможет:
- Классифицировать контентные фильтры (возрастные, тематические, региональные/юридические) и разместить их по фазам конвейера.
- Спроектировать бан-лист как эффективную структуру данных для pre-filter (точные и шаблонные совпадения, масштаб домена).
- Объяснить механизм safe-search и почему он применяется и в pre-filter, и в post-filter.
- Описать «песочницу» (sandbox) новых сайтов: что это, зачем, как реализуется через демпфирование молодых доменов.
- Сформулировать компромисс «осторожность к новичкам ↔ задержка хорошего нового контента».
Таксономия фильтров
Фильтр — правило, решающее «показывать ли этот документ в данном контексте». В отличие от антиспама (наказание за поведение сайта), фильтр работает по контексту запроса/пользователя и свойствам контента, а не по «вине».
Код: Выделить всё
Фильтр | По чему решает | Фаза | Действие
--------------------------+-------------------------------------------------------------------------+----------------------------+-----------------------------------------------------
Возрастной / safe-search | возрастной режим ctx.age_mode + контентная классификация документа | pre-filter и post-filter | скрыть/понизить взрослый контент вне явного запроса
Тематический | тематическая категория документа + политика (напр., опасные практики) | pre-filter | скрыть/ограничить класс тем
Региональный/юридический | регион пользователя + список изъятий по юрисдикции | pre-filter | удалить в конкретном регионе
Бан-лист | принадлежность домена/URL к списку | pre-filter | полное удаление
Бан-лист как структура данныхИнтуиция. Антиспам спрашивает «обманывает ли этот сайт»; фильтр спрашивает «уместно ли это здесь и сейчас». Один и тот же ролик может быть совершенно честным (не спам), но не показываться в детском режиме (возрастной фильтр) или быть изъят в одной стране и доступен в другой (юридический фильтр). Это политика контекста, а не наказание.
Бан-лист обслуживает фазу pre-filter и должен проверять принадлежность за O(1)/O(log) при миллионах записей, иначе он станет узким местом латентности.
- Точные совпадения (конкретный URL/домен) — хеш-множество.
- Шаблонные (поддомены *.example, паттерны путей) — префиксное дерево/набор правил.
- Уровень применения: URL / хост / домен / организация. Бан домена ≠ бан одной страницы — масштаб задаётся явно и логируется.
Safe-search: почему в двух фазахИнженерная заметка. Бан-лист — это горячие данные, реплицируемые на все ноды ранжирования и обновляемые часто (минуты), независимо от индекса и моделей. Источники записей: антиспам-решения (16.2), юридические removals, безопасность. Каждая запись несёт {scope, reason, actor, ttl} для аудита и автоматического истечения временных банов.
Возрастной фильтр применяется дважды:
- pre-filter — убрать заведомо взрослый контент до ранжирования (большинство случаев);
- post-filter — финальная проверка уже сформированного топ-k, потому что после диверсификации/реранка наверх мог всплыть пограничный документ, и потому что «пустую выдачу» после фильтрации нужно обработать фоллбэком.
«Песочница» новых сайтовВнимание. Жёсткая фильтрация может опустошить выдачу (всё отфильтровали — показывать нечего). Поэтому post-filter обязан иметь фоллбэк: смягчить режим, показать релевантное с пометкой, либо честно показать «ничего безопасного не найдено». Молча отдать пустую страницу — баг.
Механизм — демпфирование (damping) скора молодых доменов в фазе rerank, зависящее от возраста и накопленного доверия:Интуиция. У нового домена нет истории, которой можно доверять. Авторитет (Модуль 7) ещё не накопился, поведенческие сигналы (Модуль 11) скудны и легко накручиваются, а ровно новизна — любимый приём спамеров: зарегистрировал свежий домен, накрутил факторы, собрал трафик, бросил. «Песочница» (sandbox) — это период осторожности: системе невыгодно сразу полностью доверять молодому сайту.
Код: Выделить всё
trust(age) = min(1, age_days / T_sandbox) # 0 → 1 по мере «взросления»
rank_final = rank_rel · (1 − β·(1 − trust(age))) # молодой → скор приглушён
Внимание. «Песочница» — это не бан и не санкция. Сайт виден и индексируется, просто его факторы пока приглушены из-за недостатка доверия. Это демпфирование неопределённости, а не наказание за вину.
SEO-врезка. Вот почему новый сайт не вылетает в топ сразу, даже если технически безупречен и релевантен: молодой домен в «песочнице», его скор приглушён, доверие копится месяцами. Накрутка факторов в этот период особенно бесполезна — система к молодым доменам максимально недоверчива (и часто как раз накрутка выдаёт спамера). Стратегия: накапливать естественные сигналы качества и просто пережить период; форсирование чаще вредит, чем помогает.
Частые заблужденияЗаблуждение. «Меня посадили в песочницу — это санкция, надо апеллировать.» Нет: «песочница» применяется ко всем новым доменам по умолчанию, это не наказание за нарушение, а осторожность к отсутствию истории. Апеллировать не к чему — нужно накапливать доверие временем и качеством.
Заблуждение. «Фильтр и антиспам — одно и то же.» Антиспам наказывает за манипуляцию (вина сайта); фильтр решает уместность в контексте (возраст, регион, тема) безотносительно вины. Честный сайт может быть отфильтрован, спамный — нет (если контекст не запрещает).
Заблуждение. «Бан-лист можно держать в индексе/в базе и проверять по запросу.» Бан-лист — горячие данные на критическом пути латентности; он реплицируется на ноды и проверяется за O(1). Поход в базу за каждый запрос убьёт бюджет (Модуль 12).
Лаба / практикаЗаблуждение. «Если фильтр всё убрал, покажем пустую страницу.» Пустая выдача после фильтрации — это случай для фоллбэка, а не баг «нет результатов». Post-filter обязан его обработать.
Задача. Реализовать фильтры и «песочницу».
Вход: 20 документов {id, host, domain_age_days, adult_score, region_blocklist} и ctx={age_mode, region}.
Шаги:
- Постройте бан-лист как хеш-множество + префиксные правила; реализуйте pre-filter.
- Реализуйте safe-search в pre-filter и post-filter с фоллбэком на пустую выдачу.
- Реализуйте sandbox-демпфирование rank_final = rank_rel·(1−β(1−trust(age))); постройте кривую «позиция нового домена vs возраст» при T_sandbox=120 дней.
- Покажите, что молодой релевантный домен поднимается постепенно, а не сразу.
Критерий «сделано»: видно различие фильтра и санкции; кривая sandbox монотонно растёт к снятию демпфирования; фоллбэк не отдаёт пустую страницу. Время ~60 мин.
Контрольные вопросы
- Чем фильтр отличается от антиспам-санкции по основанию решения?
- Почему safe-search применяется и в pre-filter, и в post-filter?
- Какие структуры данных нужны бан-листу и почему он не может жить «в базе по запросу»?
- Что такое «песочница» и почему это демпфирование неопределённости, а не наказание?
- Запишите формулу sandbox-демпфирования и объясните роль β и T_sandbox.
- Почему накрутка факторов особенно бесполезна для домена в «песочнице»?
- Что должен делать post-filter, если фильтры опустошили выдачу?
Цели обучения
После главы студент сможет:
- Объяснить, какие классы запросов наиболее уязвимы к манипуляции и почему (коммерческие/денежные, YMYL).
- Сформулировать механизм anti-SEO reset: принудительное обнуление блока манипулятивных факторов (в первую очередь ссылочных) на стадии скоринга для этих классов.
- Связать это с теорией графа авторитета (Модуль 7) и поведенческих сигналов (Модуль 11): почему накрутка не окупается.
- Сравнить anti-SEO reset с пессимизацией (16.2): это не наказание конкретного сайта, а отключение целого класса факторов для класса запросов.
- Оценить компромисс: устойчивость к манипуляции ↔ потеря полезного сигнала.
Где манипуляция выгоднее всего — там и бьём
Особо уязвимы:Интуиция. Манипулировать факторами имеет смысл там, где за позицию платят деньги. На коммерческих («денежных») запросах — купить X, заказать Y, кредиты, юристы, медицина — первая страница стоит реального дохода, поэтому именно здесь концентрируется индустрия накрутки: покупка ссылок, ссылочные фермы, накрутка кликов. На запросе теорема Пифагора накручивать ссылки экономически бессмысленно. Значит, и защита должна быть сильнее именно там, где сильнее атака.
- Коммерческие / транзакционные / «денежные» запросы — прямая монетизация позиции.
- YMYL (Your Money or Your Life) — здоровье, финансы, право: цена дезинформации высока.
Главная мысль: anti-SEO reset — принудительное обнуление блока факторов
Стандартная защита (пессимизация, 16.2) наказывает конкретный сайт по его спам-скору — но требует поймать манипуляцию, что не всегда возможно (хорошо замаскированную ссылочную накрутку отличить от естественных ссылок трудно). Для уязвимых классов применяется радикально иной приём.
Формально. Пусть ранжирующий скор — линейная (или сепарабельная) комбинация блоков факторов:Главная мысль курса. Если целый блок факторов (ссылочный, манипулятивно-поведенческий) на данном классе запросов легко накручивается и плохо отличим от честного, система может просто перестать его использовать на этом классе — принудительно обнулить его вклад в скоринг. Это и есть anti-SEO reset: не «понизить накрученный сайт», а «для денежных запросов вообще не считать ссылочные/манипулятивные факторы».
Код: Выделить всё
score(q, d) = w_text · f_text(q,d)
+ w_link · f_link(d) ← манипулируемый блок (граф авторитета, Модуль 7)
+ w_behav · f_behav(q,d) ← манипулируемый блок (поведение, Модуль 11)
+ w_quality · f_quality(d)
+ …
Код: Выделить всё
если ctx.query_class ∈ {commercial, ymyl}:
w_link := 0 # ссылочные факторы НЕ влияют на скоринг
w_behav := 0 # манипулятивно-поведенческие — тоже (или сильно урезаны)
# остаются: текстовая релевантность, сигналы качества контента,
# коммерческие сигналы (ассортимент, доверие магазина, отзывы вне накрутки)
Почему это работает там, где пессимизация буксуетИнтуиция. Это как судья, который на «подозрительной» дисциплине объявляет: «вид баллов, который слишком легко подделать, в этом зачёте не считается вообще». Не «вычтем у подозрительных» — а «у всех в этой дисциплине этот вид баллов = 0». Накручивать его теперь бессмысленно для всех: вклад нулевой по построению, независимо от того, поймали тебя или нет.
Пессимизация требует обнаружения: посчитать spam_score, превысить порог, понизить. Хорошо замаскированная ссылочная накрутка обнаружение обходит — её трудно отличить от органического роста ссылок. Anti-SEO reset снимает зависимость от обнаружения: если фактор обнулён, его не нужно «ловить» — он просто не влияет.
Код: Выделить всё
| Пессимизация (16.2) | Anti-SEO reset (16.4)
----------------------------------+---------------------------+----------------------------------------------------
Объект | конкретный сайт | целый блок факторов на классе запросов
Требует обнаружения манипуляции? | да (спам-скор > порог) | нет — фактор обнулён всем
Что делает | понижает скор виновного | убирает фактор из формулы для класса
Кого затрагивает | подозрительных | всех на уязвимом классе (и честных, и накрутчиков)
Цена | риск ложного наказания | потеря полезного сигнала (см. компромисс)
SEO-врезка (ключевая для всего курса). Вот почему массовая закупка ссылок не двигает коммерческий сайт в топ. Дело не (только) в том, что вас «поймают и понизят» (хотя и это: пессимизация, 16.2). Дело в том, что на денежных запросах ссылочный блок факторов может быть принудительно обнулён на скоринге — w_link = 0. Вы платите за ссылки, граф авторитета (Модуль 7) пересчитывается, ваш PageRank-подобный вес растёт — и не влияет на позицию ни на йоту, потому что этот вход в формулу для данного класса запросов помножен на ноль. Деньги потрачены, эффект — нулевой по построению формулы, а не из-за поимки. То же с накруткой поведения (Модуль 11): w_behav := 0 обессмысливает накрутку кликов на этих запросах.
SEO-врезка. Отсюда — стратегический вывод: на коммерческих запросах инвестируйте в то, что НЕ обнуляется — текстовую релевантность и соответствие интенту (Модуль 6), реальные сигналы качества (ассортимент, цены, удобство, доверие, реальная экспертиза для YMYL), скорость и техническое здоровье. Ссылочное продвижение для денежных тематик — это часто выброшенный бюджет: даже честно заработанные ссылки на этих классах могут не учитываться. Проверка гипотезы: если рост ссылочной массы не двигает позиции по коммерческим запросам месяцами при прочих равных — вероятно, вы упёрлись в reset.
Это не «понижение», а изменение формулы для классаЗаблуждение. «Ссылки всегда помогают ранжированию.» На уязвимых классах запросов ссылочный блок может быть обнулён — тогда ссылки не помогают вообще, ни хорошие, ни плохие. «Помогают ли ссылки» — вопрос, зависящий от класса запроса, а не универсальная истина.
Внимание. Принципиальное отличие от антиспама: anti-SEO reset не наказывает конкретный сайт и не зависит от его «вины». Он меняет саму функцию ранжирования для целого класса запросов — у всех участников этого класса манипулируемый блок весит ноль. Честный сайт с органическими ссылками тоже их «не получает» в зачёт на денежных запросах. Это сознательная плата за устойчивость (см. компромисс).
Компромисс: устойчивость против потери сигналаИнженерная заметка. Технически reset реализуется как правило фазы rerank (или как переключение профиля ранжирования под класс запроса, мост к Модулю 12.3): для запросов с флагом commercial/ymyl активируется конфигурация весов с занулённым ссылочным/поведенческим блоком. Это конфиг, а не переобучение — включается/выключается и тестируется через A/B-хуки (16.1).
Обнуление блока — не бесплатно. Ссылочные и поведенческие факторы несут реальную информацию о качестве (Модуль 7, 11); выключив их, мы теряем полезный сигнал и можем чуть просесть по релевантности на честной части корпуса.
Интуиция компромисса. Это рациональный размен: на классе, где сигнал настолько зашумлён манипуляцией, что доверять ему нельзя, лучше отказаться от него целиком, чем пытаться отделить честное от накрученного и постоянно проигрывать гонку вооружений накрутчикам. Цена — потеря части честного сигнала; выигрыш — манипуляция перестаёт окупаться в принципе, что подрывает экономику накрутки. Если накрутка не даёт результата, в неё перестают вкладываться — и выдача оздоровляется системно.
Частые заблужденияИнженерная заметка. Решение «обнулять или нет» принимается по классу запроса и по A/B: измеряют качество выдачи и долю манипулятивного спама в топе при w_link>0 и w_link=0. Если выключение блока не роняет (или улучшает) качество на денежных запросах за счёт вытеснения накрутки — reset включают. Это эмпирическое, измеряемое решение, а не догма.
Заблуждение. «Меня не поймали на закупке ссылок — значит, они работают.» На денежном классе ссылочный блок может быть обнулён независимо от поимки — «не поймали» не значит «учли». Эффект может быть нулевым по построению формулы.
Заблуждение. «Anti-SEO reset — это просто сильная пессимизация.» Нет. Пессимизация понижает виновный сайт после обнаружения. Reset обнуляет блок факторов для класса запросов у всех, без обнаружения. Разные механизмы, разные объекты, разная зависимость от детекции.
Лаба / практикаЗаблуждение. «Раз ссылки могут не учитываться — графовые факторы (Модуль 7) бесполезны.» Они полезны на неуязвимых классах (информационные, навигационные) и для других задач (обход, краулинг, обнаружение). Reset — точечная мера для уязвимых классов, а не отмена теории авторитета.
Задача. Смоделировать anti-SEO reset и его эффект на накрутку.
Вход: 12 документов с блоками факторов {f_text, f_link, f_behav, f_quality} и веса {w_text, w_link, w_behav, w_quality}. Пометьте 3 документа как «накрутчиков» (искусственно высокий f_link, f_behav при среднем f_quality).
Шаги:
- Посчитайте score и ранжируйте при обычных весах — убедитесь, что накрутчики в топе.
- Примените reset для класса commercial: w_link:=0, w_behav:=0; пересчитайте и переранжируйте.
- Сравните позиции накрутчиков до/после; покажите, что их преимущество исчезло без всякого обнаружения.
- Оцените «потерю сигнала»: как сместились позиции честных сайтов с органически высоким f_link.
- (Доп.) Сравните с чистой пессимизацией: что будет, если накрутка не обнаружена (spam_score низкий)?
Критерий «сделано»: вы показали, что reset нейтрализует накрутку без детекции и ценой частичной потери честного сигнала; объяснили, почему пессимизация при необнаруженной накрутке бессильна, а reset — нет. Время ~75 мин.
Контрольные вопросы
- Какие классы запросов наиболее уязвимы к манипуляции и почему именно они?
- Сформулируйте механизм anti-SEO reset в терминах весов блоков факторов.
- Чем reset принципиально отличается от пессимизации по объекту и по зависимости от обнаружения?
- Почему массовая закупка ссылок не двигает коммерческий сайт в топ — дайте объяснение через формулу, а не только через «поймают».
- В чём компромисс anti-SEO reset? Что мы теряем, обнуляя блок?
- Почему графовые факторы (Модуль 7) не становятся «бесполезными» из-за reset?
- Как технически включается reset и почему это «конфиг, а не переобучение»?
- Как эмпирически решить, стоит ли обнулять ссылочный блок на данном классе запросов?
- Постранжирование — отдельный декларативный слой между ранжированием и выдачей. Ранжирование отвечает «насколько релевантно», постранжирование — «должны ли и в каком виде показывать». Смешивать их в одной формуле опасно.
- Фреймворк правил (rearrange) — это реестр правил + конвейер фаз (pre-filter → rerank → diversify → trim → annotate → post-filter). Порядок фаз критичен (правила некоммутативны), каждое действие пишется в аудит-лог, поведение задаётся версионируемым конфигом под профиль/класс запроса, а каждое правило снабжено A/B-хуком.
- Антиспам ловит манипуляцию, а не нерелевантность: спам опасен именно тем, что притворяется релевантным и лезет в топ.
- Два механизма наказания: мягкая пессимизация (понижение скора по ML-спам-скору; реостат; обратима, самовосстанавливается) и жёсткий бан/удаление (рубильник; необратим без снятия; цена ложного срабатывания асимметрично велика). Управляются порогами, гистерезисом и апелляциями.
- Фильтры решают уместность в контексте (возраст, регион, тема), а не вину сайта; бан-лист — горячая O(1)-структура на критическом пути; safe-search работает в двух фазах и обязан иметь фоллбэк на пустую выдачу.
- «Песочница» — демпфирование скора молодых доменов из-за недостатка истории и доверия; это не санкция, а осторожность к неопределённости. Поэтому новый сайт не вылетает в топ сразу, и накрутка в этот период особенно бесполезна.
- Кульминация — anti-SEO reset: для коммерческих/денежных и YMYL-запросов система может принудительно обнулить блок манипулятивных факторов (w_link:=0, w_behav:=0) прямо на скоринге. Это не наказание сайта, а изменение формулы для класса запросов, не требующее обнаружения манипуляции.
- Почему накрутка не работает (связь с Модулями 7 и 11): на денежных запросах ссылочный/поведенческий вклад может быть помножен на ноль — закупленные ссылки и накрученные клики не двигают позицию по построению формулы, а не из-за поимки. Цена устойчивости — частичная потеря честного сигнала; выигрыш — подрыв экономики накрутки.
- Постранжирование (post-ranking, rearrange) — слой обработки выдачи после ранжирования: перестановки, понижения, удаления, пометки, фоллбэки.
- Правило (rule) — чистое преобразование выдачи с предикатом активации, фазой и обязательной записью в аудит-лог.
- Фаза (phase) — упорядоченная группа правил (pre-filter, rerank, diversify, trim, annotate, post-filter); порядок фаз определяет результат.
- Реестр правил (registry) — место регистрации всех правил; код пишется один раз.
- Профиль постранжирования — декларативная конфигурация «какие правила, в каких фазах, с какими параметрами» под класс запроса/эксперимент.
- A/B-хук — механизм включения/выключения правила по эксперименту для измерения его эффекта без релиза.
- Shadow-режим — подсчёт того, что правило сделало бы, без применения к пользователю.
- Аудит-лог решений — структурированная запись {rule, doc_id, action, reason, delta} каждого изменения выдачи.
- Спам выдачи — документ, искусственно выглядящий релевантным/качественным, чтобы обмануть факторы и пролезть в топ.
- Спам-скор (spam_score) — выход классификатора вероятности спама, используемый как штраф в rerank.
- Мягкая пессимизация (soft demotion) — непрерывное понижение скора по спам-скору; обратима, самовосстанавливается («реостат»).
- Жёсткий бан/удаление (hard removal) — полное изъятие документа/домена из выдачи в pre-filter («рубильник»); необратим без снятия.
- Гистерезис (hysteresis) — разные пороги входа и выхода санкции, гасящие «дребезг» выдачи на границе.
- Фильтр контента — правило об уместности показа по контексту (возраст, регион, тема), а не по вине сайта.
- Safe-search — возрастная фильтрация контента; применяется в pre-filter и post-filter.
- Фоллбэк (fallback) — обработка опустошённой фильтрами выдачи (смягчить режим / пометить / честно сообщить).
- Бан-лист — горячая O(1)/O(log) структура принадлежности домена/URL для pre-filter с полями {scope, reason, actor, ttl}.
- «Песочница» (sandbox) — демпфирование скора молодых доменов из-за недостатка истории/доверия; не санкция.
- Доверие домена (trust) — функция возраста и независимых сигналов качества, снимающая sandbox-демпфирование.
- Anti-SEO reset — принудительное обнуление весов манипулируемых блоков факторов (ссылочного, поведенческого) на скоринге для уязвимых классов запросов.
- Уязвимый класс запросов — коммерческие/«денежные» и YMYL-запросы, где манипуляция выгодна и потому концентрируется.
- YMYL (Your Money or Your Life) — запросы о здоровье/финансах/праве, где цена дезинформации высока.
- Опирается на: Модуль 12 (каскад: постранжирование — продолжение фазы L3; профиль ранжирования под класс запроса — общий механизм с reset); Модуль 19 (A/B-инфраструктура и метрики: как тестируют и настраивают правила, пороги, reset); Модуль 15 (группировка/диверсификация — фаза diversify живёт здесь же).
- Использует результаты: Модуль 5 (классификация интента: флаги commercial/ymyl/adult включают нужные правила и профили); Модуль 7 (граф авторитета — манипулируемый ссылочный блок, обнуляемый в reset); Модуль 11 (поведенческие сигналы — манипулируемый поведенческий блок); Модуль 6 (текстовая релевантность — фактор, который reset не трогает).
- Питает дальше: движок выдачи (финальный список и пометки); Модуль 19 (наблюдаемые эффекты правил замыкаются на метрики и эксперименты).
- Кульминационная связь: 16.4 объясняет «обратную сторону» Модулей 7 и 11 — почему накрутка графовых и поведенческих факторов не окупается на уязвимых классах запросов: фактор может быть обнулён на скоринге, а не просто «понижен после поимки».
- Классические работы по веб-спаму и адверсариальному IR (web spam taxonomy, adversarial information retrieval): контентный, ссылочный, клоакинг, дорвеи.
- Обзоры по обнаружению ссылочного спама и спам-фермам, устойчивости графовых мер авторитета к манипуляции (Модуль 7).
- Литература по обнаружению накрутки поведенческих сигналов и устойчивым клик-моделям (Модуль 11).
- Материалы по архитектуре конвейеров постобработки и системам декларативных правил с аудитом и фичефлагами/экспериментами.
- Работы по компромиссу робастность/качество ранжирования: цена отказа от манипулируемых факторов, адверсариальная устойчивость функции ранжирования.
- Обзоры по safe-search, контентной классификации и политикам выдачи; принципы «песочницы» и демпфирования доверия для новых источников.