Как мы использовали семантический поиск, чтобы сделать наш поиск в 10 раз умнее
В Tokopedia мы понимаем, что ценность нашего продуктового корпуса раскрывается только тогда, когда наши покупатели могут находить релевантные для них товары, поэтому мы стремимся улучшать релевантность результатов поиска.
Чтобы продвинуться в этом направлении, мы внедряем поиск по сходству на Tokopedia. Если вы перейдете на страницу результатов поиска на мобильных устройствах, вы найдете кнопку “...”, которая открывает меню с возможностью искать товары, похожие на данный товар.
Поиск на основе ключевых слов
Tokopedia Search использует Elasticsearch для поиска и ранжирования товаров. Для каждого поискового запроса мы сначала обращаемся к Elasticsearch, который ранжирует товары в соответствии с поисковым запросом. ElasticSearch хранит каждое слово как последовательность чисел, представляющих ASCII (или UTF) коды для каждой буквы. Он строит инвертированный индекс, чтобы быстро определить, какие документы содержат слова из пользовательского запроса, а затем находит среди них лучшее совпадение, используя различные алгоритмы оценки. Эти алгоритмы оценки уделяют мало внимания тому, что означают слова, а скорее тому, насколько часто они встречаются в документе, насколько близко они расположены друг к другу и т. д. ASCII-представление, очевидно, содержит достаточно информации для передачи семантики (в конце концов мы, люди, можем его понять). К сожалению, не существует хорошего алгоритма, который позволял бы компьютеру сравнивать ASCII-кодированные слова по их смыслу.
Векторное представление
Одним из решений было бы придумать альтернативное представление, которое говорит нам не только о буквах, содержащихся в слове, но и о чем-то, связанном с его значением. Например, мы могли бы закодировать с какими другими словами наше слово часто используется вместе (представить через вероятный контекст). Затем мы бы предположили, что похожие контексты представляют похожие вещи, и попытались бы сравнить их с помощью математических методов. Мы могли бы даже найти способ кодировать целые предложения по их смыслу.
Векторное представление также раскрывает значение слов по сравнению с ASCII-представлением.
Выбор поискового движка для similarity search по embedding
Теперь, когда у нас есть векторы признаков, оставшаяся проблема заключается в том, как извлечь из большого объема векторов те, которые похожи на целевой вектор. Что касается поискового движка для embeddings, мы попробовали POC на нескольких движках, доступных на Github, среди них FAISS, Vearch, Milvus.
Мы предпочитаем Milvus другим движкам на основе результатов нагрузочного тестирования. С одной стороны, мы уже использовали FAISS ранее в других командах и поэтому хотели попробовать что-то новое. По сравнению с Milvus, FAISS является скорее базовой библиотекой, поэтому не совсем удобен в использовании. По мере того как мы больше узнавали о Milvus, мы в итоге решили принять Milvus из-за двух его основных особенностей:
Milvus очень прост в использовании. Все, что вам нужно сделать, — это загрузить его Docker-образ и обновить параметры в соответствии с вашим собственным сценарием.
Он поддерживает больше индексов и имеет подробную сопроводительную документацию.
В двух словах, Milvus очень дружелюбен к пользователям, а документация достаточно подробна. Если вы столкнетесь с какой-либо проблемой, обычно вы можете найти решения в документации; в противном случае вы всегда можете получить поддержку от сообщества Milvus.
Кластерный сервис Milvus
После решения использовать Milvus в качестве поискового движка по векторам признаков мы решили применить Milvus для одного из сценариев использования нашего Ads-сервиса, где мы хотели сопоставлять ключевые слова с низким fill rate с ключевыми словами с высоким fill rate. Мы настроили standalone-узел в среде разработки (DEV) и начали обслуживание; он хорошо работал в течение нескольких дней и давал нам улучшенные метрики CTR/CVR. Если standalone-узел выйдет из строя в production, весь сервис станет недоступен. Поэтому нам необходимо развернуть высокодоступный поисковый сервис.
Milvus предоставляет как Mishards, промежуточное ПО для шардирования кластера, так и Milvus-Helm для конфигурации. В Tokopedia мы используем Ansible playbooks для настройки инфраструктуры, поэтому создали playbook для оркестрации инфраструктуры. Диаграмма ниже из документации Milvus показывает, как работает Mishards:
Как работает Mishards.
Mishards каскадно передает запрос от upstream вниз к своим подмодулям, разделяя upstream-запрос, а затем собирает и возвращает результаты субсервисов в upstream. Общая архитектура кластерного решения на основе Mishards показана ниже:
Общая архитектура Mishards.
Официальная документация дает понятное введение в Mishards. Вы можете обратиться к Mishards, если вам интересно.
В нашем сервисе keyword-to-keyword мы развернули один записываемый узел, два узла только для чтения и один экземпляр промежуточного ПО Mishards в GCP, используя Milvus ansible. Пока он работает стабильно. Огромная составляющая того, что делает возможным эффективные запросы к наборам данных с миллионами, миллиардами или даже триллионами векторов, на которые опираются поисковые системы по сходству, — это индексирование, процесс организации данных, который радикально ускоряет поиск в больших данных.
Как векторное индексирование ускоряет поиск по сходству?
Поисковые системы по сходству работают, сравнивая входные данные с базой данных, чтобы находить объекты, наиболее похожие на входные данные. Индексирование — это процесс эффективной организации данных, и оно играет ключевую роль в том, чтобы сделать поиск по сходству полезным, резко ускоряя трудоемкие запросы к большим наборам данных. После индексации массивного векторного набора данных запросы могут направляться в кластеры или подмножества данных, которые с наибольшей вероятностью содержат векторы, похожие на входной запрос. На практике это означает, что определенная степень точности приносится в жертву ради ускорения запросов к действительно большим векторным данным.
Можно провести аналогию со словарем, где слова отсортированы по алфавиту. При поиске слова можно быстро перейти к разделу, который содержит только слова с той же начальной буквой, — что радикально ускоряет поиск определения входного слова.
Что дальше, спросите вы?
Blog_How we used semantic search to make our search 10x smarter_5.jpeg
Как показано выше, не существует решения, подходящего для всех; мы всегда хотим улучшать производительность модели, используемой для получения эмбеддингов.
Кроме того, с технической точки зрения мы хотим запускать несколько моделей обучения одновременно и сравнивать результаты различных экспериментов. Следите за обновлениями, чтобы узнать больше о наших экспериментах, таких как поиск по изображениям и поиск по видео.
Ссылки:
- Документация Mishards:https://milvus.io/docs/v0.10.2/mishards.md
- Mishards: https://github.com/milvus-io/milvus/tree/master/shards
- Milvus-Helm: https://github.com/milvus-io/milvus-helm/tree/master/charts/milvus
Эта статья блога перепечатана с: https://medium.com/tokopedia-engineering/how-we-used-semantic-search-to-make-our-search-10x-smarter-bd9c7f601821
Читайте другие истории пользователей, чтобы узнать больше о том, как создавать с Milvus.
Читать далее

A Few Notes from Databricks Data + AI Summit 2026: Why the Data Layer Matters Again
James Luan shares notes from Databricks Data + AI Summit 2026 on why production AI is pushing the data layer back to the center of infrastructure.

Data Deduplication at Trillion Scale: How to Solve the Biggest Bottleneck of LLM Training
Explore how MinHash LSH and Milvus handle data deduplication at the trillion-scale level, solving key bottlenecks in LLM training for improved AI model performance.

Vector Databases vs. Graph Databases
Use a vector database for AI-powered similarity search; use a graph database for complex relationship-based queries and network analysis.



