Назад в блог

Vector search для каталога: когда работает, когда переплата

Нам предложили добавить vector search к каталогу. 40 000 SKU, Elasticsearch уже стоит. Fuzzy настроен. Синонимы работают. Function_score буст по марже и остаткам — тоже.

Первый вопрос, который я задал: какую задачу не решает то, что есть сейчас?

Интегратор ушёл думать. Мы не стали ждать. Мы не добавили vector search для интернет-магазина на Elasticsearch — и каталог от этого не пострадал.

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

Что такое vector search и почему его продают e-commerce

Классический Elasticsearch как инструмент UX работает с BM25: ищет по вхождению термина, учитывает частоту, нормирует на длину документа. Быстро — 5-10 мс. Предсказуемо. Понятно при отладке.

Vector search — другое. Текст (запрос или карточка товара) превращается в числовой вектор через embedding-модель (SBERT, CLIP, Elastic ELSER). Elasticsearch ищет ближайших соседей по HNSW-индексу. Находит «семантически похожее», даже если ни одного слова не совпало.

Именно поэтому интеграторы это и продают: «пользователь ищет "удобный офисный стул" — а вы выдаёте эргономичные кресла с правильным описанием, даже если слово "удобный" в карточке не встречается».

Звучит красиво. Работает — в конкретных сценариях.

Три сценария, где vector search реально даёт прирост

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

Второй — мультиязычный поиск. Если каталог на русском, а часть запросов на английском или транслитом, embedding-модель с multilingual-поддержкой закрывает этот разрыв лучше словарей синонимов.

Третий — рекомендации, а не поиск. «Похожие товары» на карточке — это не поисковый запрос, это nearest-neighbor по вектору описания. Здесь vector search в своей стихии.

Все три — про размытые намерения, не про точные запросы.

Когда BM25 + fuzzy + synonyms достаточно — и дешевле

Артикул «WH-1000XM5» — это токен, которого нет в словаре embedding-модели. kNN-поиск по такому запросу вернёт случайность. BM25 найдёт точное совпадение за 5 мс.

Для каталога до 100 000 SKU настроенный BM25 с fuzziness: AUTO, словарём синонимов и language-анализатором под русскую морфологию закрывает 80-90% реальных поисковых проблем. Это подтверждает наш опыт: на проекте с 28 000 SKU zero-results rate упал с 22% до 11% после настройки fuzzy и добавления 180 пар синонимов — без единой строки vector search.

Latency: BM25 — 5-10 мс. kNN добавляет 20-50 мс в зависимости от размера индекса и параметров HNSW. Для мобильного пользователя с плохим соединением это ощутимо.

Есть и операционные издержки. Vector search требует:

  • embedding pipeline — сервис, который векторизует запросы и товары
  • переиндексацию при обновлении описаний, цен, остатков
  • отдельный сервис для модели или платный Elastic ELSER

На 28 000 SKU с базовой конфигурацией 384-мерные векторы добавят ~400 МБ к heap. Это не критично, но учитывать нужно.

Стоимость, которую не называют в pitch

Интегратор показывает демо на 1000 товаров с красивыми примерами. В проде на 40 000 SKU картина другая.

Batch embedding при первичной индексации: 40k документов × 50 мс на вызов внешней API = 33 минуты при одном потоке. С параллелизмом — быстрее, но нужна инфраструктура.

Incremental re-embedding: каждое обновление карточки (цена, остаток, описание) должно пересчитывать вектор и обновлять HNSW-индекс. Это batch pipeline, который надо писать, тестировать и мониторить.

Latency под нагрузкой: kNN с HNSW — операция не O(1). При high-load и 40k документах p95 может уходить за 100 мс. BM25 при тех же условиях остаётся в 10-20 мс.

Это не аргумент против vector search. Это аргумент за трезвую оценку до подписания контракта.

Пять вопросов перед внедрением

Задайте их себе или интегратору до того, как поставите задачу в бэклог.

  1. Zero-results rate выше 15%? Если ниже — сначала разберитесь с fuzzy и синонимами.
  1. Какой процент запросов — точные артикулы и модели? Если больше 40% — vector search здесь не поможет.
  1. Есть ли labeled query dataset? Без него A/B тест нельзя настроить.
  1. Какой latency бюджет? Меньше 20 мс — vector search вписать без hybrid режима не получится.
  1. Кто поддерживает embedding pipeline? Это отдельный сервис со своим SLA. Если ответ «разберёмся» — это риск.

Что делать, если клиент уже купил идею

Не спорить. Это проигрышная позиция.

Предложите гибридный поиск: BM25 + vector через Reciprocal Rank Fusion (RRF). Elasticsearch поддерживает это нативно через sub_searches. Клиент получает семантику там, где она нужна, BM25 остаётся якорем для точных запросов. Latency вырастет — предупредите заранее.

Зафиксируйте baseline до внедрения: zero-results rate, search CTR, search-to-cart. Без цифр до — нет разговора про «стало лучше».

Если через месяц A/B тест не покажет роста по ключевым метрикам, это не провал — это данные. С ними разговор с клиентом становится инженерным, а не политическим.

Итог

Vector search для интернет-магазина на Elasticsearch — не upgrade. Это другой инструмент с другой задачей.

Каталог до 100 000 SKU с настроенным fuzzy и синонимами чаще всего не упирается в потолок, который vector search призван пробить. Он упирается в операционные мелочи: неправильный анализатор, пустые синонимы, нулевые результаты из-за опечатки.

Начните с zero-results rate. Потом — search CTR. Если оба в норме, подождите с kNN до следующей настоящей проблемы.

Когда семантика запросов уйдёт дальше keyword matching — и никакие синонимы это не закроют — вы это почувствуете. Тогда и возвращайтесь к разговору про vector.