Sobes.tech
Back to questions
Middle — Senior
8

Что такое hybrid search в Qdrant и как объединять dense + sparse?

Companies where asked
ЛеруаМерлен

Answer from AI

sobes.tech AI

Что хотят услышать интервьюеры:

Hybrid search в Qdrant — это поиск, который одновременно использует плотные векторы и разреженные признаки. Он полезен, когда нужно сочетать семантическое понимание текста с точным совпадением ключевых слов. Обычно dense отвечает за смысл, sparse — за редкие термины, имена и exact-match, а итоговый результат получается за счёт объединения и ранжирования двух сигналов.

Определение:

Hybrid search — это подход к поиску, где один и тот же запрос сравнивается сразу по двум представлениям: dense embedding и sparse vector. Dense-вектор хорошо ловит общий смысл, даже если слова не совпадают дословно. Sparse-вектор хранит важные слова и их веса, поэтому помогает находить документы с точными терминами, артиклями, именами, кодами и редкими токенами.

В Qdrant это обычно реализуют как хранение нескольких векторных представлений в одной точке и последующий поиск по ним с объединением результатов. На практике dense и sparse часто комбинируют на этапе retrieval, а затем нормализуют и сливают скоринг, чтобы получить один финальный список кандидатов.

Пример использования:

Допустим, пользователь ищет «python memory leak async aiohttp». Dense-поиск может найти статьи про утечки памяти в асинхронных приложениях, даже если слова формулированы иначе. Sparse-поиск дополнительно поднимет документы, где встречаются именно aiohttp, memory leak и async, что помогает не потерять узкие технические материалы.

# Псевдокод: идея hybrid search
# Dense embedding -> смысл
dense_query = dense_model.encode("python memory leak async aiohttp")

# Sparse representation -> ключевые токены / веса
sparse_query = sparse_model.encode("python memory leak async aiohttp")

# Поиск в Qdrant по двум каналам
dense_hits = qdrant.search(
    collection_name="docs",
    query_vector=("dense", dense_query),
    limit=50,
)

sparse_hits = qdrant.search(
    collection_name="docs",
    query_vector=("sparse", sparse_query),
    limit=50,
)

# Объединение результатов: например, по взвешенной сумме скорингов
final = fuse_results(
    dense_hits,
    sparse_hits,
    dense_weight=0.7,
    sparse_weight=0.3,
)

Пояснение кода:

Код показывает типичный pipeline hybrid search.

Сначала запрос преобразуется в dense-вектор через embedding-модель: это даёт семантическое представление запроса. Затем тот же запрос преобразуется в sparse-представление: это набор токенов или признаков с весами, которые важны для точного совпадения.

После этого выполняются два отдельных поиска по одной коллекции:

  • dense search возвращает документы, близкие по смыслу;
  • sparse search возвращает документы, где сильны ключевые слова запроса.

Дальше результаты объединяются. Обычно это делают через:

  • взвешенную сумму скорингов;
  • rank fusion;
  • нормализацию scores перед объединением.

На собеседовании важно сказать, что Qdrant сам по себе хранит оба типа представления и позволяет строить retrieval-пайплайн, где dense и sparse дополняют друг друга.

Ключевые моменты:

  • Dense search лучше работает по смыслу, sparse — по точным словам и редким терминам.
  • Hybrid search уменьшает риск пропустить релевантный документ из-за синонимов или, наоборот, из-за отсутствия exact-match.
  • В Qdrant обычно хранят несколько векторных представлений одной точки и ищут по каждому из них отдельно.
  • Итоговый список результатов получают через fusion: взвешивание, нормализацию или объединение рангов.
  • Hybrid особенно полезен для технического поиска, e-commerce и RAG, где важны и смысл, и точные термины.
  • Практически dense часто даёт recall по смыслу, sparse помогает precision на специфичных токенах.