В наивной модели поиска есть одна формула ранжирования, и она применяется ко всему. На практике так не бывает: запрос про последние новости и запрос про купить холодильник имеют принципиально разную природу релевантности. Для первого критична свежесть, для второго - коммерческая полнота и доверие к источнику. Поэтому в рантайме выдачи (то, что в утечке лежит под search/, срез примерно 2022 года) есть отдельная подсистема, которая по характеристикам запроса и документа выбирает, какой именно обученной моделью считать L2 и L3. Эта подсистема - formula_chooser.
Сразу разделим две вещи, которые часто путают. Робот (краулинг плюс индексация) строит каноничный документ и документную сторону факторов. Но сам выбор формулы и самые весомые сигналы для скоринга живут не в роботе, а в рантайме формирования выдачи. Ниже это будет видно предметно.
formula_chooser: контекст как набор булевых флаговКлючевой тезис: робот дает носитель и документную сторону, а вес выдаче придают рантайм-факторы (поведение и нейро query-doc), которых в роботе физически нет.
Механика сосредоточена в formula_chooser. Контекст пары запрос плюс документ кодируется булевыми входными флагами EInputFlag. Это не числа, а именно бинарные признаки ситуации.
Код: Выделить всё
metadata: formula_chooser/metadata/metadata.proto
применение: formula_chooser/ruleset_applier.h
маппинг: mappings.proto.txt
EInputFlag (фрагмент):
F_IS_FRESH_DETECTED запрос распознан как свежий
F_IS_PORNO взрослый контур
F_IS_TOUCH_UI мобильный или touch интерфейс
F_IS_ALICE запрос пришел из Алисы
F_IS_RELEV_LOCALE_* локали и язык релевантности
F_HAS_CONSTRAINTS есть наложенные ограничения
Код: Выделить всё
сработавший кейс = (все флаги AndRequire истинны)
И (ни один флаг AndRequireNot не истинен)
Код: Выделить всё
L2Formula формула стадии L2
L3Formula формула стадии L3
PersFormula персонализационная формула
L3BoostGraph граф бустинга на L3
Код: Выделить всё
mappings.proto.txt (реальные строки):
V_DEFAULT_L2 FmlId "847322"
V_BERT_OPT_L3 FmlId "830031"
V_DEFAULT_L2_ITDITP FmlId "802161"
- Запрос свежий и touch: уходит на V_FRESH_L2 и V_FRESH_L3. Приоритет на новизну, отдельная мобильная формула.
- Коммерческий или обычный запрос: V_DEFAULT_L2 на второй стадии плюс V_BERT_OPT_L3 на третьей. То есть тяжелая трансформерная формула включается именно на L3, где документов уже мало и можно позволить себе дорогой скоринг.
Факторы материализуются через владельца хранилищ TFactorStoragesOwner (rank/factor_storages_owner.h). Он отдает слайсы TFactorStorage по стадиям через GetForL1 и GetForL2 по docId. Тяжелые признаки L2 и L3 считаются отдельно буферизованным калькулятором.
Код: Выделить всё
TFactorStoragesOwner rank/factor_storages_owner.h
GetForL1(docId) слайс факторов L1
GetForL2(docId) слайс факторов L2
TBufferedRelevanceCalcer rank/docalc_docrelev.h
CalcHeavyL2Features
CalcHeavyL3Features
Код: Выделить всё
каталоги моделей: search/formula/{default,webbase,webcommon}/
селектор: formula/webcommon/select_ranking_models.cpp
SelectWebByRankModel
суффиксы файлов модели кодируют контур:
.hast L1
.fast L2
.touch мобильный контур
.porno взрослый контур
.regional региональный
.eng английская локаль
Рантайм-факторы, которых нет в роботе
Это центральная часть разбора. Ниже подсистемы, которые подмешивают в итоговый скор сигналы, отсутствующие в роботе как таковые. Именно они, а не статические документные признаки, несут основной вес.
Код: Выделить всё
lingboost lingboost/production/web_production_features_calcer.h
TextMachine-фичи: шинглы, покрытие n-gram, специфичность термов.
Результат уходит через SaveFeatures в TFactorView. Рантайм-T.
dssm_boosting dssm_boosting/dssm_boosting_calcer.h, factors_setter.h
Нейросетевая близость query и doc. Модели семейства
BoostingXfWtd / XfOne / Ctr / SerpSimilarity, по 5-6 скоров на модель,
раскладываются в слоты FI_DSSM_BOOSTING_*. Рантайм-T.
knnboost knnboost/proto/service_protocol.proto
KNN по эмбеддингам, построенным на dwell-time:
CosineDistanceByLogDwellTimeBigrams. Поведенческо-нейро сигнал.
rapid_clicks rapid_clicks_common/misc.h (TRtmrResponseParser)
Near-realtime клики из BigRT. Агрегации по разным ключам:
QueryDopp / QueryDoppRegion / Url / Owner / User,
decay-счетчики за N дней, метрики RC_WINS* и CTR в TFactorView.
Чистое поведение, класс B.
boost_condition boost_condition/boost_calculator.h
IArgument, TBoostCalculator::Calc.
Условные множители к скору по выражениям над свежестью,
регионом, категорией. Выражения парсятся в дерево аргументов,
есть интеграция с Lua.
lingboost - это рантайм-текстовые фичи на базе TextMachine. Робот может хранить текст документа, но покрытие n-gram и специфичность считаются относительно конкретного запроса, а значит только в рантайме.
dssm_boosting дает нейросетевую близость пары запрос-документ. Документная сторона эмбеддинга может быть подготовлена заранее, но само сопоставление с эмбеддингом запроса и набор скоров FI_DSSM_BOOSTING_* возникают только при обработке запроса.
knnboost показателен тем, что эмбеддинги построены на логарифме dwell-time: близость документов определяется не их текстом, а тем, как на них задерживаются пользователи. Это уже наполовину поведенческий сигнал, упакованный в геометрию векторов.
rapid_clicks - наиболее очевидный поведенческий блок. Клики берутся почти в реальном времени из BigRT, агрегируются по запросу, региону, URL, владельцу и пользователю, с затуханием за N дней. В роботе таких данных нет в принципе - это поток событий выдачи.
boost_condition - это уже не фактор, а механизм условных множителей поверх скора, управляемый выражениями (свежесть, регион, категория) вплоть до Lua.
Что из этого следует для SEOИтог по весам: самые весомые сигналы - поведение (класс B) и рантайм-нейро (класс T) - физически вычисляются в рантайме выдачи. Робот к ним отношения не имеет: он поставляет лишь каноничный документ-носитель и документную сторону эмбеддинга. Это эмпирически подтверждает наблюдение из разбора робота о том, где сосредоточен реальный вес ранжирования.
- Под разные классы запросов работают разные формулы. Оптимизация под коммерческий запрос (контур V_DEFAULT_L2 плюс V_BERT_OPT_L3) и под свежий запрос (V_FRESH_L2/L3) - это разные задачи, и одна стратегия не покрывает обе.
- Мобильный и взрослый контуры обслуживаются отдельными моделями (.touch, .porno), то есть поведение выдачи на этих срезах независимо от десктопа.
- Основной вес дают сигналы, которые нельзя положить на страницу заранее: клики rapid_clicks, dwell-time в knnboost, нейро-близость dssm_boosting. Текст и структура документа - это входной билет, но решает рантайм-поведение и семантическое соответствие запросу.
Дисклеймер: материал основан на утечке исходников, срез примерно 2022 года. Имена флагов, переменных, FmlId и пороги могли смениться. Любые упоминания весов иллюстративны - реальные веса обучаемы и проприетарны. Это реконструкция архитектуры по коду, а не официальная документация.