ESPNRanking the top 20 impact transfers for 2026The Jerusalem PostNetanyahu reveals direct call with Syrian President Sharaa, claims he stopped Druze massacresInquirerSolons hit podcast for making fun of differently abled personsPunchCustoms seize smuggled goods worth ₦721.9m in Sokoto, ZamfaraESPN DeportesVitinha: La vuelta de Cristiano debe resolverseZDF heuteEntdecken Sie das ZDF-NachrichtenstudioLa PressePanne d’électricité | Plus de 17 000 Montréalais dans le noirE! OnlineHow Avantika & More South Asian Celebs Are Sparkling This DiwaliBBC NewsTrump calls off livestream of Fort Hood attacker's execution by firing squadPremium Times2027: Makinde/Daura campaign orders house-to-house mobilisation, agent recruitmentGolem.deAnzeige: Etikettendrucker mit Tastatur und Bluetooth für unter 29 Euro bei Amazonالشرقبريطانيا ترسل المزيد من صواريخ "ستورم شادو" إلى أوكرانيا لضرب مواقع روسية
The Daily Newsstand · Free, Always
Thursday, October 15, 2026

Почему маркетплейс строит свой поиск

Translate

Запрос «платье на свадьбу» одинаково наберут в строке Google и в строке маркетплейса. Технология на входе почти одна и та же: найти по словам или найти по смыслу, по совпадению текста или по векторной близости, когда система понимает, что «платье на свадьбу» и «нарядное платье для торжества» выражают, скорее всего, одно и то же намерение.

Дальше пути расходятся. Веб-поиск отвечает на вопрос, какие документы похожи на этот запрос. У маркетплейса вопрос другой: какие товары полезно показать этому покупателю прямо сейчас, с учётом наличия, цены, доставки и того, что уже известно про него и про товар. Технология на входе одна. Задачи за ней разные.

Со стороны кажется, что маркетплейс покупает готовую технологию, ставит её поверх каталога, и дальше всё собирается само, как сайт из готовых блоков. Ниже разберём условия, в которых живёт поиск маркетплейса, и то, как инженеры доходят до собственного движка. По дороге проверим, верна ли эта догадка.

Это первая статья серии. Во второй посмотрим, как система держит скорость на таком масштабе, и там выяснится, что для большинства запросов ответ готов заранее, ещё до того как покупатель его напечатал.

Условие первое: маркетплейс видит весь путь клиента

Веб-поиск видит один момент: человек напечатал запрос. У крупных поисковиков есть телеметрия и за пределами этого момента, от браузера до метрик на чужих сайтах и истории кликов. Но и она покрывает только отрезки пути, который начинается задолго до запроса и продолжается после него.

a1_01. Путь покупателя в шесть шагов: маркетплейс видит все шесть и связывает их с одним человеком, веб-поиск обрывается на клике по ссылке

Путь покупателя в шесть шагов: маркетплейс видит все шесть и связывает их с одним человеком, веб-поиск обрывается на клике по ссылке

Маркетплейс видит этот путь целиком, и в ранжировании это прямое преимущество. Предсказывать, что понравится покупателю, можно не только по тексту запроса, а по следу, который он сам и похожие на него люди уже оставили: тот же размер, тот же стиль, тот же уровень цены. Почти весь трафик маркетплейса идёт через собственное мобильное приложение, и этого трафика сторонние поисковики не видят вообще, даже со своей телеметрией в браузере. Внутри приложения покупатель не оставляет следа снаружи.

Условие второе: маркетплейс управляет своими данными и ждёт мгновенной реакции

Веб-поиск обновляет чужие источники в своём темпе. Новый материал на одном сайте попадёт в индекс через минуту, на другом через час, и это нормально: источник там чужой.

У маркетплейса всё иначе: источник свой. Что куда везти и сколько это стоит, решают здесь же, внутри, и от своей системы ждут, что она отразит решение мгновенно. Задержка здесь означает потерянные деньги. Скидка на массовую категорию, выставленная часом позже, это тысячи карточек, которые весь этот час продавались по старой цене. Если остаток на складе обнулился, а поиск ещё не узнал об этом, покупатель оформит заказ, который продавец физически не выполнит: необеспеченный заказ, возврат денег, испорченный опыт для всех сторон. Обратная ошибка стоит не меньше. Товар уже можно продавать, а карточка ещё не добралась до выдачи, и первые часы продаж потеряны, а для многих SKU они самые сильные. Оба сбоя об одном: как быстро собственные решения о товаре долетают до выдачи.

Условие третье: продавец управляет своими данными и ждёт того же от маркетплейса

Продавец сам себе хозяин, но от поиска ждёт того же.

a1_02. Одни сутки одного продавца: отметки изменений цены, остатка и ставки идут без перерыва, окна тишины в сутках нет

Одни сутки одного продавца: отметки изменений цены, остатка и ставки идут без перерыва, окна тишины в сутках нет

Цены, остатки и ставки правят тысячи продавцов одновременно, в любой момент суток. Эти изменения приходят не по расписанию поиска, и ни одно из них нельзя отложить до удобного окна обновления. Стоит системе отстать, и продавец теряет деньги: продаёт по старой цене, уступает заказ конкуренту, который обновился быстрее, оплачивает рекламный показ, эффект которого ранжирование не успело учесть. Для него это тот же счёт в деньгах, что и для маркетплейса. Поэтому скорость реакции системы на изменение данных прописана в коммерческом договоре с продавцом как одно из его условий.

Условие четвёртое: витрина на тысячи позиций

В вебе человеку чаще всего нужен один документ: он переходит по первой подходящей ссылке и закрывает вкладку. Внимание в выдаче распределено неровно: первая позиция получает в разы больше, чем вторая, а дальше падение резкое. Поэтому в вебе почти все силы уходят в первую позицию.

У маркетплейса условие другое, и здесь нужна оговорка: так покупатели ведут себя сегодня, и эта привычка может поменяться, например вместе с голосовыми ассистентами и ИИ-агентами, которые собирают корзину за покупателя. Но сейчас покупатель листает витрину, сравнивает, собирает образ, перебирая варианты.

Одной категории достаточно удержать качество на первых десятках позиций. Одежде и похожим категориям нужны сотни. По широким запросам покупатель пролистывает карточки тысячами, прежде чем остановиться.

a1_03. Глубина просмотра на логарифмической шкале: вебу хватает одного документа, узкой категории десятков позиций, широкому запросу тысяч

a1_03. Глубина просмотра на логарифмической шкале: вебу хватает одного документа, узкой категории десятков позиций, широкому запросу тысяч

Угадать заранее, в какую из этих глубин попадёт конкретный человек, система не может. Значит, качество приходится держать одинаковым сразу на всём диапазоне, включая ту часть выдачи, куда инженерная интуиция, воспитанная на вебе, обычно не смотрит.

Условие пятое: много измерений одновременно

Товар может идеально подходить по тексту запроса и всё равно быть бесполезным: недоступен по адресу, приедет слишком поздно, невыгоден по цене или просто низкого качества. Поэтому вместе со смыслом запроса система держит в голове цену и условия, наличие и доставку до конкретного адреса, качество товара (рейтинг, отзывы, возвраты), деньги вокруг товара (продвижение, персональные акции) и отдельно то, насколько именно этот товар подходит именно этому человеку. Футболка, которая идеально сядет на одного покупателя, для другого окажется просто не подходящей по размеру, и это тоже часть релевантности.

a1_09. Шесть осей факторов и две оценки одной карточки: у двух покупателей равнодействующая расходится по цене и по тому, подходит ли товар именно ему

a1_09. Шесть осей факторов и две оценки одной карточки: у двух покупателей равнодействующая расходится по цене и по тому, подходит ли товар именно ему

Внутри каждой категории таких факторов десятки, и все они взвешиваются друг против друга одновременно, для конкретного покупателя в конкретный момент.

Времени на эту работу отведено жёстко и одинаково для всех: ни один покупатель не должен почувствовать расчёт как задержку. Требование идёт насквозь, от железа до того, как написан код. Сколько времени отведено на один запрос, задаёт форму всей системы.

Условие шестое: распределение запросов

Каждые сутки в поиск приходит от 60 до 75 миллионов запросов, а за ними стоит больше 50 миллионов покупателей в день. Частота внутри этого потока меняется плавно: есть несколько тысяч строк, которые повторяются тысячи раз в сутки, и есть огромное множество запросов, которые встречаются раз или два.

На частом конце быстро копятся клики и покупки, любой тест набирает статистическую значимость за дни, а любая ошибка ранжирования повторяется на тысячах показов и сразу видна в агрегированной метрике. Туда и уходит больше всего внимания и тестов.

На редком конце запросу почти не на что опереться: истории именно по этой строке нет, остаются общие сигналы, синонимы, морфология, характеристики самого товара. Отдельная ошибка здесь никому не видна. Показ случился один раз, покупатель не вернулся, в общей цифре это никак не отразилось. Но таких формулировок так много, что по сумме они обходятся системе не дешевле явных провалов на частых запросах. Цена просто размазана по миллионам отдельных строк, и её легко не заметить, если не считать намеренно.

Следить за распределением приходится постоянно, потому что оно живое. Просело качество на каком-то участке частоты, и часть покупателей уходит в более широкие формулировки, часть в более точные: распределение само сдвигается вслед за качеством.

Шесть условий складываются в один вывод: движок, который отлично ищет документы, закрывает только часть задачи маркетплейса. Дальше начинается вопрос дороже: почему остальное выгоднее делать самим, а не покупать под ключ. Отвечают на него в четыре шага, и каждый следующий дороже предыдущего.

Мысль первая: купить готовый поиск

Самая очевидная мысль: купить поиск как сервис и не разворачивать движок самому. Для интернет-магазина с каталогом в тысячи или даже сотни тысяч позиций на рынке есть зрелые решения, в том числе в России и СНГ. Например, у небольших магазинов поиск часто просто встроен в 1С-Битрикс. REES46 и похожие сервисы продают персонализацию поиска как надстройку над чужим каталогом. Algolia в своё время выходила на рынок РФ и СНГ через партнёра Stellar Labs. Все они закрывают полнотекстовый поиск, синонимы, автодополнение и базовую персонализацию без найма отдельной команды, и для такого магазина это разумный выбор.

Разумным он остаётся ровно до того момента, когда вокруг каталога появляется собственный рынок продавцов. Дальше поиску приходится честно распределять видимость между продавцами, которые конкурируют за одну и ту же выдачу, встраивать их рекламную ставку в ранжирование без ущерба покупателю и отдавать цену и остаток по конкретному адресу через секунды после изменения. Готовой функции под эту коммерческую логику в SaaS-каталоге нет, и поиск как сервис не берёт её на себя ни при каком размере каталога. Когда таких продавцов десятки тысяч, как на большом маркетплейсе, решать эти вопросы приходится самому, независимо от того, кто держит индекс. Либо свыкаться с чужим решением и жить в его рамке, ограничивая этим свой бизнес. На таком масштабе мелочи решают, сколько выручки приносит каждый продавец и каждый покупатель.

Мысль вторая: развернуть готовый движок самостоятельно

Следующий шаг: поставить у себя готовое ядро и не покупать поиск как сервис. Elasticsearch, Solr, OpenSearch, Sphinx дают полнотекстовый поиск, синонимы, фильтрацию и базовое ранжирование, которые иначе надо месяцами писать с нуля. Для каталога, который уже не укладывается в лимиты SaaS, но ещё не требует полностью своей инфраструктуры, это рабочий путь.

Мы сами начинали оттуда.

Чем этот путь продолжается, видно по именам, которые у всех на слуху. Ozon в 2017-2020 годах строил поиск на Elasticsearch, а затем заменил его собственным движком на базе Apache Lucene, когда точность и скорость на масштабе каталога перестали устраивать. Lamoda сегодня держит двухуровневую схему: Elasticsearch отбирает кандидатов по упрощённым весам, переранжирование делает отдельный сервис на Go с CatBoost. Avito на Elasticsearch не переходил вовсе, у них своя поисковая СУБД на C++ поверх кластеров Sphinx. Три разные точки на одной кривой: чем больше каталог и сложнее коммерческая логика, тем раньше готовое ядро перестаёт быть тем единственным местом, где считается релевантность.

Комбинировать факторы в одной формуле ранжирования умеет почти любой такой движок: boost по полям, кастомные скрипты, подключаемые функции скоринга. Считать по этой формуле он тоже умеет. Сложность начинается в другом. Чтобы формула реально учитывала цену, остаток до конкретного адреса, динамическую рекламную ставку и персональные сигналы покупателя, все эти данные должны лежать рядом с движком в момент расчёта и обновляться с той же скоростью, с какой меняется цена или остаток, то есть за секунды. Доставлять данные с такой частотой и постоянно переобучать модель на свежих примерах: это отдельная работа, и на масштабе маркетплейса она быстро становится больше и сложнее самого движка.

Там, где доставку данных не выстраивают как следует, в движке обычно остаётся простая ранжирующая формула или лёгкий катбуст, а по-настоящему точное решение переносят в отдельный сервис выше, который пересортировывает уже найденных кандидатов. Чужие системы снаружи в таких деталях не видны, но на рынке чаще всего встречается именно такая схема. Цена у неё та же: формула в движке и модель в сервисе наверху работают с данными разной свежести. Если цена, остаток или ставка продвижения изменились между этими двумя шагами, решение по карточке примут уже без них.

Свой движок мы начали строить на каталоге около восьми миллионов SKU. Сегодня у нас в индексе 850 миллионов карточек, около 520 миллионов из них с остатком прямо сейчас. Готовое ядро свою узкую задачу решало неплохо, но сервисы, которые мы строили вокруг него, росли быстрее самого ядра.

Мысль третья: нарастить сервисы вокруг готового ядра

Мысль трудоёмкая. Ядро остаётся на месте, а вокруг него собирают решение из отдельных сервисов. Индекс остаётся готовым движком или его упрощённой собственной версией. Рядом встаёт кэш для частых запросов. Цены считает и обновляет отдельный поток. Отдельный сервис сводит данные о товаре с данными о его доступности на складе и логистике до конкретного адреса, потому что в одном месте и в одном формате эти данные почти никогда не рождаются: цена живёт в одной системе, остаток в другой, срок доставки по адресу собирает третья. Сверху встраивают точку, куда можно добавить собственную модель ранжирования, и отдельно думают, как доставить ей факторы: цену, остаток, историю покупателя, рекламную ставку, вовремя и в нужном виде.

a1_04. Пять источников со своими владельцами сходятся в одну оценку: её свежесть равна свежести самого старого из факторов

Пять источников со своими владельцами сходятся в одну оценку: её свежесть равна свежести самого старого из факторов

Путь рабочий, и многие системы на нём и остаются, потому что для их масштаба он разумен. Граница у него такая. Каждый новый сервис это новый контракт данных с соседями и новая точка, которая может отстать или сломаться. Чем больше сервисов, тем больше ресурсов уходит на то, чтобы переложить результат одного вычисления в формат, который понимает следующее звено, помимо затрат на сам расчёт. Ядро при этом остаётся прежним и несёт свои собственные ограничения: сколько факторов удержит его формула ранжирования, как быстро оно переобучается, какую глубину выдачи вытягивает с одинаковым качеством.

Мысль четвёртая: заменить все узлы и пересобрать архитектуру

Самая дорогая мысль начинается с другого вопроса. Не слишком ли мы сами себя ограничиваем, принимая чужое готовое решение как раму для своей задачи? Что если взять сами требования (показать покупателю нужный товар с учётом цены, остатка и логистики) и спроектировать систему вокруг них с нуля, вместо того чтобы отталкиваться от чужого ядра, которое решало задачу поуже: найти документы, похожие на текст запроса.

a1_05. Четыре ступени под одним потолком: с каждой ступенью запас над головой кончается, и только четвёртая проходит потолок насквозь

Четыре ступени под одним потолком: с каждой ступенью запас над головой кончается, и только четвёртая проходит потолок насквозь

На каждой из трёх предыдущих ступеней часть решения остаётся не в наших руках. В SaaS это наша коммерческая логика. В готовом движке это скорость доставки факторов. В сервисах вокруг ядра это формула ранжирования самого ядра. Чем быстрее растут каталог и трафик, тем раньше подступает потолок, потому что именно рост показывает, чего чужое решение брать на себя не собиралось. Для полной пересборки нужны люди, которые будут вести эту систему и дальше, и готовность не возвращаться к чужому ядру при следующем новом требовании.

Что мы построили

Мы выбрали эту, четвёртую ступень: перестали обслуживать чужой движок и построили собственный, без унаследованных ограничений, сразу под свою задачу. Главное в нём: в момент запроса он не опрашивает всю базу товаров.

Запрос на входе проходит два шага. Сначала разбираем строку и понимаем, что покупатель имел в виду. Потом сразу отдаём товары, без дополнительных сетевых запросов и даже без обращений к диску. Второй шаг стоит на четырёх принципах.

Владение ядром. В системе нет ни одного места, которое мы не можем поменять сами. Нужно починить баг в формуле ранжирования или добавить новый фактор: делаем сами, не ждём очередного релиза чужого вендора и не переживаем миграцию на новую мажорную версию чужого продукта. Чужого кода по чужому графику здесь просто нет.

Донести байты дороже, чем посчитать. Расчёт стоит не только процессорного времени, но и времени на дорогу: нужные байты должны оказаться в нужном месте, в регистре процессора, в кэше, в оперативной памяти, на диске, по сети до другой машины. Каждый следующий уровень в этом перечне на порядки медленнее предыдущего.

a1_06. Задержки по уровням памяти на логарифмической шкале: от кэша процессора до сети ×20 000 000, граница проходит сразу после оперативной памяти

Задержки по уровням памяти на логарифмической шкале: от кэша процессора до сети ×20 000 000, граница проходит сразу после оперативной памяти

Масштаб этой разницы показывает классическая подборка Джеффа Дина «Latency Numbers Every Programmer Should Know» (https://colin-scott.github.io/personal_website/research/interactive\_latency.html): от кэша процессора до сети счёт идёт на несколько порядков. Настоящая стоимость расчёта чаще прячется именно в перемещении байтов, а арифметика самой формулы ранжирования обходится дешевле, чем кажется. Поэтому данные держим близко к месту расчёта, чтобы на пути к решению было меньше лишних копий.

Качество и скорость не зависят от объёма ассортимента. Система, которая замедляется или теряет точность по мере роста каталога, обменивает сегодняшнее удобство на завтрашний потолок.

Масштабируемся в ширину, без встроенных узких мест. Больше категорий: добавляем железо. Покупатель, который ищет платье, не теряет ничего оттого, что мы добавили автомобили, и с ростом числа покупателей работает тот же принцип. Во многих системах есть жёсткий лимит на число документов, которые передаются между узлами, и дальше остаётся надеяться, что нужный товар проскочит через фильтр вовремя. Мы хотели убрать эту зависимость результата от удачи.

a1_07. Две дорожки на одной шкале времени: цепочка сервисов складывает задержки и выходит за дедлайн, один проход по памяти узла укладывается в ≈50 мс

Две дорожки на одной шкале времени: цепочка сервисов складывает задержки и выходит за дедлайн, один проход по памяти узла укладывается в ≈50 мс

Лучше всего это видно на логистике. Срок доставки считаем до конкретного адреса и обновляем в том же темпе, в каком меняются остатки и цены. Соседние дома одного района возят с разных складов, сроки у них разные, загрузка плавает, и расклад между ними меняется почти мгновенно.

Коммерческая логика встроена в тот же расчёт и тем же способом. Через продвижение продавец борется за внимание покупателя среди похожих предложений: платит за показ, за клик или за заказ. Его ставка для системы просто ещё один фактор, который попадает в ту же формулу ранжирования, что цена и остаток, и обязан быть таким же свежим, как они.

Остаётся главное: как не опрашивать весь каталог на каждый запрос. Мы предвычисляем всё, что не зависит от момента конкретного запроса, и оставляем на расчёт в моменте только то, что реально зависит от контекста прямо сейчас.

a1_08. Доля потока, которую покрывает предрасчёт, и разделение работы: что вынесено в фон и что остаётся на момент запроса

Доля потока, которую покрывает предрасчёт, и разделение работы: что вынесено в фон и что остаётся на момент запроса

Дальше всё держится на том, как сужается этот поток. Где именно он начинает сужаться, как это устроено и что происходит между предвычисленным набором и готовой выдачей, подробно разберём во второй статье серии.

Что это дало

Свой движок, который мы пишем и правим сами, развязал руки всем, кто работает с выдачей. Команда контентного ранжирования меняет релевантность где нужно, не упираясь в чужой код. Команды бизнес-ранжирования и платного продвижения оптимизируют деньги компании и селлеров. Блок коммерции запускает в поиске любые механики.

Новая цена, обновившийся остаток и только что заведённая карточка долетают до выдачи за секунды. Всё просто работает, как ожидается.

View the original on Хабр →

KioskNews shows a cleaned-up reading view extracted from the publisher’s page — the original always lives on their site, not ours.