Этот разбор - про рантайм. Не про то, как робот обходит и индексирует сайт (это отдельный слой про краулинг и построение индекса), а про то, что происходит уже на горячем пути: пришёл HTTP-запрос с text=, p=, numdoc= - и через считанные десятки миллисекунд назад уезжает готовый JSON выдачи. Материал - срез исходников каталога search/ из известной утечки, ориентировочно состояние ~2022. Имена компонентов, правил и факторов реальны, но пороги и веса со временем менялись, а конкретные значения весов обучаемы и проприетарны - в тексте они иллюстративны.
Главный тезис, который стоит зафиксировать сразу.
Каскад целикомФакторы (включая робото-статику вроде статического ранга и антиспам-сигналов) считаются на стадиях ранжирования L1/L2/L3. А вот порядок и состав видимого топа определяет уже не сам скоринг, а слой rearrange и blender, который работает поверх готовых оценок. Это два разных мира: оценить документ и собрать страницу - не одно и то же.
Код: Выделить всё
HTTP-запрос (text=..., p=, numdoc=)
|
v ВЕРХНИЙ МЕТАПОИСК (search/daemons/httpsearch, search/meta)
+- formula_chooser: InputFlags(запрос+док) -> RuleSet -> FmlId
| выбор формул для L2/L3, персонализации, BoostGraph
+- scatter к источникам (web / news / images / video / колдунщики)
|
v БАЗОВЫЙ ПОИСК (search/base_search, panther) -- L0/L1
+- decompose запроса -> ключи Panther -> обратный индекс -> кандидаты
+- embedding_storage: DSSM dot-product query/doc + attribute-фильтры
+- L1-факторы (TextMachine / BM15 / покрытие) -> MatrixNet L1 -> topN
+- pruning: статический ранг (anti-spam / nav-boost)
|
v СРЕДНИЙ МЕТАПОИСК (search/meta/merge)
+- union-merge группировок, host-collapsing (NumDocsInGroup), дедуп URL
|
v РАНЖИРОВАНИЕ (search/rank, formula, *boost) -- L2/L3
+- L2: тяжёлые факторы (lingboost / dssm_boosting / knnboost
| / rapid_clicks) -> GBDT
+- L3: свежесть / гео / разнообразие / персонализация -> финал + бусты
|
v REARRANGE + BLENDER (search/web/rearrange, web/blender) -- 380 правил
+- фазы: AfterSearch -> AfterMetaFeatures -> AfterMetaRank
| -> AfterMerge -> Before/AfterFetch
+- antidup / antispam / antiseo_reset_factors / fresh
| / ungroup_vital / host_presence / trash / porno ...
+- blender: вертикали, serp_resolver, dup_cleaner
+- adjust_serp_size: стр.=10 / последняя=24 / макс 259 док.
|
v REPORT (search/report)
+- TMetaGrouping -> protobuf TReport -> JSON SERP
Запрос приходит в демон httpsearch (search/daemons/httpsearch, search/meta). Первое содержательное действие - не поиск, а выбор стратегии. Компонент formula_chooser берёт набор признаков запроса и кандидата (InputFlags - язык, регион, коммерческость, навигационность, длина, наличие колдунщиков и так далее), прогоняет их через RuleSet и выдаёт FmlId - идентификатор формулы, которая будет применяться на L2/L3, плюс выбор персонализационной модели и графа бустов (BoostGraph).
Дальше верхний метапоиск делает scatter - разбрасывает запрос по источникам параллельно: основной веб-индекс, новости, картинки, видео, объектные ответы (колдунщики). Каждый источник - свой кластер базового поиска.Ключевой момент: разные классы запросов ранжируются разными формулами. Навигационный запрос, свежий новостной и широкий коммерческий уезжают по разным веткам ещё до того, как базовый поиск вернул кандидатов. Поэтому одна и та же страница в разных запросах оценивается принципиально по-разному.
Базовый поиск (L0/L1): panther, обратный индекс и dot-product
Самый нагруженный слой. Запрос декомпозируется на ключи Panther, по обратному индексу поднимаются документы, содержащие нужные термы - это text_hits, сырые кандидаты. На этой же стадии работает embedding_storage: считается dot-product между DSSM-эмбеддингом запроса и предпосчитанными эмбеддингами документов, плюс отсекаются кандидаты по attribute-фильтрам (язык, регион, тип контента).
Код: Выделить всё
L0 поднять кандидатов из обратного индекса (text_hits)
L1 лёгкие текстовые факторы:
TextMachine - близость/порядок/полнота вхождений
BM15 - вариант BM25 без длины документа
покрытие - доля терминов запроса в документе
DSSM dot - семантическая близость query/doc
MatrixNet L1 -> отобрать topN
pruning: статический ранг, anti-spam, nav-boost
Средний метапоиск: слияние и схлопывание хостов
Ответы источников и шардов сходятся в search/meta/merge. Здесь происходит union-merge группировок, дедупликация по URL и host-collapsing: документы одного хоста сворачиваются в группу, число в группе - NumDocsInGroup. Это уже подготовка к тому, чтобы один сайт не занял половину выдачи - но окончательное решение про присутствие хостов примет позже rearrange.
Ранжирование L2/L3: тяжёлые факторы и GBDT
На отобранном topN включаются дорогие факторы - те, что незачем считать по миллионам документов.
Код: Выделить всё
L2 тяжёлые факторы по выбранной FmlId:
lingboost - лингвистическое соответствие, расширения запроса
dssm_boosting - набор нейросетевых семантических моделей
knnboost - близость в пространстве эмбеддингов (kNN)
rapid_clicks - быстрые поведенческие сигналы
-> GBDT (градиентный бустинг, дерево формулы FmlId)
L3 финальная доводка:
freshness - свежесть документа/запроса
geo - гео-релевантность
diversity - разнообразие по интенту
pers - персонализация (история, регион, профиль)
-> итоговый скор + бусты (BoostGraph)
Rearrange и blender: где скоринг перестаёт быть главнымДо этого момента всё, что произошло, - это присвоение документам чисел. Никакого SERP ещё нет. Список, отсортированный по финальному скору L3, - это сырой материал, а не выдача.
Самый недооценённый слой. search/web/rearrange - это конвейер из порядка 380 правил, применяемых фазами по ходу всего каскада:
Код: Выделить всё
AfterSearch сразу после базового поиска
AfterMetaFeatures после расчёта мета-факторов
AfterMetaRank после L2/L3 ранжирования
AfterMerge после слияния источников
BeforeFetch перед подтягиванием сниппетов
AfterFetch после подтягивания
- antidup, dup_cleaner - убирают дубли и почти-дубли;
- antispam, trash, porno - выкидывают спам, мусор, взрослый контент из общей выдачи;
- antiseo_reset_factors - обнуляет/гасит факторы документам с признаками SEO-накрутки. Это прямой удар по переоптимизированным факторам уже после скоринга;
- fresh - подмешивает свежие документы туда, где интент того требует;
- ungroup_vital - разворачивает группу хоста, если витальный (главный) документ должен быть показан явно;
- host_presence - финально ограничивает присутствие одного хоста в топе (то самое продолжение host-collapsing).
Report: упаковка результатаПрактический вывод для оптимизатора. Можно идеально отыграть текстовые и поведенческие факторы и получить высокий скор на L3 - и всё равно не попасть в видимый топ, потому что host_presence ограничил хост, antiseo_reset_factors погасил накрученные факторы, а blender отдал две верхние позиции вертикали. Топ - это не argmax по скору, это результат прогона скоринга через 380 правил пересборки.
Финал - search/report. Пересобранный список превращается в TMetaGrouping, сериализуется в protobuf-структуру TReport и отдаётся наружу как JSON. Это уже не ранжирование, а форматирование: позиции, группировки, сниппеты, метаданные вертикалей в том виде, в котором их получит фронтенд и пользователь.
Итог
Горячий путь делится на две принципиально разные половины. Первая - оценка: formula_chooser выбирает формулу, panther и обратный индекс дают кандидатов, L1 грубо отсекает, L2/L3 досчитывают тяжёлые факторы и GBDT выдаёт финальный скор; робото-статика (статический ранг, антиспам) тут работает как фактор и как pruning. Вторая половина - сборка: rearrange своими 380 правилами и blender перекраивают отсортированный список в реальный SERP, и именно здесь решается состав и порядок видимого топа. Разделять эти слои в голове критично: оптимизируя факторы, вы влияете на скор, но не управляете правилами пересборки - а видит пользователь именно результат пересборки.
Дисклеймер: срез ~2022, имена компонентов, правил и пороги могли смениться; веса и значения иллюстративны, реальные обучаемы и проприетарны.
Разборы по этапам выдачи
- Базовый поиск L0/L1, panther, pruning: viewtopic.php?t=1850
- Ранжирование L2/L3 и выбор формулы: viewtopic.php?t=1851
- Сборка SERP: host-collapsing, blender, потолок 259: viewtopic.php?t=1852
- Rearrange: 380 переранжирований: viewtopic.php?t=1853
- AntiSeoResetFactors (обнуление ссылок на коммерции): viewtopic.php?t=1854
Данные (xlsx, разбор выдачи по листам):
images/data/SERP_RANKING_ANALYSIS.xlsx