Reranker-модели: зачем они нужны в RAG
Векторный поиск находит вроде бы похожие фрагменты, а модель отвечает мимо вопроса — знакомая картина, если вы уже собрали RAG и он «вроде работает, но как-то не очень». Причина часто не в эмбеддере и не в чанкинге, а в том, что косинусное сходство — не то же самое, что релевантность вопросу. Reranker — вторая модель, которая пересматривает уже найденных кандидатов и расставляет их заново, ближе к тому, что человек назвал бы «действительно по делу». Разбираемся, почему это работает, когда окупается и как встроить в свой пайплайн.
Содержание
Обсудить статью, задать вопрос или начать новую тему
Есть вопрос по этой статье, идея для обсуждения или просто хотите поделиться опытом? Сообщество MAATRIX ждёт. Для общения, пожалуйста, зарегистрируйтесь в нашем личном кабинете.
Перейти в сообщество →Почему одного векторного поиска часто недостаточно
Векторный поиск в RAG устроен так: вопрос и каждый чанк документа превращаются в вектор (эмбеддинг), а «похожесть» между ними считается как косинусное расстояние. Это быстро — по индексу из миллиона векторов ответ приходит за миллисекунды — но у самой идеи есть системное ограничение.
Эмбеддер кодирует чанк и вопрос независимо друг от друга, ничего не зная про пару целиком. Он видит «в этом тексте примерно такие темы» и «в этом вопросе примерно такие темы», а дальше просто сравнивает два облака смысла. Из-за этого возникают предсказуемые перекосы:
- Длинные общие фрагменты обгоняют точные. Абзац, который поверхностно касается пяти тем сразу, может оказаться «ближе» к вопросу, чем короткий фрагмент, отвечающий на него буквально одним предложением.
- Синонимы и парафраз путают модель. «Как отменить подписку» и «правила расторжения договора» семантически близки, но первое — вопрос пользователя, второе — юридический раздел, который на него не отвечает по сути.
- Порядок топ-N ненадёжен именно в верхней части. Разница в косинусном сходстве между 1-м и 5-м местом часто минимальна — доли процента, — а смысловая разница между этими фрагментами может быть огромной.
На практике это значит: если вы отдаёте модели top-4–5 фрагментов напрямую, релевантный ответ нередко лежит на 7–8 месте и просто не попадает в контекст. Модель честно отвечает по тому, что ей дали, — и дают ей не то.
Если вы ещё не поднимали сам RAG-пайплайн — с чанкингом, эмбеддингом и диагностикой поиска, — это описано в статье как поднять RAG по своим документам на сервере. Reranker имеет смысл добавлять поверх уже работающей базовой схемы, а не вместо неё.
Как работает reranker: вторая модель поверх кандидатов
Ключевая разница между эмбеддером и reranker-моделью — в архитектуре, а не в размере или «качестве вообще».
Эмбеддер (bi-encoder) кодирует текст и вопрос раздельно, заранее, в отрыве друг от друга — поэтому его векторы можно посчитать один раз и сложить в индекс, а поиск свести к быстрому сравнению чисел. Это и даёт скорость на больших базах.
Reranker (обычно cross-encoder) устроен иначе: он получает пару «вопрос + конкретный фрагмент» одновременно и пропускает их через модель вместе, с полным вниманием между всеми токенами обоих текстов. На выходе — не вектор, а одно число: скор релевантности именно этой пары. Модель буквально «читает» вопрос и фрагмент рядом и оценивает, отвечает ли второе на первое.
Это точнее почти всегда, но дороже: пересчитать так придётся каждую пару отдельно, и посчитать заранее, как с эмбеддингами, нельзя — фрагмент не знает вопроса заранее. Поэтому cross-encoder не используют для поиска по всей базе (это было бы N сравнений на миллион документов), а применяют только к уже отобранным кандидатам — обычно 10–50 штук после первого прохода векторным поиском.
Отсюда и название «reranker»: модель не ищет, она пересортировывает то, что уже нашли.
Нужен сервер под эту задачу?
Разверните VPS MAATRIX за пару минут: NVMe, AMD EPYC, root-доступ, локации UK, США, Франция и РФ. Оплата картой РФ и по СБП.
Развернуть QdrantПрактическая схема: retrieve top-20, rerank в top-5
Рабочая связка, которая закрывает большинство случаев:
- Retrieve. Векторный поиск по базе (Qdrant, Chroma и т. п.) возвращает top-20 кандидатов по косинусному сходству. На этом этапе важна полнота — не бойтесь взять с запасом, cross-encoder всё равно отфильтрует лишнее.
- Rerank. Все 20 пар «вопрос + фрагмент» прогоняются через cross-encoder, каждая получает скор релевантности. Кандидаты сортируются заново по этому скору.
- Truncate. В промпт модели уходят только top-5 (иногда top-3–8, в зависимости от бюджета контекста) — уже пересортированных фрагментов.
question → vector search (Qdrant) → top-20 candidates
top-20 → cross-encoder rerank (пара question+chunk → score)
top-20 sorted by score → top-5 → LLM prompt
Числа 20 и 5 не догма, а отправная точка. Логика их выбора простая:
- Top-K на retrieve должен быть достаточно широким, чтобы туда почти наверняка попал правильный ответ — иначе reranker просто нечего пересортировывать. Если ваша база разнородная (много похожих по теме, но разных по сути документов), берите 30–50.
- Top-N после rerank должен помещаться в контекст модели с запасом на системный промпт и историю диалога, и не должен размывать внимание модели лишним. Пять фрагментов — разумный дефолт для большинства LLM с контекстом в десятки тысяч токенов; для очень коротких контекстов может быть оправдано 3, для длинных — 8–10.
Проверить это на глаз почти невозможно — нужен тестовый набор вопросов с известными правильными фрагментами и метрика попадания правильного фрагмента в top-N до и после rerank. Без такого замера легко получить обратный эффект: reranker «на глаз» иногда ухудшает выдачу на конкретных доменных текстах.
Какие reranker-модели существуют
Разброс — от лёгких открытых моделей до платных API. Ориентировочная картина на конец 2026 года:
| Модель / сервис | Тип | Где крутится | Особенность |
|---|---|---|---|
| BAAI/bge-reranker-base, bge-reranker-large | cross-encoder | локально (CPU/GPU) | открытая, хорошо работает на русском и английском вместе с bge-эмбеддерами |
| BAAI/bge-reranker-v2-m3 | cross-encoder | локально | мультиязычная, легче интегрировать в пайплайн на нескольких языках |
| sentence-transformers/ms-marco-MiniLM | cross-encoder | локально (лёгкая) | компактная, быстрая на CPU, в основном под английский |
| Cohere Rerank | API | облако | платный, без своей инфраструктуры, минимальная задержка на интеграцию |
| Jina Reranker | локально / API | оба варианта | есть открытые веса, есть облачный API |
Открытые cross-encoder-модели из семейства BAAI и sentence-transformers запускаются через библиотеку sentence-transformers или FlagEmbedding и не требуют GPU для небольших объёмов — на CPU reranking 20 пар обычно укладывается в разумное время для интерактивного ответа, хотя точная скорость зависит от модели, длины фрагментов и железа: здесь я намеренно не называю цифры «токенов в секунду» — измерьте на своих данных, у вас будет иначе.
Если вы уже считаете эмбеддинги на CPU без GPU, добавление reranker того же класса обычно укладывается в тот же бюджет железа — подробнее про расчёт нагрузки есть в статье как считать эмбеддинги на CPU без GPU.
Когда reranker оправдан, а когда избыточен
Reranker — не обязательный компонент любого RAG, это оптимизация под конкретную ситуацию.
Стоит добавлять, когда:
- база большая (десятки тысяч фрагментов и больше) и в топ-N векторного поиска регулярно попадает «почти похожее», а не точный ответ;
- цена ошибки высокая — юридические, медицинские, финансовые ответы, где неточная выдача стоит дороже, чем лишние 100–300 мс на запрос;
- вопросы пользователей формулируются иначе, чем текст документов (разговорный язык против канцелярита в источниках) — именно здесь эмбеддер чаще всего промахивается;
- вы уже проверили базовый RAG на тестовом наборе и видите, что нужный фрагмент есть в top-20, но не входит в top-5 без reranker.
Скорее избыточен, когда:
- база маленькая (сотни фрагментов) — там векторный поиск и так почти всегда находит нужное в топе, а выигрыш от rerank статистически не заметен;
- задержка критичнее точности — например, чат в реальном времени, где 200–500 мс дополнительной обработки заметны пользователю, а цена неточного ответа невысока;
- документы однородные и узкотематические (одна база — одна тема), там косинусное сходство и так хорошо разделяет релевантное от нерелевантного;
- у вас пока нет способа измерить, помог ли reranker — добавлять компонент, эффект которого не с чем сравнить, обычно не стоит того.
Если сомневаетесь — разверните reranker необязательным флагом в своём пайплайне и сравните ответы на одном и том же тестовом наборе вопросов с ним и без. Часто выясняется, что для конкретной базы выигрыш есть только на определённом классе вопросов, а не везде.
Как встроить reranker в пайплайн на сервере
Если векторная база уже поднята (например, Qdrant — как это сделать, описано в статье как установить и настроить Qdrant на VPS), добавление reranker — это дополнительный шаг между поиском и сборкой промпта, без изменений в самой базе.
Минимальный пример на Python с sentence-transformers:
from sentence_transformers import CrossEncoder
from qdrant_client import QdrantClient
client = QdrantClient(url="http://localhost:6333")
reranker = CrossEncoder("BAAI/bge-reranker-base")
def search_with_rerank(question, top_k_retrieve=20, top_n_final=5):
# 1. Retrieve: обычный векторный поиск
hits = client.search(
collection_name="docs",
query_vector=embed(question), # ваша функция эмбеддинга
limit=top_k_retrieve,
)
candidates = [h.payload["text"] for h in hits]
# 2. Rerank: пары "вопрос + фрагмент" через cross-encoder
pairs = [[question, text] for text in candidates]
scores = reranker.predict(pairs)
# 3. Пересортировка и обрезка до top_n_final
ranked = sorted(zip(candidates, scores), key=lambda x: x[1], reverse=True)
return [text for text, score in ranked[:top_n_final]]
Несколько практических деталей, которые легко упустить:
- Reranker и эмбеддер — разные модели, менять их местами нельзя. Эмбеддер отвечает за скорость поиска по всей базе, reranker — за точность на малой выборке кандидатов.
- Длина фрагмента имеет значение. Cross-encoder обрабатывает вопрос и фрагмент как одну последовательность, поэтому у него есть лимит токенов на пару — обычно 512. Слишком длинные чанки будут обрезаны, и часть текста не попадёт в оценку.
- Батчинг ускоряет rerank. Вместо цикла по одной паре прогоняйте весь список сразу через
predict()— реализации cross-encoder используют батч эффективнее. - Кэшировать нечего. В отличие от эмбеддингов документов, которые считаются один раз и хранятся в индексе, reranker считает скор заново для каждой новой пары — закладывайте это время в бюджет ответа.
- Мониторьте, что реально меняется после rerank. Если top-1 почти всегда совпадает с top-1 до rerank, компонент не даёт эффекта на вашей базе — стоит сменить модель или вернуться к обычному векторному поиску.
Если у вас RAG собран не с нуля, а на готовой платформе вроде AnythingLLM, встроить произвольный cross-encoder в её пайплайн retrieve может быть не так прямолинейно, как в собственном коде — прежде чем внедрять reranker, стоит понять, где именно у вас теряется точность: подробнее об устройстве векторной базы под RAG — в статье как поднять векторную базу для RAG на сервере.
Нужен сервер под эту задачу?
Разверните VPS MAATRIX за пару минут: NVMe, AMD EPYC, root-доступ, локации UK, США, Франция и РФ. Оплата картой РФ и по СБП.
Развернуть QdrantОбсудить статью, задать вопрос или начать новую тему
Есть вопрос по этой статье, идея для обсуждения или просто хотите поделиться опытом? Сообщество MAATRIX ждёт. Для общения, пожалуйста, зарегистрируйтесь в нашем личном кабинете.
Перейти в сообщество →Частые вопросы
Reranker заменяет векторный поиск?
Нет. Он работает только поверх уже найденных кандидатов — прогнать всю базу через cross-encoder на каждый запрос было бы слишком медленно на сколько-нибудь большом объёме данных.
Нужен ли GPU для reranker?
Не обязательно. Небольшие cross-encoder-модели (base-размера) справляются на CPU с разумной задержкой для 10–20 кандидатов; для большого потока запросов или тяжёлых моделей GPU ускорит работу, но это вопрос нагрузки, а не обязательное требование.
Можно ли использовать reranker вместо переранжирования top-K, а сразу как основной поиск?
Технически можно построить полный перебор через cross-encoder на маленькой базе (сотни документов), но с ростом базы это быстро упирается в линейный рост времени — отсюда и двухэтапная схема retrieve→rerank.
Насколько сильно reranker меняет качество ответов?
Зависит от базы и вопросов — на некоторых доменах эффект заметный (нужный фрагмент чаще попадает в топ), на однородных узких базах разница может быть минимальной. Единственный надёжный способ узнать — замерить на своём тестовом наборе вопросов, а не полагаться на общие оценки из чужих бенчмарков.
Есть ли смысл ставить reranker, если у меня и так всего 4 фрагмента в топе?
Обычно нет — если top-4 из векторного поиска и так стабильно релевантны на ваших вопросах, добавлять ступень пересортировки незачем. Reranker решает проблему, когда top-4 или top-5 без него часто мимо.
Нужны сами нейросети для контента?
Генерируйте изображения, видео и озвучку нейросетями на falapi.io — десятки моделей в одном окне. Оплата картой РФ и по СБП.