Поиск редко сводится к одному универсальному сценарию. Пользователь, вводящий "cheap running shoes", хочет точных совпадений по ключевым словам, а пользователь, задающий "comfortable footwear for jogging", выражает то же намерение другими словами. Традиционный полнотекстовый поиск хорошо справляется с первым случаем. Векторный поиск решает второй. Гибридный поиск объединяет оба в одном запросе, так что вам не приходится выбирать.

В современных поисковых системах это часто описывается как комбинирование лексического (разреженного) поиска с семантическим (плотным) поиском. Разные термины, одна идея: точное совпадение плюс смысл.

Что такое гибридный поиск?

Гибридный поиск одновременно выполняет полнотекстовый (BM25) поиск и векторный (KNN) поиск, а затем объединяет два списка результатов в один. Документы, получившие высокий балл по любому из сигналов (или по обоим), поднимаются наверх.

Полнотекстовый поиск отлично работает с точными ключевыми словами, редкими терминами и идентификаторами. Векторный поиск понимает смысл — например, что "automobile" и "car" обозначают одну и ту же концепцию, — потому что их эмбеддинги находятся рядом в векторном пространстве.

У каждого метода есть свои слабые места:

  • Полнотекстовый затрудняется с синонимами и естественным языком

  • Векторный поиск затрудняется с точными токенами, такими как SKU, коды ошибок и идентификаторы

Гибридный поиск охватывает оба.

Как гибридный поиск вписывается в современные поисковые приложения

Гибридный поиск — это этап извлечения: часть системы, которая находит релевантных кандидатов в ваших данных.

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

На практике это означает:

  • Лучшее покрытие (recall) для запросов на естественном языке

  • Точное совпадение для идентификаторов, таких как SKU или коды ошибок

  • Более релевантные результаты без сложной логики запросов

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

Когда следует использовать гибридный поиск?

Гибридный поиск подходит, когда:

  • Ваши запросы сочетают намерение и детали. Поиск вроде python error 403 forbidden выигрывает от точности по ключевому слову в коде ошибки и семантического понимания описания проблемы.

  • Вы создаёте конвейер RAG. Retrieval-Augmented Generation требует подачи самых релевантных фрагментов в LLM. Гибридное извлечение постоянно находит более релевантные документы, чем любой из методов по отдельности.

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

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

Как это работает

Manticore использует Reciprocal Rank Fusion (RRF) для объединения результатов. Идея проста: вместо попытки сравнивать сырые оценки BM25 с расстояниями KNN, которые живут на совершенно разных шкалах, RRF смотрит на позиции в ранжировании. Документ, занявший #1 в текстовых результатах и #3 в результатах KNN, получает более высокий комбинированный балл, чем документ, появившийся только в одном списке.

Вот простой пример. Предположим, что текстовый поиск и поиск KNN возвращают свои топ‑3:

Результаты текстового поиска:

Ранг

Документ

1

Doc A

2

Doc B

3

Doc C

Результаты поиска KNN:

Ранг

Документ

1

Doc C

2

Doc A

3

Doc D

RRF оценивает каждый документ по формуле 1 / (rank_constant + rank). При значении по умолчанию rank_constant=60:

Документ

Вклад текста

Вклад KNN

Балл RRF

Doc A

1/(60+1) = 0.0164

1/(60+2) = 0.0161

0.0325

Doc C

1/(60+3) = 0.0159

1/(60+1) = 0.0164

0.0323

Doc B

1/(60+2) = 0.0161

0.0161

Doc D

1/(60+3) = 0.0159

0.0159

Doc A занимает первое место, потому что появляется почти вверху обоих списков. Doc C находится рядом по той же причине. Doc B и Doc D присутствуют только в одном списке, поэтому их баллы ниже.

Почему RRF?

Существует два распространённых способа объединения результатов:

  • Слияние на основе рангов (RRF) — простое, надёжное, без необходимости нормализовать оценки

  • Слияние на основе оценок — сначала нормализовать оценки, а затем объединять

Manticore использует RRF, потому что этот метод хорошо работает сразу из коробки и избавляет от проблем с калибровкой оценок.

Внутри гибридный запрос разбивается на независимые подзапросы: один для полнотекстового поиска, один или несколько для KNN. Они выполняются параллельно, а после завершения RRF объединяет их ранжированные списки результатов в один итоговый список.

Почему нельзя просто использовать один из методов?

Рассмотрим базу знаний поддержки со статьями о разных кодах ошибок — сбоях соединения, проблемах аутентификации и ошибках синхронизации. Пользователь видит ошибку E-5020 на экране и сообщает: "Не могу подключиться к серверу."

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

#

Заголовок

Расстояние KNN

1

Ошибка E-5030: Ошибка разрешения DNS

0.572

2

Ошибка E-2091: Превышено время загрузки приложения

0.583

3

Ошибка E-5020: Несоответствие SSL‑сертификата

0.605

4

Ошибка E-5010: Сервис недоступен

0.622

5

Ошибка E-4001: Не удалось войти

0.665

Правильная статья (E-5020) оказывается только на позиции #3. KNN ставит выше ошибки DNS и таймаутов, потому что их описания семантически ближе к фразе "не могу подключиться". Реальная проблема — несоответствие SSL‑сертификата — использует совсем другую лексику, поэтому получает более низкий балл.

Можно подумать: просто добавить код ошибки в запрос KNN. Но "E-5020" и "E-5010" — это произвольные идентификаторы без семантического значения, и эмбеддинги воспринимают их как почти одинаковые токены. KNN по запросу "E-5020 не могу подключиться к серверу" действительно поднимает E-5020 на позицию #1, но лишь потому, что добавленный текст меняет семантический контекст — сам код ошибки почти ничего не весит.

Гибридный поиск решает эту проблему, отправляя каждый сигнал туда, где он работает лучше всего: код ошибки — в полнотекстовый поиск, симптом — в KNN.

SELECT title, hybrid_score()
FROM support_articles
WHERE knn(embedding, 'can not connect to the server')
  AND MATCH('E-5020')
LIMIT 5
OPTION fusion_method='rrf';

#

Title

Hybrid score

1

Error E-5020: SSL Certificate Mismatch

0.032

2

Error E-5030: DNS Resolution Failed

0.016

3

Error E-2091: App Loading Timeout

0.016

4

Error E-5010: Service Unavailable

0.016

5

Error E-4001: Login Failed

0.015

E-5020 поднимается с #3 на #1 и получает почти вдвое более высокий балл, чем остальные. Полнотекстовый поиск воспринимает «E-5020» как точную строку — не похожую на «E-5010», не "почти близкую", а просто другую. KNN при этом гарантирует, что связанные ошибки соединения всё равно остаются ниже для контекста.

Это основная ценность гибридного поиска:

  • Идентификаторы → полнотекстовый поиск

  • Смысл → векторный поиск

Каждый метод покрывает слепую зону другого.

С чего начать

Самый простой способ выполнить гибридный поиск — использовать hybrid_match(). Если в вашей таблице настроено автоматическое создание эмбеддингов, одна строка делает всё: поиск по тексту, генерацию эмбеддингов, поиск KNN и объединение через RRF.

SELECT id, hybrid_score()
FROM products
WHERE hybrid_match('running shoes');

JSON-эквивалент:

POST /search
{
  "table": "products",
  "hybrid": { "query": "running shoes" }
}

Manticore:

  • генерирует эмбеддинги

  • выполняет оба поиска параллельно

  • объединяет результаты

Полный контроль: явный MATCH + KNN

Если вы хотите передавать собственные векторы или настраивать отдельные подзапросы, используйте явную форму с MATCH() и KNN() в условии WHERE:

SELECT id, hybrid_score()
FROM products
WHERE match('running shoes')
  AND knn(embedding, (0.12, 0.45, 0.78, ...))
OPTION fusion_method='rrf';
POST /search
{
  "table": "products",
  "knn": {
    "field": "embedding",
    "query_vector": [0.12, 0.45, 0.78, "..."]
  },
  "query": { "match": { "title": "running shoes" } },
  "options": { "fusion_method": "rrf" }
}

Каждый результат включает:

  • hybrid_score() — объединённый балл (используется для сортировки по умолчанию)

  • weight() — балл BM25

  • knn_dist() — векторное расстояние

Фильтры по атрибутам (AND category = 'footwear') применяются к обоим подзапросам.

Настройка

Поведение объединения настраивается тремя опциями:

  • rank_constant — контролирует, насколько верхние позиции доминируют в объединённом балле. Низкие значения (например, 10) делают позицию #1 значительно более значимой, чем позицию #5. Высокие значения сглаживают кривую. См. rank_constant .

  • fusion_weights — позволяет задать разную важность каждому подзапросу. Если релевантность текста важнее, чем векторное сходство, задайте больший вес. См. fusion_weights .

  • window_size — сколько результатов каждый подзапрос получает до объединения. По умолчанию Manticore вычисляет это автоматически из параметров KNN и LIMIT запроса. См. window_size .

Слияние нескольких векторов

Гибридный поиск не ограничивается одним текстовым поиском и одним поиском KNN. Можно объединять несколько векторных поисков — это полезно, когда в данных есть несколько разных семантических измерений. Например, у товара в e-commerce есть текстовое описание и фотография. Пользователь, ищущий «минималистичные белые кроссовки», опирается сразу на оба сигнала: название должно соответствовать стилю, а изображение товара — выглядеть так, как он это представляет. Если закодировать название и изображение в отдельных векторных пространствах, их можно искать одновременно и позволить RRF выводить наверх товары, которые соответствуют всем трём сигналам — ключевым словам, смыслу текста и визуальному сходству:

SELECT id, hybrid_score()
FROM products
WHERE match('running shoes') AS text
  AND knn(title_vec, (0.12, 0.45, ...)) AS title_sim
  AND knn(image_vec, (0.88, 0.21, ...)) AS image_sim
OPTION fusion_method='rrf',
       fusion_weights=(text=0.5, title_sim=0.3, image_sim=0.2);

Все подзапросы выполняются параллельно и объединяются вместе через RRF.

Заключение

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

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

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

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