Riordinamento con cross-encoder: Cohere e BGE
Integri l'endpoint rerank di Cohere e il modello BGE-reranker per assegnare un punteggio alle coppie query-documento e riordinare i Suoi chunk top-k in base alla reale rilevanza.
Riordinamento con cross-encoder: Cohere e BGE è una lezione AI Engineering Academy gratuita su CoddyKit. Questa è la lezione 2 di 4. Puoi leggere la lezione completa qui gratuitamente — poi esercitati direttamente nel browser con un editor di codice integrato e un tutor IA disponibile 24/7. Fa parte del percorso di apprendimento AI Engineering Academy, e i tuoi progressi si sincronizzano tra il web e l'app CoddyKit. Il corso AI Engineering Academy include 4 lezioni in totale.
Che cos'è un cross-encoder?
Un cross-encoder è un modello neurale che riceve una query e un documento come unico input concatenato e restituisce un punteggio di rilevanza. A differenza di un bi-encoder, che incorpora separatamente query e documento, i livelli di attenzione del cross-encoder analizzano entrambi i testi simultaneamente, consentendogli di modellare segnali di rilevanza dettagliati che un bi-encoder non rileva. È questa elaborazione congiunta a rendere i cross-encoder significativamente più accurati nel ranking.
# Bi-encoder: separate encoding
query_vec = encoder.encode(query) # [768] vector
doc_vec = encoder.encode(document) # [768] vector
score = cosine_similarity(query_vec, doc_vec) # compare independently
# Cross-encoder: joint encoding
combined_input = '[CLS] ' + query + ' [SEP] ' + document + ' [SEP]'
logits = cross_encoder.forward(combined_input) # score from joint attention
# The model attends from every query token to every document tokenL'API Cohere Rerank
Cohere Rerank è un'API cloud di riordinamento basata su cross-encoder, che accetta una query e un elenco di massimo 1000 testi di documenti e restituisce i relativi punteggi di rilevanza. Utilizza modelli cross-encoder di grandi dimensioni, addestrati su dataset di ranking di alta qualità, e supera costantemente i piccoli cross-encoder self-hosted nella maggior parte dei benchmark. L'API viene tariffata per ogni migliaio di documenti riordinati.
import cohere
co = cohere.Client('YOUR_COHERE_API_KEY')
candidates = [
'How to configure pgvector in PostgreSQL for vector search',
'BM25 scoring formula and hyperparameters explained',
'Installing and using the pgvector extension for embeddings',
'Hybrid search combining BM25 and dense retrieval',
]
result = co.rerank(
model='rerank-english-v3.0',
query='pgvector setup guide',
documents=candidates,
top_n=3,
return_documents=True,
)
for item in result.results:
print(f'Score {item.relevance_score:.4f}: {item.document.text[:60]}')Cohere Rerank in una pipeline RAG
L'integrazione di Cohere Rerank in una pipeline RAG segue uno schema semplice: recuperi 20-50 candidati dal Suo vector store, ne estragga il testo, chiami l'API Cohere Rerank e selezioni i risultati top-K da passare all'LLM. Il sovraccarico di latenza è in genere di 100-300 ms, un valore accettabile quando il miglioramento della precisione produce risposte finali migliori.
import cohere
from openai import OpenAI
co = cohere.Client('COHERE_KEY')
client = OpenAI()
def rag_with_rerank(question: str, retriever, top_k: int = 5) -> str:
# Stage 1: coarse retrieval
candidates = retriever.invoke(question) # returns 30 docs
texts = [doc.page_content for doc in candidates]
# Stage 2: Cohere re-ranking
rerank_result = co.rerank(
model='rerank-english-v3.0',
query=question,
documents=texts,
top_n=top_k,
)
top_texts = [texts[r.index] for r in rerank_result.results]
context = '\n\n'.join(top_texts)
# Stage 3: generation
response = client.chat.completions.create(
model='gpt-4o-mini',
messages=[
{'role': 'system', 'content': 'Answer using only the provided context.'},
{'role': 'user', 'content': f'Context:\n{context}\n\nQuestion: {question}'},
],
)
return response.choices[0].message.contentBGE Reranker: alternativa open source
BGE Reranker (BAAI General Embedding) è una famiglia open source di modelli cross-encoder della Beijing Academy of AI. Il modello BAAI/bge-reranker-v2-m3 supporta il riordinamento multilingue e ottiene punteggi vicini a Cohere Rerank nei benchmark in inglese, eseguendo però localmente. Lo utilizzi con la libreria sentence-transformers per un riordinamento completamente self-hosted, senza costi per l'API.
from sentence_transformers import CrossEncoder
# Load BGE reranker model
reranker = CrossEncoder(
'BAAI/bge-reranker-v2-m3',
max_length=512,
device='cpu', # use 'cuda' if GPU is available
)
def bge_rerank(query: str, documents: list[str], top_k: int = 5) -> list[dict]:
pairs = [[query, doc] for doc in documents]
scores = reranker.predict(pairs, show_progress_bar=False)
ranked = sorted(
zip(documents, scores.tolist()),
key=lambda x: x[1],
reverse=True,
)
return [{'text': doc, 'score': score} for doc, score in ranked[:top_k]]Varianti dei modelli BGE Reranker
La famiglia di reranker BGE offre diversi compromessi tra dimensioni e qualità. bge-reranker-base (278 milioni di parametri) è il più piccolo e veloce. bge-reranker-large (560 milioni di parametri) è più accurato. bge-reranker-v2-m3 supporta più lingue ed è l'impostazione predefinita consigliata per la produzione. Per ottenere la massima accuratezza, bge-reranker-v2-gemma utilizza un backbone Gemma e supera la maggior parte delle opzioni open source nei benchmark in inglese.
# Model size vs accuracy trade-offs
models = [
('BAAI/bge-reranker-base', '278M params', 'fast, English-focused'),
('BAAI/bge-reranker-large', '560M params', 'better, English-focused'),
('BAAI/bge-reranker-v2-m3', '570M params', 'best for multilingual use'),
('BAAI/bge-reranker-v2-gemma', '2B params', 'SOTA open-source accuracy'),
]
# For most RAG applications, bge-reranker-v2-m3 offers the best
# balance of accuracy, multilingual support, and inference speed on CPUBatching delle predizioni del cross-encoder
Per impostazione predefinita, i cross-encoder elaborano una alla volta le coppie (query, documento), ma la predizione a batch migliora drasticamente il throughput eseguendo simultaneamente più coppie attraverso il modello. Il parametro batch_size controlla quante coppie vengono elaborate insieme. Su GPU, sono comuni batch di dimensioni comprese tra 32 e 128. Su CPU, batch più piccoli, da 4 a 16 elementi, riducono la pressione sulla memoria migliorando comunque il throughput rispetto all'elaborazione sequenziale.
def batch_rerank(reranker, query: str, documents: list[str],
top_k: int = 5, batch_size: int = 32) -> list[dict]:
pairs = [[query, doc] for doc in documents]
# Batch prediction
all_scores = reranker.predict(
pairs,
batch_size=batch_size,
show_progress_bar=len(pairs) > 100,
)
ranked = sorted(
zip(documents, all_scores.tolist()),
key=lambda x: x[1],
reverse=True,
)
return [{'text': doc, 'score': score} for doc, score in ranked[:top_k]]Integrazione di LangChain CrossEncoderReranker
LangChain fornisce CrossEncoderReranker come compressore di documenti, integrando il riordinamento con cross-encoder nello schema ContextualCompressionRetriever. Ciò consente di racchiudere qualsiasi retriever esistente in uno stadio di riordinamento usando solo poche righe di codice e di inserirlo in qualsiasi catena LCEL che accetti un'interfaccia retriever.
from langchain.retrievers.document_compressors import CrossEncoderReranker
from langchain_community.cross_encoders import HuggingFaceCrossEncoder
from langchain.retrievers import ContextualCompressionRetriever
from langchain_community.vectorstores import FAISS
from langchain_openai import OpenAIEmbeddings
# Base retriever (coarse stage)
base_retriever = FAISS.from_documents(
documents, OpenAIEmbeddings()
).as_retriever(search_kwargs={'k': 30})
# Re-ranker (fine stage)
model = HuggingFaceCrossEncoder(model_name='BAAI/bge-reranker-v2-m3')
compressor = CrossEncoderReranker(model=model, top_n=5)
# Combined two-stage retriever
two_stage_retriever = ContextualCompressionRetriever(
base_compressor=compressor,
base_retriever=base_retriever,
)
docs = two_stage_retriever.invoke('how does hybrid search work?')Interpretazione dei punteggi e definizione delle soglie
I punteggi dei cross-encoder non hanno una scala universale. Il reranker BGE restituisce logits grezzi (spesso compresi tra -10 e +10), mentre Cohere restituisce un punteggio di rilevanza normalizzato tra 0 e 1. Può applicare una soglia minima del punteggio per escludere dal contesto inviato all'LLM i documenti con rilevanza molto bassa, riducendo ulteriormente il rumore. Inizi con una soglia al 25° percentile dei punteggi e la regoli a partire da quel valore.
def rerank_with_threshold(reranker, query, documents, top_k=5, min_score=-2.0):
pairs = [[query, doc] for doc in documents]
scores = reranker.predict(pairs)
scored_docs = [
{'text': doc, 'score': float(score)}
for doc, score in zip(documents, scores)
if float(score) >= min_score # filter low-relevance docs
]
scored_docs.sort(key=lambda x: x['score'], reverse=True)
if not scored_docs:
return [] # nothing passed the threshold
return scored_docs[:top_k]Cohere vs BGE: quale scegliere
Utilizzi Cohere Rerank quando desidera un'API gestita, necessita della massima accuratezza sui dati aziendali in inglese e vuole evitare un'infrastruttura GPU. Utilizzi BGE Reranker quando deve eseguire il self-hosting per motivi di privacy dei dati, desidera costi API nulli per query, necessita del supporto multilingue o vuole eseguire il sistema offline. Entrambi ottengono punteggi NDCG simili nella maggior parte dei benchmark: la scelta dipende soprattutto dalle preferenze relative all'infrastruttura e dal modello dei costi.
Riordinamento di contenuti multilingue
Se il Suo corpus o i Suoi utenti includono più lingue, scelga un cross-encoder multilingue. bge-reranker-v2-m3 gestisce oltre 100 lingue e Cohere Rerank dispone di una variante di modello multilingue. È supportato anche il riordinamento cross-lingua, cioè l'assegnazione di un punteggio a una query in inglese rispetto a documenti in francese o spagnolo; questa funzionalità è utile nelle implementazioni aziendali globali, dove le basi di conoscenza sono disponibili in più lingue.
from sentence_transformers import CrossEncoder
# Multilingual BGE reranker
ml_reranker = CrossEncoder('BAAI/bge-reranker-v2-m3')
# Cross-lingual example: English query, French document
query_en = 'How to configure vector search?'
doc_fr = 'La configuration de la recherche vectorielle dans PostgreSQL'
score = ml_reranker.predict([[query_en, doc_fr]])
print(f'Cross-lingual relevance score: {float(score):.3f}')
# Positive score indicates the document is relevant to the query
# despite being in a different languageMemorizzazione nella cache dei risultati del riordinamento
L'inferenza del cross-encoder è la parte più lenta di una pipeline a due stadi. Per le applicazioni in cui le stesse coppie (query, documento) ricorrono frequentemente, la memorizzazione nella cache dei risultati del riordinamento può eliminare le inferenze ridondanti. Calcoli l'hash della coppia (query, document_id) come chiave della cache e memorizzi il punteggio in Redis con un TTL. Nelle applicazioni di assistenza clienti, in cui gli utenti pongono spesso domande simili, sono comuni percentuali di cache hit del 30-50%.
import redis
import hashlib
import json
r = redis.Redis(host='localhost', port=6379)
def cached_rerank_score(reranker, query: str, doc_text: str, doc_id: str) -> float:
cache_key = 'rerank:' + hashlib.md5((query + doc_id).encode()).hexdigest()
cached = r.get(cache_key)
if cached:
return float(cached)
score = float(reranker.predict([[query, doc_text]]))
r.setex(cache_key, 3600, str(score)) # cache 1 hour
return scoreVerifica rapida
Verifichi la Sua comprensione del riordinamento con cross-encoder illustrato in questa lezione.
Riepilogo della lezione
In questa lezione ha imparato che: Cohere Rerank offre un'API cloud basata su cross-encoder con accuratezza all'avanguardia; BGE Reranker è un'alternativa open source per il deployment self-hosted, anche con contenuti multilingue; il batching migliora drasticamente il throughput quando si assegnano punteggi a molte coppie (query, documento). CrossEncoderReranker di LangChain integra entrambi nello schema ContextualCompressionRetriever. Ora implementeremo la compressione contestuale per ridurre il rumore nei chunk recuperati.
Domande Frequenti
La lezione «Riordinamento con cross-encoder: Cohere e BGE» è gratuita?
Sì — il testo completo di «Riordinamento con cross-encoder: Cohere e BGE» è gratuito qui sul web. Per esercitarvi in modo interattivo (un editor di codice integrato e un tutor IA 24/7) e sbloccare il resto del corso AI Engineering Academy, passa a CoddyKit PRO. Il corso AI Engineering Academy include 4 lezioni in totale.
Cosa imparerò in «Riordinamento con cross-encoder: Cohere e BGE»?
Integri l'endpoint rerank di Cohere e il modello BGE-reranker per assegnare un punteggio alle coppie query-documento e riordinare i Suoi chunk top-k in base alla reale rilevanza. Eserciti AI Engineering Academy con codice pratico che esegui direttamente nel browser, e un tutor IA 24/7 risponde alle tue domande mentre lavori sulla lezione.
Ho bisogno di esperienza per iniziare AI Engineering Academy?
Non è richiesta alcuna esperienza precedente. AI Engineering Academy su CoddyKit è strutturato per principianti e studenti avanzati, quindi puoi iniziare da qui o dall'inizio e procedere al tuo ritmo. Questa è la lezione 2 di 4.
Quanto tempo richiede la lezione «Riordinamento con cross-encoder: Cohere e BGE»?
La maggior parte delle lezioni CoddyKit richiede circa 5–10 minuti. Ogni lezione è breve e interattiva, quindi fai progressi costanti e riprendi esattamente da dove hai lasciato su web e app.
Posso scrivere ed eseguire codice in questa lezione AI Engineering Academy?
Sì. Ogni lezione AI Engineering Academy include un editor di codice integrato, quindi scrivi ed esegui codice reale direttamente nel tuo browser e ricevi feedback istantaneo dall'IA — nessuna configurazione locale necessaria.
Tutte le lezioni di questo corso
- Perché il retrieval a due fasi funziona
- Riordinamento con cross-encoder: Cohere e BGE
- Compressione contestuale e filtro della rilevanza
- Misurare l'impatto del re-ranking