Гибридный поиск в RAG — это одновременный запуск двух поисков по базе знаний: полнотекстового (BM25 или аналог), который точно находит слова, коды и номера, и векторного, который находит перефразированные вопросы по смыслу. Затем два списка объединяют в один, чаще всего методом Reciprocal Rank Fusion (RRF). Настраивают его так: собирают набор реальных вопросов, замеряют каждый поиск отдельно, подключают морфологию русского языка, индексируют одни и те же фрагменты в оба индекса, объединяют выдачу через RRF и подбирают веса на отложенной части вопросов.
Материал подготовлен AIrassvet 24 октября 2026 года для ИТ-руководителей, аналитиков и разработчиков, которые запускают корпоративного ассистента или поиск по базе знаний и видят, что он не находит номер договора, артикул или код ошибки. Инструкция опирается на документацию Qdrant, Elasticsearch, Weaviate, PostgreSQL и pgvector, а также на исходную статью о методе RRF. Собственных замеров для статьи мы не проводили.
Содержание
- Кратко
- Что входит и не входит в инструкцию
- Как работает гибридный поиск
- Что понадобится до старта
- Пошаговая настройка гибридного поиска
- Пример для PostgreSQL с pgvector
- Типовые ошибки
- Копируемый шаблон конфигурации и протокола теста
- Частые вопросы
- Первоисточники и метод
Кратко
- Два поиска закрывают слабые места друг друга. Векторный поиск понимает перефразировки, полнотекстовый точно совпадает по словам. Документация Qdrant называет такое сочетание способом получить смысловое понимание и точное совпадение слов одновременно.
- Объединяйте по местам в выдаче, а не по сырым оценкам. Оценки BM25 и косинусная близость измеряются в разных шкалах. RRF складывает величины вида 1/(k + место), поэтому вверх поднимаются фрагменты, которые высоко стоят в обоих списках.
- Константа k в разных системах разная. В Elasticsearch по умолчанию 60, как в исходной статье о RRF, в Qdrant — 2. При переносе настроек это нужно учитывать.
- Веса подбирают только на тесте. Qdrant советует: без набора вопросов с известными ответами оставлять равные веса, а с набором — подбирать на одной половине и проверять на другой.
- Русскому тексту нужна морфология. В PostgreSQL для этого есть конфигурация полнотекстового поиска
russianсо стеммером Snowball.
Что входит и не входит в инструкцию
Инструкция охватывает первый этап поиска в RAG-системе: как найти кандидатов двумя способами и объединить их. Мы не разбираем нарезку документов на фрагменты — об этом отдельная статья «Чанкинг документов для RAG», и не повторяем, что такое векторная база, — см. «Что такое векторная база данных». Второй этап, переранжирование кандидатов отдельной моделью, описан в статье «Реранкер в RAG: когда нужен».
Как работает гибридный поиск
Запрос пользователя уходит в два поиска параллельно:
- Полнотекстовый (лексический). Ищет фрагменты, где встречаются слова запроса. Классический алгоритм ранжирования — BM25. Он сильнее всего там, где важны точные значения: «договор № 47-К», «ошибка E-102», фамилия, название пункта регламента.
- Векторный (семантический). Превращает запрос в вектор моделью эмбеддингов и ищет ближайшие по смыслу фрагменты. Он находит ответ на «как вернуть деньги клиенту», даже если в регламенте написано «порядок возврата оплаты».
Каждый поиск возвращает свой упорядоченный список. Дальше списки объединяют. Самый распространённый способ — Reciprocal Rank Fusion (RRF), предложенный Кормаком, Кларком и Бюттхером в статье на конференции SIGIR 2009. Оценка фрагмента — сумма величин 1/(k + место) по всем спискам, где он встретился. В статье k = 60 выбрано на пилотном эксперименте; авторы пишут, что это значение оказалось близким к оптимальному, но выбор не критичен.
Пример расчёта (Calculated). Пусть k = 60, места считаются с единицы. Фрагмент А стоит первым в полнотекстовом списке и третьим в векторном: 1/61 + 1/63 ≈ 0,0164 + 0,0159 = 0,0323. Фрагмент Б стоит первым только в векторном списке: 1/61 ≈ 0,0164. В итоговой выдаче А окажется выше Б, потому что его подтвердили оба поиска.
Есть и альтернативы RRF. Weaviate смешивает оценки параметром alpha: по документации, alpha = 1 — чистый векторный поиск, alpha = 0 — чистый полнотекстовый. Qdrant кроме RRF предлагает метод DBSF, который нормализует оценки каждого поиска по их распределению, прежде чем сложить.
Модель эмбеддингов может сама давать и плотные, и разреженные (похожие на ключевые слова) векторы. Так устроена, например, BGE-M3: по карточке модели она поддерживает плотный, разреженный и многовекторный поиск, работает более чем со 100 языками, а для RAG авторы рекомендуют связку «гибридный поиск + переранжирование».
Что понадобится до старта
- Рабочий векторный поиск по базе знаний с выбранной моделью эмбеддингов. Если модель ещё не выбрана, поможет чек-лист выбора модели эмбеддингов.
- Движок с полнотекстовым поиском: PostgreSQL, Elasticsearch или OpenSearch, векторная база с поддержкой текстовых или разреженных запросов (например, Qdrant или Weaviate).
- Единые идентификаторы фрагментов. Один и тот же фрагмент должен иметь один ID в обоих индексах, иначе списки нельзя объединить.
- Набор вопросов с известными ответами: реальные вопросы сотрудников или клиентов и ID фрагментов, где лежит ответ. Нужны оба типа вопросов: с точными значениями (номера, коды, фамилии) и сформулированные обычным языком.
- Метрика: доля вопросов, для которых нужный фрагмент попал в первые k результатов (recall@k или Hit@k). Как считать метрики качества RAG, описано в статье «Точность RAG и галлюцинации».
- Ответственный за набор вопросов со стороны бизнеса: он подтверждает, какой фрагмент считается правильным ответом.
Пошаговая настройка гибридного поиска
Шаг 1. Разметьте вопросы по типам
Разделите набор на группы: вопросы с идентификаторами (номер, артикул, код), вопросы с терминами компании и аббревиатурами, вопросы обычным языком. Гибридный поиск часто помогает неравномерно: группе с идентификаторами — сильно, группе с перефразировками — меньше. Без разметки этот эффект потеряется в общем среднем.
Шаг 2. Замерьте каждый поиск отдельно
Прогоните весь набор через чистый векторный поиск и через чистый полнотекстовый. Запишите recall@k по каждой группе вопросов. Это базовая линия: если полнотекстовый поиск нигде не находит то, что пропускает векторный, гибрид не даст прироста, и проблему нужно искать в нарезке документов или в модели эмбеддингов.
Шаг 3. Настройте полнотекстовый поиск под русский язык
Без морфологии запрос «договоры поставки» не найдёт фрагмент со словами «договор поставки». В PostgreSQL используйте конфигурацию russian: по документации словари Snowball приводят разные формы слова к общей основе и убирают стоп-слова. В других движках включите анализатор для русского языка.
Отдельно проверьте вопросы с идентификаторами: убедитесь, что коды вида «47-К» или «E-102» после разбора текста ищутся так, как пользователи их вводят. Если нет, храните такие значения в отдельном поле метаданных и ищите по нему точным совпадением.
Шаг 4. Проиндексируйте одни и те же фрагменты в оба индекса
Полнотекстовый и векторный индексы строятся из одной и той же нарезки документов с одинаковыми ID. Метаданные (документ, раздел, дата действия, уровень доступа) тоже должны совпадать: фильтры по правам доступа применяются в обоих поисках до объединения, иначе в выдачу попадёт фрагмент, который сотруднику видеть нельзя.
Шаг 5. Берите кандидатов с запасом
Каждый поиск должен возвращать больше результатов, чем нужно в итоге. В примере из документации Qdrant каждый из двух поисков возвращает 20 результатов, а после объединения остаётся 10. В примере Elasticsearch размер окна rank_window_size равен 50; документация отмечает, что большее окно улучшает релевантность ценой производительности.
Шаг 6. Объедините списки через RRF
Начните с RRF с равными весами. Учтите значения по умолчанию:
| Система | Константа k по умолчанию | Что ещё настраивается |
|---|---|---|
Elasticsearch, ретривер rrf |
60 (rank_constant, не меньше 1) |
rank_window_size, по умолчанию равен size |
Qdrant, запрос rrf |
2 (места считаются с нуля) | k — с версии 1.16.0, веса списков — с версии 1.17.0 |
| Исходная статья о RRF | 60 | — |
Чем меньше k, тем сильнее итог зависит от первых мест каждого списка. Поэтому настройки, подобранные в одной системе, нельзя просто перенести в другую.
Шаг 7. Подберите веса на отложенной части вопросов
Если один поиск заметно сильнее на ваших данных, дайте ему больший вес. В Qdrant вес 3,0 у первого списка и 1,0 у второго означает, что третье место в первом списке ценится как первое во втором. Подбирайте веса на половине набора вопросов, а итог проверяйте на другой половине: документация Qdrant предупреждает, что замер на тех же вопросах, на которых подбирали веса, завышает результат. Без такого набора Qdrant рекомендует оставить веса по умолчанию.
Шаг 8. Решите, нужен ли реранкер
Гибридный поиск расширяет круг кандидатов, а реранкер точнее упорядочивает их. Если нужный фрагмент уже попадает в первые 20–50 кандидатов, но не в первые 5, следующий шаг — реранкер. Если его нет даже среди кандидатов, переранжирование не поможет: возвращайтесь к шагам 3–5.
Шаг 9. Зафиксируйте конфигурацию и перепроверяйте её
Сохраните вместе с индексом: модель эмбеддингов, языковую конфигурацию полнотекстового поиска, размеры окон кандидатов, метод объединения, k и веса. Qdrant советует перенастраивать веса при смене модели эмбеддингов или нарезки, при заметном изменении корпуса документов или регулярно на свежей выборке вопросов.
Пример для PostgreSQL с pgvector
README pgvector предлагает сочетать векторный поиск со встроенным полнотекстовым поиском PostgreSQL и объединять результаты через RRF или реранкер. Ниже — учебный пример запроса; адаптируйте имена таблиц, окна и k под свою систему и проверяйте на тесте.
-- Полнотекстовый индекс по русской морфологии
ALTER TABLE chunks
ADD COLUMN tsv tsvector
GENERATED ALWAYS AS (to_tsvector('russian', content)) STORED;
CREATE INDEX chunks_tsv_idx ON chunks USING GIN (tsv);
-- Гибридный поиск: два списка по 40 кандидатов и RRF с k = 60
WITH semantic AS (
SELECT id, ROW_NUMBER() OVER (ORDER BY embedding <=> $1) AS rank
FROM chunks
ORDER BY embedding <=> $1
LIMIT 40
),
keyword AS (
SELECT id, ROW_NUMBER() OVER (ORDER BY ts_rank_cd(tsv, query) DESC) AS rank
FROM chunks, websearch_to_tsquery('russian', $2) AS query
WHERE tsv @@ query
ORDER BY ts_rank_cd(tsv, query) DESC
LIMIT 40
)
SELECT COALESCE(s.id, k.id) AS id,
COALESCE(1.0 / (60 + s.rank), 0) + COALESCE(1.0 / (60 + k.rank), 0) AS rrf_score
FROM semantic s
FULL OUTER JOIN keyword k ON s.id = k.id
ORDER BY rrf_score DESC
LIMIT 10;
Здесь $1 — вектор запроса, $2 — текст запроса. Учтите: встроенные функции ранжирования PostgreSQL — не BM25. По документации, ts_rank учитывает частоту совпавших лексем, а ts_rank_cd — плотность их покрытия. Для RRF важен только порядок, поэтому для старта этого достаточно; если тест покажет слабость полнотекстовой части, сравните её с движком, где есть BM25.
Типовые ошибки
- Складывать сырые оценки двух поисков. Оценка BM25 и косинусная близость лежат в разных шкалах, и простая сумма отдаёт победу тому поиску, у которого числа больше. Используйте RRF, нормализацию вроде DBSF или параметр смешивания, предусмотренный движком.
- Разные ID фрагментов в двух индексах. Объединение молча перестаёт работать: каждый фрагмент встречается только в одном списке.
- Фильтр доступа только в одном поиске. Фрагмент, отсеянный в векторном поиске, возвращается через полнотекстовый.
- Нет морфологии. Полнотекстовый поиск по русскому тексту без стемминга пропускает словоформы и выглядит бесполезным.
- Перенос k и весов между системами. k = 60 в Elasticsearch и k = 2 в Qdrant дают разное поведение при одинаковых весах.
- Подбор весов и замер на одних и тех же вопросах. Результат выглядит лучше, чем будет у пользователей.
- Маленькое окно кандидатов. Если каждый поиск возвращает только 5 результатов, объединять почти нечего.
- Ожидание чуда от гибрида. Если ответ разрезан между фрагментами или документ плохо распознан, гибридный поиск этого не исправит.
Копируемый шаблон конфигурации и протокола теста
КОНФИГУРАЦИЯ ГИБРИДНОГО ПОИСКА — версия [__]
Дата: [__] Ответственный: [__]
Индекс и данные
☐ Версия нарезки документов: [__]
☐ Модель эмбеддингов и её версия: [__]
☐ Полнотекстовый движок: [PostgreSQL / Elasticsearch / OpenSearch / Qdrant / другое]
☐ Языковая конфигурация: [russian / другое]
☐ Поля для точного поиска идентификаторов: [__]
☐ Одинаковые ID фрагментов в обоих индексах: [да / нет]
☐ Фильтры доступа применяются в обоих поисках: [да / нет]
Объединение
☐ Окно кандидатов, полнотекстовый: [__]
☐ Окно кандидатов, векторный: [__]
☐ Метод: [RRF / DBSF / alpha / другое]
☐ k: [__] Веса: полнотекстовый [__], векторный [__]
☐ Итоговое число фрагментов для модели: [__]
☐ Реранкер: [нет / модель __]
ПРОТОКОЛ ТЕСТА
Набор вопросов: [__] шт., из них с идентификаторами [__], обычным языком [__]
Разбиение: подбор весов [__] шт. / проверка [__] шт.
| Вариант | recall@k (идентификаторы) | recall@k (обычный язык) | recall@k (всего) |
|------------------|---------------------------|-------------------------|------------------|
| Только векторный | [__] | [__] | [__] |
| Только текстовый | [__] | [__] | [__] |
| Гибрид, RRF | [__] | [__] | [__] |
| Гибрид + веса | [__] | [__] | [__] |
Провалы на проверочной части (вопрос → причина): [__]
Решение и причина: [__]
Когда перепроверить: при смене модели, нарезки или заметном изменении корпуса
Частые вопросы
Что такое гибридный поиск в RAG?
Гибридный поиск — это сочетание полнотекстового и векторного поиска по одной базе знаний. Полнотекстовый находит точные слова, коды и номера, векторный — фрагменты, близкие по смыслу. Два списка результатов объединяют в один, обычно методом RRF, и лучшие фрагменты передают языковой модели для ответа.
Когда гибридный поиск нужен, а когда нет?
Он нужен, когда пользователи ищут по точным значениям: номерам договоров, артикулам, кодам ошибок, фамилиям, названиям пунктов. Если в вашем наборе вопросов полнотекстовый поиск не находит ничего, что пропускает векторный, гибрид прироста не даст. Решение принимают по замеру recall@k на своих вопросах, а не заранее.
Какое значение k выбрать для RRF?
Начните со значения по умолчанию вашей системы: в Elasticsearch это 60, в Qdrant — 2. В исходной статье о RRF k = 60 оказалось близким к оптимальному, а выбор — не критичным. Меняйте k только если тест на отложенных вопросах показывает улучшение, и не переносите его между системами без проверки.
Можно ли сделать гибридный поиск в PostgreSQL?
Да. pgvector отвечает за векторный поиск, встроенный полнотекстовый поиск PostgreSQL с конфигурацией russian — за поиск по словам, а объединение делается SQL-запросом с RRF. Встроенное ранжирование PostgreSQL не является BM25, но для RRF важен порядок результатов, поэтому для старта этого обычно достаточно. Качество проверяйте на своих вопросах.
Чем гибридный поиск отличается от реранкера?
Гибридный поиск — первый этап: он собирает кандидатов двумя способами и объединяет списки. Реранкер — второй этап: отдельная модель заново упорядочивает уже найденных кандидатов. Гибрид помогает, когда нужного фрагмента нет среди кандидатов, реранкер — когда он есть, но стоит слишком низко. Их часто используют вместе.
Первоисточники и метод
- Qdrant: Hybrid Queries — формула RRF, k по умолчанию, веса, DBSF, советы по подбору весов.
- Elasticsearch: Reciprocal rank fusion — параметры
rank_constantиrank_window_size. - Cormack, Clarke, Büttcher. Reciprocal Rank Fusion outperforms Condorcet and individual Rank Learning Methods, SIGIR 2009 — исходный метод и выбор k = 60.
- Weaviate: Hybrid search — параметр alpha.
- PostgreSQL: словари полнотекстового поиска и ранжирование.
- pgvector — гибридный поиск с полнотекстовым поиском PostgreSQL.
- Карточка модели BGE-M3 — плотные и разреженные векторы, рекомендация гибридного поиска.
Все источники проверены 24 октября 2026 года. Порядок шагов собран из рекомендаций этой документации; пример расчёта RRF выполнен нами по формуле из статьи. SQL-запрос — учебный пример, его нужно проверить на вашей версии PostgreSQL и данных. Мы не приводим цифр прироста качества от гибридного поиска: он зависит от документов и вопросов конкретной компании.
Как AIrassvet помогает настроить гибридный поиск в базе знаний
Гибридный поиск — часть RAG-системы, и его настройка зависит от документов и вопросов конкретной компании. Среди направлений, указанных на сайте AIrassvet, есть те, что закрывают эту работу:
- RAG и корпоративные базы знаний: полнотекстовый и векторный индексы с общими ID, морфологией русского языка и фильтрами доступа;
- подготовка данных: сбор набора реальных вопросов с подтверждёнными ответами и разметка по типам;
- тестирование и запуск: сравнение векторного, полнотекстового и гибридного вариантов на ваших вопросах и фиксация выбранной конфигурации.
Первый шаг — выбрать один процесс, где сотрудники ищут ответы в документах, и зафиксировать текущий результат, источники данных, ограничения и критерий приёмки.
Итог: гибридный поиск настраивают по тесту
Гибридный поиск соединяет точность полнотекстового поиска и понимание смысла векторного. Чтобы он работал, оба индекса строят из одних и тех же фрагментов с общими ID и фильтрами доступа, полнотекстовый поиск настраивают на русскую морфологию, а списки объединяют через RRF.
Начните с равных весов и значения k по умолчанию вашей системы, сравните варианты на наборе реальных вопросов и подбирайте веса только на отложенной части. Если нужный фрагмент попадает в кандидаты, но стоит низко, следующим шагом станет реранкер.






