Hybrid Search та Reranking: як підняти якість RAG на 15–40% без зміни моделі

Updated:
Hybrid Search та Reranking: як підняти якість RAG на 15–40% без зміни моделі

Ваш RAG-пайплайн працює. Відповіді генеруються, retrieval повертає результати. Але користувач шукає get_user_v2 — і замість документації отримує статтю про user management. Або питає про "стаття 42 ЗУ про захист персональних даних" — і vector search повертає три чанки про GDPR, але жоден не містить тексту потрібної статті. Спойлер: проблема не в LLM і не в embedding-моделі. Проблема в тому, що чистий vector search шукає сенс — але іноді потрібен текст. Hybrid search + reranking закривають цю діру і дають +15–25% якості retrieval у реальних проєктах без жодної зміни моделі.

⚡ Коротко

  • Vector search vs BM25: сенс vs ключові слова — потрібна комбінація
  • Hybrid search: об’єднання через RRF, а не нормалізацію скорів
  • Reranking: +8–25% якості за рахунок cross-encoder
  • 🎯 Ви отримаєте: коли і як застосовувати hybrid + reranking з кодом
  • 👇 Нижче — архітектура, формули та приклади

📚 Зміст статті

🎯 Розділ 1. Два типи пошуку: чому кожен сильний по-своєму

BM25 (keyword search) знаходить точні збіги — артикули, ID, назви методів. Dense vector search знаходить семантично схожі документи — синоніми, перефразування, cross-lingual запити. Жоден з цих підходів не є достатнім для production RAG: BM25 не розуміє сенс, а vector search "розмиває" точні значення.

Якщо vector search — це "знайди щось схоже за змістом", то BM25 — це "знайди документ, де є саме це слово". Production RAG потребує обох.

BM25 (Keyword Search): чому алгоритм 1994 року досі живий

BM25 (Best Matching 25) — це класичний алгоритм ранжування, який оцінює релевантність документа за трьома факторами: частота терміну в документі (TF), зворотна частота по корпусу (IDF) і довжина документа. Алгоритм був формалізований Robertson та Walker у 1994 році і досі є стандартом keyword-пошуку в Elasticsearch, OpenSearch і більшості пошукових систем.

Чому він не помер за 30 років? Тому що для певних типів запитів нічого кращого немає. Коли користувач шукає SKU-4521, get_user_v2 або "стаття 42" — це exact match задача. Embedding-модель перетворює SKU-4521 на вектор, який описує загальний "сенс" товарного артикулу, але різниця між 4521 і 4522 у цьому векторі мінімальна. BM25 знаходить точний збіг за мілісекунди — без нейронних мереж, без GPU, без ембедингів.

Де BM25 незамінний: артикули і коди товарів, назви функцій і API-ендпоінтів, номери документів і статей законів, рідкісні терміни і абревіатури, точні цитати.

Обмеження BM25: "автомобіль" ≠ "машина". Якщо користувач написав "скасувати підписку", а в документі — "відмовитись від тарифу", BM25 не знайде нічого, бо жодного спільного слова немає.

Dense Vector Search (Semantic): сила контексту

Dense vector search працює інакше. Запит і документи перетворюються на числові вектори (embeddings), і пошук відбувається за cosine similarity — кутом між векторами у просторі сенсу. "Скасувати підписку" і "відмовитись від тарифу" отримають близькі вектори, бо embedding-модель навчилась, що ці фрази означають одне і те саме.

Де dense vector search незамінний: семантичний пошук по синонімах і перефразуваннях, cross-lingual запити (запит українською знаходить документ англійською), запити природною мовою ("як зменшити витрати на інфраструктуру").

Обмеження: embedding "розмиває" точні значення. Два різних артикули отримують майже однаковий вектор. Короткі запити з одного-двох слів дають нечіткий вектор. Детально про ці обмеження — у статті про embeddings

Таблиця: коли що працює

Тип запиту BM25 Dense Vector Hybrid
get_user_v2 (точний термін) ✅ точний збіг ❌ розмиває
"як скасувати підписку" (семантичний) ❌ немає збігів слів ✅ семантика
"стаття 42 закону про дані" (змішаний) ✅ "стаття 42" ✅ "захист даних" ✅✅ обидва сигнали
"pricing" (1 слово) ⚠️ занадто широко ⚠️ розмитий вектор ⚠️ потрібен query transform
  • ✔️ BM25: незамінний для exact match — ID, артикули, назви функцій
  • ✔️ Dense vectors: незамінні для семантичного пошуку — синоніми, перефразування, cross-lingual
  • ✔️ Жоден з підходів не є самодостатнім для production RAG

Висновок розділу: BM25 і dense vector search — це не конкуренти, а комплементарні інструменти. Перший знаходить слова, другий — сенс. Production RAG потребує обох.

📌 Розділ 2. Hybrid Search: як об'єднати обидва підходи

Hybrid search виконує BM25 і dense vector search паралельно, а потім об'єднує результати через Reciprocal Rank Fusion (RRF) — алгоритм, який використовує позиції у рейтингу замість скорів. RRF не потребує нормалізації і стабільно працює з різнотипними джерелами. На бенчмарках Weaviate (2025) hybrid search з RRF перевершує best-performing single-method на 2.6–13.4 пунктів nDCG@10.

Головна проблема об'єднання результатів з BM25 і vector search — їхні скори живуть на різних шкалах і їх не можна просто скласти. RRF елегантно обходить цю проблему, працюючи з рангами, а не з числами.

Reciprocal Rank Fusion (RRF): простий і надійний метод злиття

RRF був запропонований Cormack, Clarke та Buettcher у 2009 році (SIGIR '09) і з тих пір став стандартом де факто для hybrid search. Формула:

score(d) = Σ  1 / (k + rank(d))

де rank(d) — позиція документа у кожному окремому рейтингу, а k — константа згладжування (стандартне значення: 60).

Чому k = 60? Як пояснює документація Elasticsearch, ця константа запобігає надмірному впливу першої позиції. Без згладжування різниця між рангом 1 (score = 1.0) і рангом 2 (score = 0.5) — двократна. З k = 60 різниця між рангом 1 (1/61 ≈ 0.0164) і рангом 2 (1/62 ≈ 0.0161) — мінімальна, що робить злиття стабільнішим.

Чому RRF кращий за лінійну комбінацію скорів? Три причини. По-перше, BM25 повертає скори в довільному діапазоні (від 0 до десятків), а cosine similarity — від -1 до 1. Нормалізація цих шкал до спільного діапазону — нетривіальна задача, яка залежить від розподілу скорів у конкретному корпусі. RRF працює виключно з позиціями, ігноруючи абсолютні скори. По-друге, RRF нечутливий до outlier'ів: один документ з аномально високим BM25-скором не "перетягне" на себе весь рейтинг. По-третє, як зазначає OpenSearch (2025), RRF природно підсилює документи, які з'являються у верхніх позиціях кількох рейтингів одночасно — що є сильним сигналом релевантності.

Приклад з числами

BM25 повертає: [Doc A (rank 1), Doc C (rank 2), Doc B (rank 3)]

Dense повертає: [Doc B (rank 1), Doc A (rank 2), Doc D (rank 3)]

RRF-скори (k=60):

  • Doc A: 1/(60+1) + 1/(60+2) = 0.0164 + 0.0161 = 0.0325 ← виграє
  • Doc B: 1/(60+3) + 1/(60+1) = 0.0159 + 0.0164 = 0.0323
  • Doc C: 1/(60+2) + 0 = 0.0161
  • Doc D: 0 + 1/(60+3) = 0.0159

Результат: [A, B, C, D]. Doc A виграє, бо стабільно у верхніх позиціях обох рейтингів.

Weighted Hybrid: коли потрібен контроль через α (alpha)

RRF дає рівну вагу кожному методу пошуку. Але не завжди це оптимально. Для технічної документації з великою кількістю точних термінів BM25 має бути "голосніше". Для customer support з природномовними запитами — dense vectors важливіші.

Більшість vector DB підтримують параметр α (alpha), де α = 0.0 — чистий BM25, α = 1.0 — чистий vector search. Weaviate документація дозволяє виставити alpha безпосередньо у запиті. Elasticsearch з версії 8.x підтримує weighted RRF — кожен retriever отримує свою вагу.

Рекомендації по доменах (орієнтовні — тестуйте на своїх даних):

  • Технічна документація, код: α = 0.3–0.4 (більше keyword)
  • Загальний контент, customer support: α = 0.6–0.7 (більше семантики)
  • Юридичні тексти: α = 0.4–0.5 (баланс: точні статті + семантичний контекст)
  • E-commerce каталоги: α = 0.3–0.5 (артикули + описи товарів)

Як підібрати α на практиці: візьміть 20–30 реальних запитів з відомими правильними відповідями, прогоніть пошук з α від 0.1 до 0.9 з кроком 0.1, порівняйте recall@5. Це займає годину і дає конкретну відповідь для вашого домену.

Які Vector DB підтримують hybrid нативно

Vector DB Hybrid підтримка Метод злиття Примітка
Qdrant ✅ нативно RRF, DBSF Sparse vectors через BM25 або SPLADE, prefetch multi-stage
Weaviate ✅ нативно RRF, Relative Score Fusion, Learned Fusion (v1.25+) Найпростіший API: один параметр alpha
Elasticsearch ✅ нативно RRF, Weighted RRF, Linear Потужно, але складніший setup. Weighted RRF з v8.x
pgvector ⚠️ вручну Окремий BM25 (ts_vector) + злиття в коді Підходить якщо Postgres вже є, але вимагає ручної роботи
ChromaDB ✅ з v0.6+ RRF через Rrf() API Вимагає sparse vector index, не доступно у legacy API

Детальне порівняння vector DB — у статті ChromaDB, Qdrant або pgvector: як обрати.

⚠️ Підводні камені

Невірний α вбиває якість замість покращення. На бенчмарку WANDS (e-commerce) RRF додав лише +1.7% Mean NDCG над dense-only. Якщо ваші запити переважно семантичні і без точних термінів — hybrid може не дати помітного приросту. Вимірюйте, не вірте дефолтам.

Подвійна індексація = подвійні ресурси. Hybrid search вимагає і інвертованого індексу (для BM25), і векторного. Це більше RAM і більше часу на індексацію. Для невеликих проєктів (<10K документів) додатковий overhead може бути невиправданим.

α-рекомендації по доменах — це орієнтири, не абсолютні правила. Оптимальне значення залежить від вашого корпусу, мови, типу запитів. Завжди тестуйте на реальних даних.

  • ✔️ RRF — стандарт де факто для hybrid search, працює з рангами замість скорів
  • ✔️ Weighted hybrid (α) дає контроль — але потребує тестування на реальних запитах
  • ✔️ Qdrant, Weaviate, Elasticsearch підтримують hybrid нативно

Висновок розділу: На мою думку Hybrid search — перший і найпростіший крок для підвищення якості RAG. Якщо ваші запити містять точні терміни — ефект (ROI) помітний одразу.

Hybrid Search та Reranking: як підняти якість RAG на 15–40% без зміни моделі

📌 Reranking: другий етап, який змінює все

Reranking — це другий етап retrieval, де cross-encoder модель переоцінює кожну пару (запит, документ) і переупорядковує кандидатів за точнішою оцінкою релевантності. Типова архітектура: hybrid search повертає топ-50, reranker обирає фінальні 5–10 для LLM. За даними Agentset Reranker Leaderboard (2026), reranking стабільно покращує nDCG@10 і hit rate незалежно від embedding-моделі.

Bi-encoder (embedding model) оцінює запит і документ окремо — швидко, але грубо. Cross-encoder (reranker) оцінює пару разом — точно, але повільно. Перший — для відсіювання, другий — для точного ранжування.

Чому top-k з першого етапу недостатньо

Embedding-модель (bi-encoder) перетворює запит і документ на вектори незалежно один від одного. Це робить пошук швидким — можна порівнювати мільйони документів за мілісекунди. Але ця швидкість коштує точності: модель не "бачить" запит і документ одночасно, тому може не вловити тонкий зв'язок між ними.

Cross-encoder (reranker) працює інакше. Він приймає пару (запит + документ) як єдиний вхід і обробляє їх разом через всі шари трансформера. Це дає значно точнішу оцінку релевантності — але кожна пара вимагає окремого проходу через модель. На 1 мільйоні документів це зайняло б хвилини замість мілісекунд.

Аналогія: bi-encoder — це сканування 1000 резюме за ключовими словами. Cross-encoder — це співбесіда з кожним кандидатом. Очевидно, що на першому етапі потрібно скоротити список, а на другому — ретельно обрати найкращих.

Two-Stage Retrieval: архітектура

Запит → [Stage 1: Hybrid Search → top-50] → [Stage 2: Reranker → top-5] → LLM

Stage 1 (Hybrid Search): швидкий, грубий відбір. BM25 + dense vectors + RRF повертають ~50 кандидатів за 20–50ms. Мета — максимізувати recall: переконатись, що правильний документ є десь у списку.

Stage 2 (Reranker): точне переранжування. Cross-encoder оцінює кожну з 50 пар (запит, документ) і обирає фінальні 5–10. Час: 100–300ms залежно від моделі і кількості документів. Мета — максимізувати precision: поставити найрелевантніше на перше місце.

Чому 50, а не 20 або 200? Це trade-off recall vs latency. Менше 20 кандидатів — ризик, що релевантний документ не потрапить у вибірку. Більше 100 — reranker стає bottleneck за latency. ZeroEntropy (2026) рекомендує 50 документів для чат-ботів (де важлива швидкість) і 100–200 для задач comprehensive search.

Lost in the Middle: як reranking вирішує проблему позиційного bias

LLM краще використовують інформацію з початку і кінця контекстного вікна, ігноруючи середину. Це ефект "lost in the middle", задокументований у Stanford TACL дослідженні: падіння точності на 20–50% для інформації, розміщеної в середині довгого контексту. Детально про цей ефект — у статті про контекстне вікно LLM, Розділ 3.

Reranker вирішує це побічно, але ефективно. Він не просто фільтрує — він упорядковує. Якщо найрелевантніший чанк стоїть на позиції 47 з 50, reranker підніме його на позицію 1. А оскільки у LLM контекст формується з топ-5 результатів reranker'а, найважливіша інформація автоматично опиняється на початку контексту — саме там, де LLM працює найефективніше.

Порівняння Rerankers (2026)

За даними Agentset Reranker Leaderboard (2026) та BSWEN порівняння (2026):

Reranker Тип Якість Latency (50 docs) Ціна Коли обирати
Zerank-2 API Найвища (ELO лідер) ~600ms ~$0.05/1K запитів Найкраща якість, production
Voyage Rerank 2.5 API Висока ~600ms Порівнянна з Cohere Баланс якість/швидкість
Cohere Rerank 3.5 API Висока ~600ms $2/1K запитів Production, reliability, SLA
bge-reranker-v2-m3 Self-hosted Висока ~80ms (GPU), ~350ms (CPU) $0 (потрібен GPU) Конфіденційні дані, контроль
mxbai-rerank-large-v2 Self-hosted Висока (BEIR лідер) ~150ms (GPU) $0 (Apache 2.0) Open-source production
cross-encoder/ms-marco Self-hosted Середня ~300ms (GPU) $0 Прототипування, бюджет

Важливий нюанс: за даними Agentset, Cohere v3.5 — найшвидший серед API-рішень, але за якістю (ELO score) поступається Zerank і Voyage. BGE-v2-m3 на GPU конкурує з API-рішеннями за latency при нульовій вартості за запит, що робить його оптимальним вибором для self-hosted production.

Коли reranking НЕ допоможе

❌ Поганий chunking → reranker сортує сміття → сміття залишається сміттям. Якщо важлива інформація розірвана між чанками — навіть ідеальний reranker не склеїть її назад. Детально — у статті про chunking strategies.

❌ Невірна embedding-модель → hybrid search не знаходить релевантних кандидатів → reranker'у нічого сортувати. Якщо модель погано працює з вашою мовою або доменом — спочатку замініть її.

❌ Брудні дані (дублікати, застарілий контент) → reranker підніме "найкращий" дублікат, але проблема залишиться. Garbage in — garbage out.

⚠️ Підводні камені

"+48% якості" — це маркетинг. Цифри Pinecone/Superlinked — best-case на ідеальних бенчмарках. У реальних проєктах цільтесь у +15–25% покращення retrieval. Якщо на вашому корпусі ефект менше +5% — проблема, імовірно, не в retrieval.

Latency budget. Reranker додає 100–300ms до кожного запиту. Для чат-ботів з очікуваним response time < 2s це суттєва частка. Рахуйте повний pipeline: embedding (20ms) + hybrid search (30ms) + reranker (200ms) + LLM (500–1500ms) = 750–1750ms.

GPU для self-hosted. BGE-reranker-v2 на CPU дає ~350ms latency. На GPU — ~80ms. Різниця у 4x може визначити, чи вписуєтесь ви у latency budget. BSWEN (2026) описує як автор ледь не відмовився від BGE через тестування на CPU.

  • ✔️ Two-stage retrieval (hybrid → reranker) — стандартна production-архітектура
  • ✔️ Reranker вирішує і precision, і lost in the middle
  • ✔️ Self-hosted (BGE-v2-m3) конкурує з API-рішеннями на GPU

З мого досвіду: Reranking — другий за ROI крок після hybrid search. Додає 100–300 ms latency, але суттєво підвищує precision і усуває позиційний bias. Головне обмеження: reranker не виправить поганий chunking або брудні дані.

📌 Query Transformation: коли запит занадто "бідний"

Query transformation — це техніки розширення або переформулювання запиту перед пошуком. Multi-query генерує кілька варіантів запиту для підвищення recall. HyDE створює "гіпотетичну відповідь" і шукає по її вектору. Step-back prompting узагальнює запит до ширшого рівня. Кожна техніка додає 0.5–2 секунди latency через додатковий LLM-виклик.

Hybrid search + reranking вирішують 80% проблем retrieval. Але залишаються випадки, коли сам запит — недостатньо інформативний для пошуку. Цей розділ — для тих 20%.

Multi-query

LLM генерує 3–5 варіантів оригінального запиту, кожен шукається окремо, результати об'єднуються через RRF. Техніка формалізована як RAG-Fusion (Rackauckas, 2024) і добре інтегрується з existing hybrid pipeline.

Коли працює: неоднозначні запити ("як це налаштувати" — що саме?), запити з неявним контекстом. Коли зайвий: чіткі конкретні запити, де одного формулювання достатньо. Latency: +500ms–1.5s (один LLM-виклик для генерації варіантів).

HyDE (Hypothetical Document Embeddings)

LLM генерує "гіпотетичну ідеальну відповідь" на запит, embedding цієї відповіді використовується для пошуку. Оригінальна стаття Gao et al. (2023).

Коли працює: короткий запит, довга очікувана відповідь. Запит "OAuth" → LLM генерує абзац про OAuth flow → embedding цього абзацу шукає схожі документи значно точніше, ніж embedding одного слова "OAuth".

⚠️ Ризик: на вузьких доменах (медицина, юриспруденція) LLM може згалюцинувати "гіпотетичний документ" з неправильними фактами — і пошук піде в хибному напрямку. Використовуйте HyDE тільки на загальних доменах, де LLM має достатні знання.

Latency: +1–2s (один LLM-виклик).

Step-back Prompting

LLM спочатку формулює ширше питання, потім шукає по ньому. Запит "чому bge-reranker-v2 повільніший на CPU" → step-back: "як працюють cross-encoder rerankers і які у них вимоги до hardware" → пошук по ширшому запиту знаходить загальну документацію, яка містить і відповідь на конкретне питання.

Коли працює: дуже специфічні запити, де прямий пошук не повертає результатів. Latency: +500ms–1s.

Latency Tax: таблиця

Техніка Додатковий час LLM-виклик Коли виправдано
Multi-query +0.5–1.5s ✅ 1 виклик Неоднозначні запити
HyDE +1–2s ✅ 1 виклик Короткі запити, загальний домен
Step-back +0.5–1s ✅ 1 виклик Вузькоспеціалізовані запити
Без трансформації 0 Чіткі конкретні запити

⚠️ Підводні камені

HyDE на вузьких доменах — ризик. Якщо LLM не має достатніх знань у вашому домені, "гіпотетичний документ" буде неправильним, і пошук знайде нерелевантні чанки. Тестуйте на 10–20 запитах перед впровадженням.

Latency складається. Multi-query + reranking = +2–3.5s до кожного запиту. Для інтерактивних чат-ботів це може бути неприйнятним. Для batch-processing або аналітичних задач — цілком виправдано.

Висновок розділу: Query transformation — це інструмент для специфічних випадків, не для всіх запитів. Впроваджуйте після hybrid search і reranking, і тільки якщо бачите конкретні проблеми з recall на певних типах запитів.

📌 Практика: мінімальний код для старту

Hybrid search на Qdrant реалізується через prefetch API з RRF fusion за ~15 рядків Python-коду. Для додавання reranking — ще ~10 рядків з Cohere API або sentence-transformers. Нижче — copy-paste ready приклади для обох варіантів.

Hybrid Search + RRF на Qdrant (Python)

Qdrant підтримує hybrid search нативно через Universal Query API з prefetch-механізмом. Приклад використовує вбудований BM25 та dense vectors:

from qdrant_client import QdrantClient, models

client = QdrantClient(url="http://localhost:6333")

def hybrid_search(query: str, limit: int = 10):
    """Hybrid search з RRF: dense + sparse (BM25)."""
    return client.query_points(
        collection_name="my_documents",
        prefetch=[
            # Stage 1a: Dense vector search
            models.Prefetch(
                query=models.Document(
                    text=query,
                    model="sentence-transformers/all-MiniLM-L6-v2",
                ),
                using="dense",
                limit=50,  # top-50 для recall
            ),
            # Stage 1b: Sparse (BM25) search
            models.Prefetch(
                query=models.Document(
                    text=query,
                    model="Qdrant/bm25",
                ),
                using="sparse",
                limit=50,
            ),
        ],
        # Злиття через RRF
        query=models.FusionQuery(fusion=models.Fusion.RRF),
        limit=limit,
    ).points

# Використання
results = hybrid_search("стаття 42 закону про захист даних")
for i, point in enumerate(results, 1):
    print(f"{i}. {point.payload.get('title')} (Score: {point.score:.4f})")

Код базується на офіційному туторіалі Qdrant і документації Query API.

Додаємо Reranking (Cohere API)

import cohere

co = cohere.Client("your-api-key")

def hybrid_search_with_rerank(query: str, top_k: int = 5):
    """Two-stage: hybrid search (top-50) → rerank (top-k)."""
    # Stage 1: Hybrid search
    candidates = hybrid_search(query, limit=50)

    # Формуємо документи для reranker
    docs = [point.payload.get("text", "") for point in candidates]

    # Stage 2: Reranking
    reranked = co.rerank(
        model="rerank-v3.5",
        query=query,
        documents=docs,
        top_n=top_k,
    )

    # Повертаємо переранжовані результати
    return [
        {
            "text": docs[r.index][:200],
            "relevance_score": r.relevance_score,
            "original_rank": r.index + 1,
        }
        for r in reranked.results
    ]

Як виміряти ефект: мінімальний A/B тест

Я раджу: Перед впровадженням на production вам потрібно переконатись, що hybrid + reranking дійсно покращує якість на ваших даних. Мінімальний тест:

  1. Зберіть 20–30 реальних запитів з відомими правильними відповідями (golden set)
  2. Прогоніть кожен запит через: (a) чистий vector search, (b) hybrid search, (c) hybrid + reranking
  3. Порівняйте recall@5 (чи правильна відповідь є у топ-5) для кожного варіанту
  4. Якщо recall зріс на <5% — проблема, ймовірно, не в retrieval, а в chunking або якості даних

Детально про метрики retrieval — у Як виміряти якість RAG: метрики, інструменти .

⚠️ Підводні камені

Версії бібліотек. Qdrant Query API (prefetch + fusion) доступний з версії 1.10+. Перевірте вашу версію qdrant-client. ChromaDB RRF API доступний з v0.6+.

Cohere pricing може змінитись. Станом на березень 2026 — $2/1K запитів для Rerank 3.5. Перевіряйте актуальний прайс перед впровадженням.

Self-hosted reranker потребує GPU. BGE-reranker-v2-m3 на CPU дає ~350ms на 50 документів — може не вписатись у latency budget. На GPU (навіть T4) — ~80ms.

Висновок розділу: Впровадження hybrid search + reranking — це години, не тижні. Головне — виміряти ефект на реальних запитах перед deployment на production.

💼 Діагностична матриця: що впроваджувати першим

Я раджу: Порядок впровадження: (1) hybrid search — мінімальний effort, максимальний ефект, (2) reranking — +100–300ms, але значне покращення precision, (3) query transformation — тільки якщо перші два кроки недостатні. Якщо жодне з трьох не допомагає — проблема в chunking або якості даних, не в retrieval.

Decision Tree: що впроваджувати першим

Ваш RAG не знаходить потрібне?
│
├─ Не знаходить точні терміни / ID / коди?
│  └─ → Додайте BM25 (Hybrid Search)
│     Latency: +0ms (паралельний пошук)
│     ROI: найшвидший
│
├─ Знаходить правильні документи, але не в топ-3?
│  └─ → Додайте Reranking
│     Latency: +100–300ms
│     ROI: високий для precision-critical задач
│
├─ Запити занадто короткі або неоднозначні?
│  └─ → Спробуйте Multi-query або HyDE
│     Latency: +0.5–2s
│     ROI: залежить від типу запитів
│
├─ Велика база, високий шум у результатах?
│  └─ → Reranking + збільшіть top-k Stage 1 до 100
│
└─ Нічого не допомагає?
   └─ → Проблема в chunking або якості даних, не в retrieval
      Перевірте: chunking strategies, embedding model, дані

Порядок впровадження

  1. Hybrid search — мінімальний effort, максимальний ефект. Якщо ваша Vector DB підтримує hybrid нативно (Qdrant, Weaviate, Elasticsearch) — це зміна конфігурації, не переписування пайплайну.
  2. Reranking — додає 100–300ms, але значно покращує precision. Почніть з Cohere API (мінімум інфраструктури), потім мігруйте на self-hosted BGE-v2-m3 якщо latency або вартість стануть проблемою.
  3. Query Transformation — тільки якщо 1 і 2 недостатньо. Кожна техніка додає LLM-виклик і latency. Впроваджуйте вибірково — не для всіх запитів, а для тих типів, де бачите проблему з recall.

❓ Часті питання (FAQ)

Чи потрібен hybrid search, якщо я використовую BGE-M3 з native sparse?

Так, але реалізація спрощується. BGE-M3 генерує dense і sparse вектори в одній моделі — вам не потрібен окремий BM25. Але RRF або інший fusion метод все одно потрібен для об'єднання результатів. У Qdrant це реалізується тим самим prefetch API.

Скільки коштує Cohere Rerank на 1000 запитів на день?

Станом на березень 2026: Cohere Rerank 3.5 коштує ~$2 за 1000 запитів (при reranking 50 документів на запит). 1000 запитів/день = ~$60/місяць. Для порівняння: self-hosted BGE-v2-m3 на T4 GPU (~$150–300/місяць) стає вигідніше при > 2500–5000 запитів/день.

Чи можна використовувати reranking без hybrid search?

Так. Reranking працює з будь-яким retriever — чистим vector search, BM25, або hybrid. Але комбінація hybrid + reranking дає найкращий результат, бо hybrid забезпечує ширший і різноманітніший набір кандидатів для reranker'а.

Як hybrid search впливає на latency?

Мінімально. BM25 і vector search виконуються паралельно, а RRF fusion додає лише обчислення рангів — мікросекунди. Основний додатковий час — reranking (100–300ms), не hybrid search як такий.

Чим RRF відрізняється від weighted sum?

RRF працює з рангами (позиціями), weighted sum — зі скорами (числовими оцінками). RRF не потребує нормалізації і стабільніший при різних розподілах скорів. Weighted sum дає більше контролю, але вимагає калібрування шкал — що не завжди можливо.

✅ Висновки

  • 🔹 Vector search сам по собі не достатній: розмиває точні терміни та короткі запити; BM25 закриває ці пробіли.
  • 🔹 Hybrid search (BM25 + dense + RRF): перший і простий крок для покращення якості.
  • 🔹 Reranking (cross-encoder): другий етап; +100–300ms, але +8–25% precision, вирішує "lost in the middle".
  • 🔹 Query transformation: для специфічних запитів, додає latency через LLM-виклик.
  • 🔹 Порядок впровадження: hybrid → reranking → query transform; якщо не допомагає — проблема в chunking або даних.
  • 🔹 Тестуйте на реальних запитах: 20–30 запитів з golden set, recall@5 до і після — мінімум перед production.

Моя головна думка: Hybrid search і reranking — це не заміна хорошої embedding-моделі або правильного chunking. Це наступний шар оптимізації для RAG-системи, яка вже працює, але потребує вищої точності. Впроваджуйте поступово, вимірюйте кожен крок, і не вірте маркетинговим цифрам "+48%" — цільтесь у реалістичні +15–25%.

Якщо хочете глибше зануритись в архітектуру retrieval — ColBERT, Vector DB Internals (🔴 Advanced, скоро). Якщо потрібно системно вимірювати якість —

📖 Джерела

Останні статті

Читайте більше цікавих матеріалів

Hybrid Search та Reranking: як підняти якість RAG на 15–40% без зміни моделі

Hybrid Search та Reranking: як підняти якість RAG на 15–40% без зміни моделі

Ваш RAG-пайплайн працює. Відповіді генеруються, retrieval повертає результати. Але користувач шукає get_user_v2 — і замість документації отримує статтю про user management. Або питає про "стаття 42 ЗУ про захист персональних даних" — і vector search повертає три чанки про...

Embeddings простими словами: як AI розуміє сенс, а не просто слова

Embeddings простими словами: як AI розуміє сенс, а не просто слова

Ви коли-небудь дивувались, чому ChatGPT знаходить зв'язок між "автомобілем" і "машиною" — хоча це різні слова? Або чому RAG-система знаходить потрібний документ навіть якщо у запиті немає жодного слова з тексту? Спойлер: за цим стоїть одна технологія — embedding. Це спосіб...

Як виміряти якість RAG: метрики, інструменти та перший evaluation pipeline — гайд 2026

Як виміряти якість RAG: метрики, інструменти та перший evaluation pipeline — гайд 2026

Ви побудували RAG-систему, відповіді генеруються, retrieval працює. Але як дізнатися, чи працює він на 90% запитів чи на 55%? Eyeball evaluation не скейлиться: variance між ревьюерами, нульове покриття edge cases, неможливість відловити регресії. Спойлер: п'ять метрик + 50...

ChromaDB, Qdrant або pgvector: як обрати Vector DB під свій проєкт

ChromaDB, Qdrant або pgvector: як обрати Vector DB під свій проєкт

ChromaDB, Qdrant або pgvector: як обрати Vector DB Проблема: Ви запустили перший RAG на ChromaDB — все працює: ~50 000 документів, відповіді стабільні. Але з’являється нова вимога: масштабування. Менеджер очікує мільйон документів, DevOps ставить під сумнів окрему vector DB, якщо...

Vector Search для початківців: як RAG знаходить потрібну інформацію

Vector Search для початківців: як RAG знаходить потрібну інформацію

Ви додали документи у свій RAG-пайплайн, написали запит — і система знаходить відповідь. Але як саме? Чому вона обирає цей фрагмент, а не сусідній? І чому іноді повертає повну нісенітницю? Спойлер: за кожним RAG-пошуком стоїть математика кутів у просторі тисячі вимірів — і її можна...

RAG для PDF: як задавати питання по документах — повний гайд 2026

RAG для PDF: як задавати питання по документах — повний гайд 2026

RAG для PDF: як задавати питання по документах Ви хочете задавати питання по своєму PDF — договору, звіту чи документації. Копіюєте код із туторіалу, запускаєте — і отримуєте беззмістовні відповіді або помилки. Проблема майже ніколи не в LLM. Вона виникає ще на першому кроці —...