Avanzato 12 minOttimizzazione

Aggiungere un reranker al proprio pipeline

Risposta diretta

Un reranker è un cross-encoder che rilegge ogni coppia domanda-passaggio e riordina i candidati restituiti dalla ricerca vettoriale: si recupera un ampio insieme di passaggi (da 20 a 100) e se ne conservano da 3 a 5, i migliori, per il modello. Per il francese, BAAI/bge-reranker-v2-m3 (licenza Apache 2.0, circa 568 milioni di parametri) è il punto di partenza più semplice, in locale, su GPU o anche su CPU se il volume rimane modesto.

Gli embedding recuperano passaggi affini a una domanda, non necessariamente passaggi che vi rispondono. Il reranker corregge questo difetto valutando ogni coppia domanda-passaggio in un solo calcolo. Questa guida spiega quando il suo costo è giustificato, quale modello scegliere per il francese, come integrarlo in trenta righe e come verificare sui tuoi documenti che migliori davvero i risultati.

Di Mohamed Meguedmi·Agg. 2026-09-30·Testato su Windows, macOS e Linux

#Reranker: a cosa serve in un pipeline RAG

Un reranker riceve la domanda e un passaggio, li legge insieme e restituisce un punteggio di pertinenza; i candidati vengono poi ordinati per punteggio decrescente e al modello linguistico vengono trasmessi solo i migliori. In una pipeline RAG locale, lo si inserisce tra il database vettoriale (ChromaDB, Qdrant, Weaviate) e il LLM: la ricerca vettoriale recupera, per esempio, 30 passaggi e il reranker ne seleziona 5. La scheda ufficiale di BAAI lo descrive così: a differenza di un modello di embedding, il reranker riceve la domanda e il documento in ingresso e produce direttamente una similarità, anziché un vettore. Il vantaggio è più evidente quando la risposta corretta si trova tra i candidati ma non in cima alla lista: passaggi che trattano l'argomento generale giusto senza rispondere alla domanda specifica occupano le prime posizioni e il modello genera quindi una risposta fuori tema o inventata. Se la risposta corretta non è tra i candidati, un reranker non può fare nulla: non cerca, ordina.

Un embedding genera un vettore per ogni documento, indipendentemente dalla domanda posta, e la distanza misura una vicinanza tematica complessiva. Due passaggi sullo stesso tema possono quindi ottenere punteggi simili, anche se solo uno contiene la risposta. Il cross-encoder esamina l'intera coppia: verifica se la data, il nome o la condizione richiesti figurano nel passaggio. È più preciso in questa valutazione locale, ma anche più costoso, perché ogni coppia richiede un passaggio nel transformer anziché un solo calcolo per documento.

i
La metafora
L'embedding è il bibliotecario che ti guida alla sezione giusta e ti porge venti libri. Il reranker è l'esperto che sfoglia questi venti libri con la tua domanda in mente e mette in cima i tre che rispondono.

#Bi-encoder e cross-encoder: perché si combinano entrambi

Il kit RAG Local

I tuoi documenti, la tua IA: un RAG locale affidabile sui tuoi PDF, sulle tue note e sulle tue email — senza inviare nulla nel cloud.

  • Spazio online a vita
  • PDF + file
  • Aggiornamenti a vita
Bi-encoder (embedding)
Codifica la domanda e ogni documento separatamente; i vettori dei documenti vengono calcolati una sola volta durante l'indicizzazione e la ricerca si riduce a un confronto tra vettori. Veloce, adatto a milioni di passaggi.
Cross-encoder (reranker)
Codifica domanda e passaggio insieme e restituisce un punteggio. Nessun calcolo può essere riutilizzato: deve essere rifatto per ogni domanda e ogni candidato. Preciso, ma impossibile da applicare a tutto il corpus.

La documentazione di Sentence Transformers spiega il ragionamento: valutare migliaia o milioni di coppie sarebbe piuttosto lento, quindi si usa il retriever per produrre un insieme di candidati, ad esempio un centinaio, che il cross-encoder riordina. Lo schema a due fasi è lo stesso dei motori di ricerca classici. Spiega anche il parametro principale: il numero di candidati recuperati determina sia il recall (più si amplia la selezione, maggiori sono le probabilità che contenga la risposta corretta) sia la latenza (ogni candidato aggiuntivo richiede un passaggio nel cross-encoder).

#Qual modello di reranking scegliere in francese

La scelta si basa su tre criteri: la lingua, la licenza e la memoria. I dati sulle dimensioni riportati qui sotto provengono dalle schede Hugging Face; nota che la dimensione del file dipende dalla precisione dei pesi: F32 per bge-reranker-v2-m3 (circa 4 byte per parametro), F16 per mxbai.

Rerankers utilizzabili localmente (schede Hugging Face, settembre 2026)
ModelloLingueDimensione dichiarataLicenzaVerdetto per il francese
BAAI/bge-reranker-v2-m3Multilingue0,6 miliardi di parametri, pesi in F32 (circa 2,3 GB)Apache 2.0Scelta predefinita: multilingue, leggero, con un buon ecosistema di strumenti
BAAI/bge-reranker-v2-gemmaMultilingue3 miliardi di parametri, pesi in F32 (circa 10 GB)Apache 2.0Da riservare ai casi più impegnativi con GPU dedicata; reranker basato su Gemma-2B
mixedbread-ai/mxbai-rerank-large-v1Inglese0,4 miliardi di parametri, pesi in F16Apache 2.0Da evitare per un corpus francese: la scheda indica l'inglese
Cohere RerankMultilingueServizio ospitatoCommercialeNon adatto a una pipeline locale al 100%: i brani di testo lasciano la tua macchina

La scheda di bge-reranker-v2-m3 lo presenta come un reranker leggero, con spiccate capacità multilingui, facile da distribuire e veloce in inferenza; la scheda di bge-reranker-v2-gemma lo indica per contesti multilingui, con buoni risultati sia in inglese sia in più lingue. Due correzioni utili rispetto a quanto si legge spesso: il file di bge-reranker-v2-m3 pesa più di 2 GB, non 560 MB (568 milioni di parametri in F32), e mxbai-rerank-large-v1 è un modello per la lingua inglese, da escludere per i documenti in francese. Una volta caricato in mezza precisione, il modello m3 occupa circa 1,1 GB per i pesi (568 milioni di parametri × 2 byte, calcolo di questa guida), ai quali si aggiungono le attivazioni del batch elaborato.

→
Modello di embedding e reranker sono indipendenti
Puoi cambiare l'uno senza reindicizzare l'altro: il reranker legge solo il testo dei passaggi, mai i loro vettori. Per scegliere il modello di embedding, vedere la guida dedicata ai modelli di embedding per il francese.

#La pipeline prima e dopo l'aggiunta del reranker

Prima / dopo
AVANT :
  Question → Embedding → Base vectorielle (top-5) → LLM

APRÈS :
  Question → Embedding → Base vectorielle (top-20 à top-50)
                       → Reranker (top-5) → LLM

On récupère large, puis on ordonne finement.

Due parametri governano l'intero sistema: k_retrieve, il numero di candidati restituiti dal database vettoriale, e k_final, il numero di passaggi trasmessi al LLM. Un k_final compreso tra 3 e 5 è adatto alla maggior parte dei modelli locali con un numero di parametri compreso tra 7 e 14 miliardi; oltre questo valore, si riempie la finestra di contesto senza un vantaggio netto e aumenta il tempo di elaborazione del prompt. k_retrieve dipende dalla difficoltà del corpus: 20 è un buon valore per un primo tentativo, da 50 a 100 se le domande sono vaghe o se il corpus contiene molti passaggi simili. La guida sulla finestra di contesto spiega nel dettaglio il costo dei passaggi aggiuntivi nel prompt.

#Implementazione: sentence-transformers, FlagEmbedding, llama.cpp

#Con sentence-transformers

La classe CrossEncoder carica il modello e valuta coppie. Il suo metodo rank accetta direttamente la domanda e l'elenco dei documenti e restituisce i migliori; il parametro top_k limita il numero di risultati (senza questo parametro, vengono restituiti tutti i documenti).

CrossEncoder.rank
from sentence_transformers import CrossEncoder

reranker = CrossEncoder("BAAI/bge-reranker-v2-m3", max_length=512)

def retrieve_and_rerank(question, k_retrieve=20, k_final=5):
    # 1. Récupération par embedding (ChromaDB, Qdrant, etc.)
    candidats = embedding_search(question, top_k=k_retrieve)  # liste de textes

    # 2. Scoring par le cross-encoder, tri et coupe en une seule étape
    resultats = reranker.rank(question, candidats, top_k=k_final, batch_size=16)
    # resultats = [{'corpus_id': 3, 'score': 0.91}, ...]
    return [candidats[r['corpus_id']] for r in resultats]

#Con FlagEmbedding, la libreria degli autori del modello

La pagina del modello utilizza la libreria FlagEmbedding. Specifica che il punteggio grezzo può essere riportato nell'intervallo tra 0 e 1 tramite una funzione sigmoide con normalize=True e che use_fp16=True accelera il calcolo a costo di una leggera diminuzione della qualità. Ricorda che il punteggio grezzo è un valore senza scala assoluta, spesso negativo per i passaggi fuori tema; conta solo l'ordine, a meno che tu non stabilisca una soglia.

FlagReranker
from FlagEmbedding import FlagReranker

reranker = FlagReranker('BAAI/bge-reranker-v2-m3', use_fp16=True)
score = reranker.compute_score(['ma question', 'un passage'], normalize=True)  # entre 0 et 1

#Con llama.cpp, senza Python

Il server llama.cpp offre un endpoint di reranking, disattivato per impostazione predefinita. La documentazione indica che richiede un modello di reranking, cita bge-reranker-v2-m3 come esempio e che il server si avvia con le opzioni --embedding e --pooling rank. Serve una versione GGUF del modello. È l'opzione da scegliere se il tuo stack è già costruito intorno a llama.cpp e vuoi evitare di installare PyTorch. Verifica l'opzione esatta nella versione installata: la documentazione avverte che questo endpoint potrebbe evolvere.

llama-server (da adattare alla tua versione)
llama-server -m bge-reranker-v2-m3-Q8_0.gguf --embedding --pooling rank --reranking --port 8081

#Con LlamaIndex

SentenceTransformerRerank
from llama_index.core.postprocessor import SentenceTransformerRerank

reranker = SentenceTransformerRerank(model="BAAI/bge-reranker-v2-m3", top_n=5)

query_engine = index.as_query_engine(
    similarity_top_k=20,
    node_postprocessors=[reranker],
)

#Costo: latenza, memoria, lunghezza dei passaggi

Nessun valore di latenza è garantito: dipende dalla scheda, dalla precisione (FP16 o FP32), dal numero di candidati e dalla lunghezza dei passaggi. Tieni conto delle proporzioni. Il tempo di reranking aumenta linearmente con il numero di coppie: passare da 20 a 100 candidati moltiplica il lavoro per cinque. Aumenta anche con la lunghezza del passaggio, poiché ogni coppia viene codificata integralmente. Misura sulla tua macchina con i tuoi passaggi invece di fidarti di un valore riportato su un blog: cronometra cento richieste reali e osserva il tempo mediano e il caso peggiore.

Numero di candidati
Prima leva su cui intervenire. Inizia da 20, misura il recall e aumenta a 50 solo se alcune risposte corrette restano fuori dall'insieme dei candidati.
Precisione
use_fp16=True (FlagEmbedding) o un caricamento a mezza precisione riduce l'uso di memoria e accelera il calcolo, con, secondo la scheda del modello, un leggero calo delle prestazioni.
Dimensione del lotto
Il metodo rank di sentence-transformers elabora per impostazione predefinita 32 coppie per batch. Riduci la dimensione del batch a 8 o 16 se la memoria non basta, aumentala se la GPU è sottoutilizzata.
Lunghezza massima
512 token per coppia (valore max_length degli esempi ufficiali). Un passaggio più lungo viene troncato: se i tuoi chunk superano questa dimensione, la fine del passaggio non viene letta. Riduci i chunk prima di aumentare il limite.
CPU o GPU
Su CPU, il reranker funziona, ma ogni richiesta con 20-50 candidati richiede secondi di elaborazione; è accettabile per un assistente documentale interno, meno per una chat interattiva.
→
Evitare il reranker quando non serve
Su un corpus piccolo e ben strutturato (qualche decina di pagine ben suddivise), il top-5 vectoriale contiene spesso già la risposta. Misurate prima, e tenete il reranker solo se il ricordo migliora.

#Reranker e suddivisione in chunk: le due impostazioni interagiscono

Un cross-encoder valuta un passaggio nella sua interezza. Se il passaggio mescola tre argomenti, il suo punteggio sarà medio per tutte e tre le domande corrispondenti; se è troppo breve, perde il contesto che permetterebbe di riconoscerlo come risposta. La suddivisione in passaggi di dimensioni medie, con una leggera sovrapposizione, fornisce al reranker materiale da valutare senza superare la sua lunghezza massima. Se cambi la dimensione dei chunk, ripeti il test di recall: il valore ottimale di k_retrieve e il beneficio del reranker cambiano al variare di questa dimensione. La guida sulle strategie di chunking illustra queste scelte in dettaglio.

Un'altra interazione è quella con la ricerca ibrida. Quando la ricerca per parole chiave (BM25) e la ricerca vettoriale vengono combinate, l'insieme dei candidati è più vario, il che dà al reranker maggiori possibilità di trovare una buona risposta che ciascun metodo, da solo, avrebbe mancato. Il reranker è l'ultimo stadio, la ricerca ibrida il secondo: si completano anziché sostituirsi.

#Misura il miglioramento sui tuoi documenti

Il miglioramento dichiarato nei blog varia da una a cinque volte a seconda del corpus, e nessun valore generale vale per il tuo. Su un corpus molto strutturato (documentazione tecnica pulita), la sola ricerca vettoriale dà già buoni risultati; su un corpus con molto rumore (email, note, PDF estratti male), il divario è più marcato. L'unico modo per saperlo è effettuare una valutazione.

  1. 01
    Preparare da 30 a 50 domande
    Prendi domande reali degli utenti e associa a ciascuna il passaggio che contiene la risposta (basta un identificativo).
  2. 02
    Misurare il recall a 5 senza reranker
    Per ogni domanda, controlla se il brano giusto compare nei primi 5 risultati del database vettoriale.
  3. 03
    Misurare il recall a 5 con reranker
    Recupera 20 candidati, riordinali per rilevanza e conta di nuovo i passaggi pertinenti tra i primi 5.
  4. 04
    Confrontare anche la latenza
    Annota il tempo mediano dall'inizio alla fine. Un miglioramento di qualche punto di recall non giustifica necessariamente un secondo di attesa in più.
  5. 05
    Guardare gli errori
    Per ogni domanda a cui è stata data una risposta sbagliata, verifica se la risposta corretta era tra i 20 candidati. In caso contrario, il problema è a monte: suddivisione in blocchi, embedding o estrazione del testo.
Valutare il recall
def rappel_a_k(pipeline, questions, cibles, k=5):
    ok = 0
    for q, cible in zip(questions, cibles):
        ok += cible in [p.id for p in pipeline(q)[:k]]
    return ok / len(questions)

sans = rappel_a_k(pipeline_sans_reranker, questions, cibles)
avec = rappel_a_k(pipeline_avec_reranker, questions, cibles)
print(f"Sans : {sans:.0%}   Avec : {avec:.0%}")
!
Limiti del reranker
Non corregge né un testo estratto male da un PDF, né una suddivisione che spezza la risposta in due, né una domanda ambigua. Può anche penalizzare passaggi brevi con un punteggio basso pur contenendo il numero giusto: verifica i casi di insuccesso invece di fidarti della media.

#Serve un reranker? Criteri di decisione

Quando aggiungere un reranker
SituazioneDecisione
Corpus di alcune decine di documenti puliti, risultati della ricerca vettoriale top-5 già buoniNo, misura prima
Buona risposta spesso tra il 6º e il 30º postoSì: è il caso d'uso tipico
Domande vaghe, corpus rumoroso o molto eterogeneoSì, con 30–50 candidati
Chat interattivo su macchina senza GPUAttenzione: misura la latenza sulla CPU, riduci a 10-20 candidati
Risposta corretta assente anche tra i primi 50 candidatiNo: correggi prima la suddivisione in chunk, gli embedding o l'estrazione

#Domande frequenti sul reranking

FAQ
Un reranker sostituisce la ricerca vettoriale?+
No. Non esamina l'intero corpus: riordina le poche decine di candidati che la ricerca vettoriale gli fornisce. Senza una prima fase rapida, bisognerebbe eseguirlo su ogni passaggio della base documentale, il che sarebbe decisamente troppo lento. Le due fasi si completano a vicenda: la ricerca vettoriale garantisce il richiamo, mentre il reranker migliora la precisione nelle prime posizioni della classifica.
Quale reranker scegliere per documenti in francese?+
BAAI/bge-reranker-v2-m3 è un punto di partenza ragionevole: multilingue, con licenza Apache 2.0 e circa 0,6 miliardi di parametri, quindi utilizzabile su una scheda grafica modesta. Evita mxbai-rerank-large-v1, la cui scheda indica l'inglese. Il modello bge-reranker-v2-gemma, più pesante, si giustifica solo se il primo non basta sul tuo insieme di domande.
Quanti candidati bisogna sottoporre al reranking?+
Inizia con 20 candidati e conserva 5 passaggi. Se, durante la valutazione, alcune risposte corrette rimangono fuori dai 20, aumenta a 50. Ogni candidato aggiuntivo richiede un calcolo in più, quindi la latenza aumenta in modo approssimativamente lineare. Oltre 100, ulteriori miglioramenti sono rari: spesso è il segnale di un problema di suddivisione in blocchi o di embedding.
Serve una GPU per un reranker?+
No, ma aiuta. Su CPU, il modello m3 funziona, con una latenza dell'ordine di un secondo o più per un gruppo di candidati, a seconda della macchina: da misurare sul tuo sistema. Questo resta accettabile per un uso documentale interno. Per una chat fluida, una GPU anche modesta, o un modello più leggero, cambia l'esperienza d'uso.
È possibile usare un reranker con Ollama?+
Ollama serve il modello di generazione e gli embedding, ma il reranking avviene separatamente: con sentence-transformers o FlagEmbedding in Python, oppure con il server llama.cpp che espone un endpoint di reranking. Il reranker è un modello distinto, caricato in un processo separato, che coesiste con il modello di generazione se la memoria lo permette.
Come capire se il reranker migliora veramente i miei risultati?+
Prepara da 30 a 50 domande reali con il passaggio atteso, poi confronta il recall nei primi 5 risultati con e senza reranker, oltre alla latenza mediana. Su un corpus pulito, la differenza può essere piccola; su un corpus rumoroso, è più netta. Analizza poi i casi di insuccesso per capire se dipendono da problemi a monte.
Questa guida ti è stata utile?

Un feedback, un errore, una precisazione? Facci sapere, così la guida migliora per tutti.