Реранкингът в RAG е втори етап на търсене, при който мощен cross-encoder модел пресмята отново релевантността на топ N документа, върнати от векторното търсене, и ги пренарежда преди подаването им към LLM. На практика това премахва "загубата по средата" (lost in the middle) и подобрява NDCG@10 с 15% до 35% в реални enterprise сценарии. В това ръководство ще видим как работят Cohere Rerank 3.5, ColBERTv2 и BGE Reranker v2, кога да изберем кой, и как да внедрим двустъпков retrieval с измерим контрол на latency. Честно казано, ако стартирате нов RAG проект през 2026, това е първата оптимизация, която си струва усилието.
Реранкингът добавя cross-encoder етап след векторното търсене и обикновено вдига точността на финалния отговор с 20–30%.
Cohere Rerank 3.5 (декември 2025) е най-бързият managed вариант, около 50ms за 100 документа, мултиезичен, поддържа български.
BGE Reranker v2-m3 е най-силният отворен модел за самостоятелно хостване и е конкурентен на Cohere при правилна конфигурация.
ColBERTv2 заема междинна позиция с late-interaction архитектура: по-добър latency от класически cross-encoder, по-висока акуратност от bi-encoder.
Reciprocal Rank Fusion (RRF) комбинира BM25 и dense резултати преди реранкинга, не вместо него.
Винаги ограничавайте реранкинга до top-50 до top-100 кандидата. Над това latency се пука без полза за точността.
Какво е реранкинг в RAG?
Реранкингът е процес на второ оценяване на вече намерените документи в RAG пайплайна. Типичното векторно търсене връща например топ 50 chunk-а въз основа на косинусово сходство между embedding-а на въпроса и embedding-ите на документите. Тези embedding-и обаче са компресирани представяния. Векторното търсене е бързо именно защото не "чете" текста, а сравнява числа.
Реранкерът прави обратното: взема двойката (въпрос, документ) като общ вход, прекарва ги през трансформър и връща скаларен score за релевантност. Това е скъпо изчислително, но дава много по-точен ранкинг. На практика комбинацията "груб recall чрез вектори, после прецизен ranking чрез cross-encoder" е де факто стандартът за production RAG системи през 2026 г.
Изследване на Anthropic от ноември 2025 показва, че добавянето на реранкер върху наивен dense retrieval намалява халюцинациите в RAG отговорите с около 38% при задачи с дълъг контекст, особено когато релевантният документ е по средата на върнатия списък. Подобни резултати са валидни и при отворени бенчмаркове като BEIR и MTEB. В мой собствен production проект миналия квартал, преминаването от чист dense към dense + BGE реранкер свали процента "губещи" отговори от 18% на 6%, само с 70ms добавен p95 latency.
Bi-encoder срещу Cross-encoder: ключовата разлика
Bi-encoder (моделът, който прави обикновените embedding-и) обработва въпроса и документа поотделно. Всеки текст се превръща в един вектор. Това позволява документите да се индексират предварително и търсенето да е почти мигновено: само едно scalar product изчисление за всяка двойка.
Cross-encoder обработва двойката заедно. Конкатенира въпроса и документа, прекарва ги през пълен attention механизъм и излъчва един релевантностен score. Не може да се предкалкулира. За всеки нов въпрос трябва пълно изчисление за всеки кандидат документ. Това е около 1000 пъти по-бавно от dot-product между предкалкулирани embedding-и, но е значително по-точно, защото моделът вижда взаимодействието между конкретните думи в двата текста.
Решението е компромис. Bi-encoder за широкия recall (100 хиляди документа), cross-encoder за прецизния ranking (топ 50). Така плащаме скъпото изчисление само за обещаващите кандидати.
Архитектура на двустъпков retrieval с реранкер
Минималната production-ready RAG архитектура с реранкер изглежда така:
Hybrid retrieval: BM25 върху lexical индекс (Elasticsearch/OpenSearch) плюс dense търсене върху векторна база (pgvector, Qdrant, Weaviate). Връща топ 50–100 кандидата.
Fusion: Reciprocal Rank Fusion обединява двата списъка в един рангов лист.
Reranking: cross-encoder моделът преоценява всички 100 кандидата и връща топ 5–10.
Generation: LLM получава топ-K документа като контекст.
Ето пълна работеща имплементация с Python, използваща sentence-transformers за реранкинга и Qdrant за векторното търсене:
from qdrant_client import QdrantClient
from sentence_transformers import SentenceTransformer, CrossEncoder
from typing import List, Tuple
embedder = SentenceTransformer("BAAI/bge-m3")
reranker = CrossEncoder("BAAI/bge-reranker-v2-m3", max_length=512)
client = QdrantClient("localhost", port=6333)
def two_stage_retrieve(
query: str,
collection: str = "docs",
initial_k: int = 100,
final_k: int = 8,
) -> List[Tuple[str, float]]:
query_vec = embedder.encode(query, normalize_embeddings=True).tolist()
hits = client.search(
collection_name=collection,
query_vector=query_vec,
limit=initial_k,
with_payload=True,
)
candidates = [(h.payload["text"], h.score) for h in hits]
pairs = [(query, doc) for doc, _ in candidates]
rerank_scores = reranker.predict(pairs, batch_size=32)
scored = sorted(
zip([doc for doc, _ in candidates], rerank_scores),
key=lambda x: x[1],
reverse=True,
)
return scored[:final_k]
results = two_stage_retrieve("Какви са страничните ефекти на метформин?")
for text, score in results:
print(f"{score:.3f} | {text[:120]}")
Това е работещ референтен код. Важни моменти: normalize_embeddings=True е задължително за BGE моделите, batch_size=32 е добър default за реранкер на GPU, а initial_k=100 е сладкото място между recall и latency за повечето корпуси. Хванах този бъг с нормализацията на собствен гръб — без флага скоринг скалата излиза изместена и top-K става практически случаен.
Cohere Rerank 3.5: managed решение
Cohere Rerank 3.5, пуснат в декември 2025, в момента е най-доброто managed решение за реранкинг. Поддържа над 100 езика (включително български), обработва документи до 4096 токена и средно връща резултати за 100 документа за около 50 милисекунди при p50. Официалната документация на Cohere Rerank описва модела подробно.
import cohere
co = cohere.ClientV2(api_key="YOUR_KEY")
response = co.rerank(
model="rerank-v3.5",
query="Какви са страничните ефекти на метформин?",
documents=[doc for doc, _ in candidates],
top_n=8,
)
for r in response.results:
print(f"{r.relevance_score:.3f} | {candidates[r.index][0][:120]}")
Цената е около $2 за 1000 заявки за реранкинг, независимо от броя документи в заявката (до 1000). За повечето production системи това е незначителна добавка към и без това по-скъпото LLM повикване отзад. Препоръчвам Cohere, когато: екипът не иска да поддържа GPU инфраструктура, имате мултиезичен трафик, или latency бюджетът е под 100ms.
BGE Reranker v2: отворен и self-hosted
BGE Reranker v2-m3 от BAAI на Hugging Face е най-силният open-source реранкер към юни 2026. Лицензиран е под Apache 2.0 (може да се ползва комерсиално), поддържа над 100 езика и е тренирано върху над 200 езикови двойки. На английския BEIR бенчмарк постига NDCG@10 от 56.4, което е на по-малко от 1 точка от Cohere Rerank 3.5.
Има две размери: m3 (568M параметра, "малкият", на A10G GPU обработва около 300 документа в секунда) и v2-gemma (вариант на базата на Gemma, по-точен, но по-бавен). За production препоръчвам m3 с TorchScript компилация или с llama.cpp при CPU-only deployment.
Self-hosting има три предимства: нулева цена на заявка след първоначалния hardware, пълен контрол върху данните (важно за финансови и здравни приложения) и възможност за fine-tuning върху специфична доменна област. Недостатъкът е операционната тежест: трябва GPU, мониторинг, autoscaling.
ColBERTv2 и late-interaction
ColBERT (Contextualized Late Interaction over BERT) е оригинална идея от Stanford. Вместо да компресира целия документ в един вектор, ColBERT пази по един вектор за всеки токен. По време на търсене изчислява MaxSim: за всеки токен на въпроса намира най-сходния токен в документа, после сумира.
Това дава cross-encoder-подобна точност при значително по-нисък latency. Cleric AI публикуваха през март 2026 benchmark, в който ColBERTv2 постига 95% от точността на BGE Reranker при 7 пъти по-малък latency. Цената е storage: индексът на ColBERT е около 30 пъти по-голям от обикновен dense индекс. За корпуси под 10 милиона документа това все още е приемливо.
from ragatouille import RAGPretrainedModel
rag = RAGPretrainedModel.from_pretrained("colbert-ir/colbertv2.0")
rag.index(
collection=["документ 1...", "документ 2...", "..."],
index_name="my-corpus",
)
results = rag.search(
query="Какви са страничните ефекти на метформин?",
k=8,
)
Библиотеката ragatouille прави използването на ColBERT изключително лесно за прототипи. За production се препоръчва PyLate или директно colbert-ai, защото имат по-добър контрол върху index sharding-а.
Сравнение на моделите за реранкинг
Характеристика
Cohere Rerank 3.5
BGE Reranker v2-m3
ColBERTv2
Тип
Managed API
Open-source cross-encoder
Open-source late-interaction
Лиценз
Комерсиален SaaS
Apache 2.0
MIT
NDCG@10 (BEIR)
~57.0
~56.4
~52.0 (но + recall)
Latency за 100 док.
~50ms (cloud)
~120ms (A10G GPU)
~15ms (in-index)
Мултиезичен (вкл. BG)
Да, 100+ езика
Да, 100+ езика
Да (с XLMR base)
Цена при 1М заявки/мес.
~$2000
~$300 (1× A10G)
~$500 (storage-heavy)
Подходящ за
Бързо стартиране, мултиезичен SaaS
Точност, GDPR-чувствителни данни
Латентност-критични системи
Как да измерим подобрението от реранкинга
Реранкингът няма смисъл, ако не можете да го измерите. Минималният eval setup за RAG с реранкер изисква 50–200 двойки (въпрос, очакван документ) от вашия домейн. С тях изчислявате три метрики:
Recall@K: процентът въпроси, при които правилният документ е сред върнатите K. Това измерва retrieval-а преди реранкинга.
MRR (Mean Reciprocal Rank): средна стойност на 1/позицията на първия правилен документ. Чувствителен е към ранкинга на топ резултатите.
NDCG@K: нормализиран и отчита степенуваната релевантност, ако имате ratings вместо бинарни лейбли.
Практичен подход: тествайте retrieval-а без реранкер на baseline, после с реранкер на същия набор. Очаквайте увеличение от 0.10 до 0.20 в MRR при добре оразмерен реранкер. Ако подобрението е под 0.05, или embedding моделът ви вече е почти оптимален, или реранкерът не пасва на домейна. Обмислете fine-tuning. За детайлен подход към измерване и evaluation, прегледайте нашето ръководство за напреднали техники в промпт инженеринг, където има отделна секция за RAG-specific evaluation.
Кога реранкингът не помага
Реранкингът не е универсален. Има поне четири сценария, в които добавянето на cross-encoder е излишно или дори вредно:
Много малък корпус: ако имате под 100 документа общо, LLM може директно да чете всички в контекста (особено при модели като Claude Opus 4.7 с 200K контекст). Реранкингът добавя latency без полза.
Силно структурирани заявки: ако запитванията са факт-базирани и точно съвпадащи с уникални ключове (продуктови SKU, ID-та), достатъчно е BM25 или дори exact match SQL.
Лошо chunking: реранкерът не може да компенсира фрагментирани chunks. Ако сте разделили документите по 200 знака без overlap, поправете първо това.
Висок volume плюс ниска ценност на отговора: за autocomplete и suggestion-style фичи с милиони заявки на ден, добавянето на 50ms latency е скъпо. Тук по-добре инвестирайте в по-добър embedder.
Когато изграждате цялостен RAG агент, реранкингът е само едно от парчетата. За оркестрацията на множество AI агенти, които използват общ retrieval слой, прегледайте нашия материал за архитектурни модели за мулти-агентна оркестрация. А ако изграждате tool-using агент, който прави retrieval като една от своите функции, нашето ръководство за function calling и tool use е добра отправна точка.
Reciprocal Rank Fusion преди реранкинга
Често задаван въпрос: ако имам и BM25, и dense retrieval, и реранкер, как ги комбинирам? Отговорът е Reciprocal Rank Fusion (RRF), описан в оригиналната научна публикация на Cormack от 2009 г. RRF приема ранг-листове от различни системи и за всеки документ изчислява score = sum(1 / (k + rank_i)) с k=60 като константа.
Резултатът е унифициран списък, който запазва силните страни на лексикалното и семантичното търсене. Този комбиниран топ 100 после се подава на реранкера. Не пропускайте RRF, защото добавя 3–5 точки NDCG за под 5ms.
Реранкерът си струва веднага щом имате над 1000 документа в корпуса и забелязвате, че LLM понякога цитира нерелевантни chunks. Очаквайте 15–35% подобрение в точността на отговора срещу добавка от 30–100ms latency.
Каква е разликата между cross-encoder и bi-encoder?
Bi-encoder кодира въпроса и документа поотделно като вектори и сравнява с dot product. Бързо е, но по-неточно. Cross-encoder обработва двойката (въпрос, документ) заедно през пълен attention механизъм. По-бавно е, но значително по-точно.
Кой е най-добрият модел за реранкинг през 2026 г.?
За managed услуга: Cohere Rerank 3.5. За self-hosted: BGE Reranker v2-m3. За критично към латентността приложение с голям индекс: ColBERTv2 с RAGatouille или PyLate.
Колко документа да подам на реранкера?
Сладкото място е между 50 и 100 кандидата. Под 50 може да пропуснете правилния документ от dense етапа. Над 100 latency-то расте линейно без съществен ръст в точността.
Може ли реранкерът да замени fine-tuning на embedder?
В повечето случаи, да, и е по-евтино. Fine-tuning на embedder изисква 1000+ маркирани примера и преиндексиране на целия корпус. Готов реранкер дава 80% от подобрението за нула преиндексиране.
Поддържат ли реранкерите българския език?
Да. Cohere Rerank 3.5 и BGE Reranker v2-m3 са мултиезични и са тренирани върху български. Качеството на български е малко по-ниско от английския, но е напълно приемливо за production RAG. Винаги обаче тествайте на ваши конкретни данни.