← Tutte le lezioni
Lezione 28 RAG e documenti 7:08

Database vettoriali: cercare per significato

Dove finiscono i vettori dei tuoi documenti e come si fa a ritrovarli in fretta. Indici, metriche di distanza e la scelta fra le opzioni che contano davvero, senza cambiare strumento tre volte.

Il video parte solo se lo chiedi: nessuna richiesta a YouTube prima del click.

Un database normale risponde a domande esatte: dammi le righe dove il nome è “Marco”. Un database vettoriale risponde a una domanda diversa: dammi i testi che parlano di qualcosa di simile a questo. È il pezzo che tiene in piedi il recupero, e l’unico componente della pipeline che si comporta come un’infrastruttura vera — con indici, compromessi e conti da fare.

SQL
  SELECT * FROM documenti WHERE titolo LIKE '%polimorfismo%'
  → trova solo se quella parola compare nel titolo

Vettoriale
  cerca(vettore("come funziona l'ereditarietà in Java"))
  → trova anche override, classi astratte, polimorfismo:
    significati vicini, parole diverse

Cosa contiene, davvero

Una riga in un archivio vettoriale non è solo un vettore. Sono tre cose, e servono tutte:

id:       "manuale-java#chunk-23"
vettore:  [0.23, 0.87, -0.12, 0.45, ...]     ← per cercare
testo:    "Il polimorfismo permette a..."     ← per rispondere
metadati: { fonte: "manuale.pdf", pagina: 145, sezione: "5.3" }

Il vettore serve a trovare, il testo serve al modello per rispondere, i metadati servono a filtrare e citare. Un archivio che salva solo i vettori ti costringe a tenere i testi da un’altra parte e a riallinearli a mano: sembra un dettaglio, diventa un problema alla prima reindicizzazione.

Come si misura la vicinanza

Tre metriche, ma la scelta è più semplice di quanto sembri.

Similarità del coseno. Guarda l’angolo fra due vettori e ignora la loro lunghezza. Va da -1 a 1, dove 1 vuol dire “stessa direzione”, cioè stesso significato. È lo standard per il testo, ed è quello che vuoi in quasi tutti i casi.

Distanza euclidea. La distanza in linea d’aria fra due punti. Tiene conto anche della lunghezza dei vettori, che nel testo di solito non significa nulla.

Prodotto scalare. Combina direzione e lunghezza. Su vettori normalizzati coincide con il coseno, ed è quello che diversi archivi usano sotto il cofano proprio per questo.

Regola pratica: coseno, e passa oltre. L’unica accortezza è restare coerente: se indicizzi con una metrica e cerchi con un’altra, i punteggi non vogliono dire niente.

Gli indici: perché non si confrontano tutti i vettori

Con mille pezzi puoi confrontare la domanda con tutti, uno per uno, e prendere i più vicini. È esatto e costa niente. Con un milione di pezzi la stessa cosa diventa improponibile, e allora si usa un indice che accetta di essere quasi esatto in cambio della velocità.

IndiceCome funzionaIl compromesso
Esatto (flat)Confronta tuttoPreciso al 100%, lento sui grandi numeri
HNSWGrafo navigabile a livelliMolto veloce, si mangia RAM
IVFRaggruppa i vettori in gruppiBuon equilibrio, va tarato
QuantizzazioneComprime i vettoriPoca RAM, un po’ di precisione persa

La cosa che conta: sotto il centinaio di migliaia di pezzi, l’indice esatto va benissimo. Prima di quella soglia, mettersi a tarare un HNSW è tempo speso a ottimizzare qualcosa che non è il problema. Il problema, a quel punto, è ancora il chunking.

C’è un’implicazione che sorprende: dal momento in cui usi un indice approssimato, il recupero può perdere un pezzo pertinente che l’indice esatto avrebbe trovato. Non è un difetto, è il prezzo scelto. Ma quando confronti la qualità di due configurazioni, ricordati che stai confrontando anche questo.

Le opzioni, in ordine di quando servono

ChromaFAISSLanceDBQdrantPinecone
Come giraNel tuo processoLibreriaNel tuo processoServerServizio cloud
In localeNo
Filtri sui metadatiNoAvanzati
Salva su disco da soloNo, a manoGestito
Per iniziareConsigliatoNoPoiNo
In produzionePiccola scalaCon impalcaturaMedia scala

Chroma per iniziare: si installa e funziona, salva su disco, tiene testo e metadati insieme. FAISS è la libreria più veloce in circolazione ma non è un database: niente persistenza, niente filtri: sei tu a doverti costruire il contorno. Qdrant è il passo successivo quando servono filtri seri o più utenti. Pinecone toglie la manutenzione e in cambio si porta i tuoi documenti su un servizio altrui — che per appunti personali o materiale aziendale è esattamente la domanda da farsi prima, non dopo.

I filtri sui metadati contano più della velocità

La ricerca puramente semantica ha un difetto pratico: non sa dire di no. Se chiedi qualcosa sul capitolo 5 e il capitolo 5 non parla di quello, ti restituisce comunque i pezzi meno lontani, presi da qualunque punto dell’archivio.

I filtri risolvono questo, e sono la ragione per cui i metadati vanno salvati fin dall’inizio:

cerca(vettore("rimborso spese"), filtro={ fonte: "regolamento-2026.pdf" })
cerca(vettore("polimorfismo"),   filtro={ capitolo: 5 })
cerca(vettore("ferie"),          filtro={ lingua: "it", anno: { ">=": 2025 } })

Un archivio senza filtri ti obbliga a fare la selezione dopo aver recuperato, cioè quando hai già sprecato il recupero. È il motivo principale per cui si cambia strumento a metà progetto.

Dove si sbaglia

Cambiare modello di embedding senza rifare l’archivio. I vecchi vettori vivono in uno spazio, i nuovi in un altro: le distanze diventano numeri senza senso. Non c’è un errore, c’è solo un recupero che peggiora senza motivo apparente. Se cambi modello, si ricostruisce tutto.

Reindicizzare senza svuotare. Rilanciare l’indicizzazione sugli stessi documenti senza cancellare produce doppioni: lo stesso testo occupa due o tre posti fra i primi risultati, e il modello riceve tre copie della stessa cosa invece di tre pezzi diversi.

Salvare i vettori e non i testi. Recuperi gli identificativi e poi devi andare a ripescare i testi da un’altra parte, sperando che nel frattempo nessuno abbia rinumerato i pezzi.

Ottimizzare l’indice prima del resto. Su archivi piccoli la scelta dell’indice non si sente: si sentono il chunking e il modello di embedding. L’ordine in cui vale la pena lavorare è quello, non il contrario.

Fidarsi del punteggio come se fosse una probabilità. Un coseno di 0,82 non vuol dire “82% giusto”. I punteggi sono confrontabili fra loro nella stessa ricerca, non in assoluto: la soglia sotto la quale scartare un risultato va misurata sui propri documenti, non copiata.

In sintesi

ConcettoIn una riga
Database vettorialeArchivia vettori e trova i più vicini a una domanda
Cosa salvareVettore per cercare, testo per rispondere, metadati per filtrare
MetricaCoseno, salvo casi particolari
Indice esattoSotto le centinaia di migliaia di pezzi va benissimo
Indici approssimatiVelocità in cambio di qualche pezzo pertinente perso
Da dove partireChroma in locale; Qdrant quando servono filtri o scala
Filtri sui metadatiSpesso più utili della velocità pura
Errore ricorrenteCambiare modello di embedding senza ricostruire l’archivio

Lezioni collegate

Guarda su YouTube