Когда разбираешь товарную вертикаль Яндекса по исходникам (дерево ya/extsearch/goods), быстро упираешься в простую вещь: для товарной выдачи мало быть релевантным запросу. Оффер должен быть покупаемым прямо сейчас и доставляемым в регион пользователя. Поэтому в реестре факторов (factors_meta_gen.in, 3144 фактора, Index 0..3143) есть отдельная плотная группа сигналов про наличие, способ доставки, её цену и сроки. Я выдрал их грепом из реестра и прошёлся по тегам каждого. В этом треде разбираю именно эту группу.
Сразу дисклеймер, чтобы потом не было вопросов.
Что нашлось в кодеЭто разбор по исходному коду товарной вертикали goods, а не официальная формула Яндекс.Маркета. Ранжируют скомпилированные CatBoost/MatrixNet-модели (в ya/extsearch/goods/data/formulas), это деревья решений - у факторов НЕТ статических процентных весов. Любые оценки силы сигнала ниже - качественная реконструкция, а не "фактор весит N процентов".
Греп по реестру (ONSTOCK|STOCK|DELIVERY|COURIER|PICKUP|HAS_STORE) выдаёт довольно стройную картину. У большинства сигналов есть зеркальная пара FI_* - это та же фича, просто feature-importance/нормализованный вариант, по сути дубликат для другого среза, отдельным фактором его не считаю.
Ключевое наблюдение по тегам: почти вся группа висит на TG_DELIVERY и одновременно на TG_TEXT_PLACE и TG_MODEL_OFFER_PLACE. То есть это сигналы и для текстовой товарной выдачи, и для карточки модели с офферами. Ни одного TG_DEPRECATED/TG_UNUSED в группе наличия и доставки я не нашёл - вся пачка живая. Это само по себе говорит о том, что блок логистики Маркет считает рабочим, а не легаси.
Код: Выделить всё
ФАКТОР TAGS (как в реестре) СМЫСЛ
--------------------------------- -------------------------------------------------------- ---------------------------
OFFER_IS_ONSTOCK TG_BASE, TG_MODEL_OFFER_PLACE оффер в наличии (да/нет)
HAS_STORE TG_BASE, TG_TEXT_PLACE, TG_MODEL_OFFER_PLACE, TG_DELIVERY есть точка/магазин
DELIVERY_EMPTY TG_BASE, TG_TEXT_PLACE, TG_MODEL_OFFER_PLACE, TG_DELIVERY данных о доставке нет
DELIVERY_NO ... TG_DELIVERY доставки нет вообще
DELIVERY_OFF ... TG_DELIVERY доставка отключена
DELIVERY_FREE ... TG_DELIVERY доставка бесплатна
DELIVERY_PRICE ... TG_DELIVERY цена доставки
DELIVERY_SELF ... TG_DELIVERY самовывоз как тип
DELIVERY_LOCAL ... TG_DELIVERY локальная доставка
DELIVERY_DOWNLOADABLE ... TG_DELIVERY цифровой товар (скачать)
COURIER_DELIVERY_FREE ... TG_DELIVERY курьер бесплатно
COURIER_DELIVERY_PRICE ... TG_DELIVERY цена курьерской
COURIER_DELIVERY_PRICE_IN_PERCENT ... TG_DELIVERY цена курьера в % от товара
COURIER_DELIVERY_FROM_DAYS ... TG_DELIVERY срок доставки, нижняя граница
COURIER_DELIVERY_TO_DAYS ... TG_DELIVERY срок доставки, верхняя граница
COURIER_DELIVERY_TYPE ... TG_DELIVERY тип курьерской доставки
COURIER_DELIVERY_CARRIER ... TG_DELIVERY кто везёт (перевозчик)
COURIER_DELIVERY_IS_SHOP_CARRIER ... TG_DELIVERY везёт сам магазин
COURIER_DELIVERY_NO_OPTIONS ... TG_DELIVERY нет вариантов курьера
PICKUP_FREE ... TG_DELIVERY самовывоз бесплатный
PICKUP_PRICE / _IN_PERCENT ... TG_DELIVERY цена самовывоза
PICKUP_OUTLETS ... TG_DELIVERY кол-во точек выдачи
PICKUP_TYPE ... TG_DELIVERY тип самовывоза
HAS_POST_DELIVERY ... TG_DELIVERY доставка почтой
HAS_POST_TERM_DELIVERY ... TG_DELIVERY доставка в постамат
HAS_DEPOT_DELIVERY ... TG_DELIVERY доставка на пункт/склад
MIN_DELIVERY_PRICE / _IN_PERCENT ... TG_DELIVERY min(самовывоз, доставка)
NO_DEFAULT_DELIVERY_OPTION TG_BLENDER_PLACE, TG_BASE, TG_MODEL_OFFER_PLACE нет варианта по умолчанию
MIN/AVG/MAX_REL_WITH_DELIVERY TG_BLENDER_PLACE, TG_BASE, TG_MODEL_OFFER_PLACE релевантность с учётом доставки
COURIER_DELIVERY_EXISTS TG_OFFER, TG_BASE курьер есть (one-hot)
COURIER_DELIVERY_BY_MARKET TG_OFFER, TG_BASE доставка самим Маркетом
COURIER_DELIVERY_EXPRESS TG_OFFER, TG_BASE экспресс-доставка
PICKUP_EXISTS TG_OFFER, TG_BASE самовывоз есть (one-hot)
V2_DELIVERY_* ... TG_DELIVERY вторая версия тех же фич
1. Наличие - бинарный гейт, а не плавный сигнал
OFFER_IS_ONSTOCK висит на TG_BASE и TG_MODEL_OFFER_PLACE и по смыслу это да/нет: есть товар в наличии или нет. Соседний DELIVERY_NO / DELIVERY_OFF / DELIVERY_EMPTY ловят ситуации, когда доставка не настроена, выключена или данные пустые.
Моя реконструкция: эта пачка работает скорее как фильтр-гейт, чем как плавный ранжирующий вес. Оффер без наличия и без способа получения не имеет шансов конкурировать в товарной выдаче, потому что покупать нечего. CatBoost вполне может в верхних узлах дерева резать такие офферы вниз ещё до того, как в дело пойдут тонкие текстовые и поведенческие сигналы. Это согласуется с тем, что в коде наличие сидит на TG_MODEL_OFFER_PLACE - месте, где Маркет собирает офферы под карточку модели и решает, какой показать.
2. Цена доставки и её доля от цены товара
Тут интересная деталь реализации. Есть и абсолютные цены (DELIVERY_PRICE, COURIER_DELIVERY_PRICE, PICKUP_PRICE, MIN_DELIVERY_PRICE), и их нормированные близнецы в процентах от стоимости товара (COURIER_DELIVERY_PRICE_IN_PERCENT, MIN_DELIVERY_PRICE_IN_PERCENT, PICKUP_PRICE_IN_PERCENT). По описанию в реестре MIN_DELIVERY_PRICE прямо сказано - минимальная из самовывоза и доставки.
3. Бесплатность - отдельные флаги, причём на каждый каналЗачем процент от цены, а не только рубли. 300 рублей доставки на чехол за 500 - это убийца конверсии, а те же 300 рублей на холодильник за 80 тысяч - шум. Процентная нормировка позволяет модели одинаково трактовать дорогую доставку в разных ценовых сегментах. Это сильный аргумент за то, что Маркет смотрит именно на относительную стоимость логистики, а не на абсолют.
Бесплатность вынесена в самостоятельные булевы фичи на каждый способ: DELIVERY_FREE, COURIER_DELIVERY_FREE, PICKUP_FREE. То, что разработчики не свели это к одному флагу free=1, а держат раздельно по каналам - намёк, что разные способы получения для модели не равноценны и она учится на каждом отдельно. Бесплатный самовывоз и бесплатный курьер - разные истории.
4. Сроки доставки - вилкой from/to
COURIER_DELIVERY_FROM_DAYS и COURIER_DELIVERY_TO_DAYS дают именно диапазон, а не одно число. Это позволяет модели отличать честное от 1 до 2 дней от широкого от 1 до 14, где верхняя граница пугает. Отдельно стоит COURIER_DELIVERY_EXPRESS (TG_OFFER, тикет MARKETOUT-43384, описание Экспресс-доставка) - выделенный флаг быстрой доставки. Сообщество селлеров и практика 2025-2026 этот сигнал подтверждают: экспресс даёт заметный плюс к видимости и отдельную метку в выдаче. Срок доставки сейчас открыто называют одним из факторов позиции наряду с ценой и рейтингом магазина.
5. Кто и откуда везёт
COURIER_DELIVERY_CARRIER, COURIER_DELIVERY_IS_SHOP_CARRIER и особенно COURIER_DELIVERY_BY_MARKET (TG_OFFER, Доставка Яндекс.Маркета) разделяют логистику Маркета и доставку силами магазина. Плюс каналы: HAS_POST_DELIVERY (почта), HAS_POST_TERM_DELIVERY (постамат), HAS_DEPOT_DELIVERY (пункт/склад), PICKUP_OUTLETS (сколько точек самовывоза). Чем больше способов забрать товар и чем ближе они к пользователю - тем больше офферу есть чем закрыть запрос в конкретном регионе. PICKUP_OUTLETS как счётчик точек - это по сути прокси на покрытие.
6. Блендерный слой - релевантность с учётом доставки
Отдельно от per-offer фич стоит группа MIN_REL_WITH_DELIVERY / AVG_REL_WITH_DELIVERY / MAX_REL_WITH_DELIVERY и OFFER_PRICE_DIV_OVERALL_MEDIAN_MODEL_PRICE_WITH_DELIVERY, все с тегом TG_BLENDER_PLACE. Это уже агрегаты на уровне подмешивания товарного блока в общую выдачу. Тут любопытно, что цена сравнивается с медианой по модели именно с учётом доставки (..._PRICE_WITH_DELIVERY) - то есть Маркет считает реальную цену на руки, а не голый ценник оффера. Дешёвый оффер с дорогой доставкой по этому фактору проиграет.
Что из этого реально может крутить магазин
- Держать наличие честным. OFFER_IS_ONSTOCK и DELIVERY_NO/_OFF/_EMPTY - это гейт. Оффер без наличия или без настроенной доставки вылетает из конкуренции. Фид должен отдавать актуальный остаток.
- Снижать долю доставки от цены. Процентные фичи (..._IN_PERCENT) намекают, что важна не абсолютная сумма, а её вес относительно товара. Особенно критично в дешёвом сегменте.
- Включать бесплатность там, где экономика позволяет. DELIVERY_FREE / PICKUP_FREE / COURIER_DELIVERY_FREE - отдельные сигналы, можно закрыть хотя бы бесплатный самовывоз.
- Сжимать сроки и подключать экспресс. COURIER_DELIVERY_TO_DAYS (верхняя граница вилки) и COURIER_DELIVERY_EXPRESS - управляемые параметры. Узкая честная вилка лучше широкой.
- Расширять каналы получения: курьер, почта, постамат, больше точек самовывоза (PICKUP_OUTLETS). Это улучшает покрытие по регионам.
- Следить за корректностью фида (YML): пустые или кривые поля доставки уводят оффер в DELIVERY_EMPTY/NO_DEFAULT_DELIVERY_OPTION, а это потеря места по умолчанию.
Если кому интересно - могу следующим разобрать ценовую группу (OFFER_PRICE и сравнения с медианой по модели), она тесно сцеплена с этой через ..._WITH_DELIVERY.Доказано кодом: все перечисленные факторы реально присутствуют в реестре товарной вертикали, живые (TG_DEPRECATED/TG_UNUSED в группе наличия и доставки не встретилось), сидят на TG_TEXT_PLACE и TG_MODEL_OFFER_PLACE, а агрегаты ..._REL_WITH_DELIVERY - на TG_BLENDER_PLACE. Существование процентных нормировок и вилки сроков from/to - тоже факт из реестра и описаний.
Реконструкция (НЕ факт): что наличие работает как гейт в верхних узлах дерева; что процент важнее абсолюта по влиянию; относительная сила любого из этих сигналов. Веса задаёт CatBoost-модель из data/formulas, статических процентов у факторов нет, и формула - не публичная. Конкретные пороги бесплатной доставки и буст экспресса - это уже практика площадки 2025-2026, а не строки реестра.