Reranking

Реранкинг — второй этап поиска в RAG: после быстрого отбора кандидатов более тяжёлая модel (cross-encoder) переупорядочивает их по точной релевантности. Метафора лекции — «сужающаяся воронка»: 100 → 20 → 5.

Суть

Векторный поиск (bi-encoder) быстрый, но грубый: он кодирует вопрос и документ независимо и сравнивает косинусом. Cross-encoder подаёт пару «вопрос + документ» в модель вместе, поэтому ранжирует точнее — но медленнее, и его нельзя гонять по всей базе.

Зачем это нужно

Если запустить cross-encoder на всех документах базы, поиск простого запроса может занять ~2 минуты. Поэтому его применяют только к уже отфильтрованному топу: даёт стабильный +5-8% accuracy при контролируемой latency.

Как работает (воронка)

  1. Recall-этап — гибридный поиск (Hybrid Search, BM25 + vector) отбирает топ-50…100 кандидатов.
  2. Precision-этап — cross-encoder переранжирует топ-20.
  3. Финал — топ-5 наиболее релевантных чанков уходят в промпт LLM.
  • Multi-stage Reranking — каскад: быстрый bi-encoder → cross-encoder → (опционально) LLM-фильтр. Каждая ступень дороже и точнее предыдущей.
  • Trade-off: «быстрый, но неточный RAG бесполезен» — реранкинг и есть способ докупить точность за приемлемую задержку (целевые P95 < 3 c, см. RAG Metrics).
  • Реранкинг — самая дешёвая по усилиям техника с стабильным приростом, поэтому входит в Production Baseline 2026 (вместе с Hybrid Search).
  • Multilingual reranker (на момент источников): jina-reranker-v3 — 0.6B, listwise, «last but not late» (causal attention по запросу и всем кандидатам в одном окне, без late-interaction как у ColBERT), BEIR 61.94 nDCG@10; покрывает и русский. ⚠️ Конкретные SOTA-модели быстро устаревают.
  • Top-k как production-эвристика (пример, не универсальный стандарт): top-50 (BM25) → top-20 (vector) → top-5 (после reranker); целевые latency P95 < 3 c, TTFT < 500 мс.

Пример

Двухступенчатая воронка: bi-encoder быстро отбирает top-10 кандидатов, cross-encoder (принимает пару «вопрос+документ» вместе) точно переранжирует их в top-k.

from sentence_transformers import CrossEncoder
reranker = CrossEncoder("cross-encoder/ms-marco-MiniLM-L-6-v2")

def reranking_retrieve(question, k=3):
    candidates = vectorstore.similarity_search(question, k=10)   # bi-encoder: грубо, top-10
    pairs  = [(question, c.page_content) for c in candidates]
    scores = reranker.predict(pairs)                             # cross-encoder: точно
    ranked = sorted(zip(scores, candidates), key=lambda x: x[0], reverse=True)
    return [d.metadata["doc_id"] for _, d in ranked][:k]

Связано с

  • RAG — реранкинг = precision-этап retrieval
  • Hybrid Search — поставляет кандидатов на реранкинг
  • Embeddings — bi-encoder (быстрый отбор) работает на эмбеддингах

Открытые вопросы

  • RU-специфичный выбор/бенчмарк reranker'а (multilingual jina-reranker-v3 — текущий ориентир; прямого RU-сравнения reranker'ов нет)
  • tensor-based reranking (RAGFlow) vs классический cross-encoder