Un embedding è un vettore numerico che cattura il significato; un database vettoriale archivia e cerca quei vettori per similarità, non per uguaglianza esatta. Le due idee sono una sola capacità: un modello trasforma il testo (o le immagini, o l’audio) in un elenco di numeri posizionati in modo che un significato simile finisca vicino, e un database vettoriale trova in fretta i punti più prossimi. È tutto il trucco dietro la ricerca semantica, le raccomandazioni e il RAG – e per chi sviluppa applicazioni il titolo pratico è che gli embedding sono semplicemente un campo archiviato accanto ai dati che descrivono.
Punti chiave
| Domanda | Risposta |
|---|---|
| Embedding | Un vettore in cui un significato simile → punti vicini |
| Database vettoriale | Archivia vettori e risponde a “il più prossimo a questo” tramite indici ANN |
| La metrica | Cosseno (il solito per il testo) · prodotto scalare · euclidea |
| Esatta vs. ANN | Perfetta ma lineare contro ~99 % di richiamo, più rapida di ordini di grandezza |
| Serve uno dedicato? | Di solito no fino a ~1 milione di vettori – è probabile che il database lo faccia già |
Gli embedding, in concreto
Dimenticare per un momento le 1.536 dimensioni e immaginarne tre: un modello giocattolo che assegna a ogni parola un punteggio su è-animale, è-veicolo, è-piccolo.
animale veicolo piccolo
gattino 0.95 0.02 0.90
gatto 0.93 0.01 0.60
camion 0.03 0.96 0.05
motocicletta 0.04 0.94 0.55
"gattino" sta vicino a "gatto" (entrambi molto animale) e lontano da "camion".
distance(gattino, gatto) → piccola → simili
distance(gattino, camion) → grande → non correlati
I modelli reali usano centinaia o migliaia di dimensioni invece di tre,
apprese dai dati invece che etichettate a mano – ma l'intuizione è esattamente questa:
il significato diventa geometria e "simile" diventa "vicino".
La dimostrazione famosa che tutto questo cattura una struttura reale è l’aritmetica sui vettori: negli embedding di parole addestrati, re − uomo + donna cade vicino a regina. Il significato trasformato in coordinate fa algebra.
Come funziona la ricerca per similarità
Tre metriche di distanza dominano: il cosseno misura l’angolo fra i vettori (ignorando la lunghezza), il prodotto scalare incorpora il modulo e l’euclidea è la distanza in linea retta. L’intuizione che risparmia confusione: per vettori normalizzati tutte e tre ordinano i risultati in modo identico e, poiché i modelli di embedding testuale producono tipicamente vettori normalizzati tarati per il cosseno, la domanda “quale metrica?” ha di solito già una risposta.
Esatta vs. approssimata: il trade-off dell’ANN
| Esatta (kNN) | Approssimata (ANN) | |
|---|---|---|
| Confronta con | Ogni vettore | Un sottoinsieme astuto |
| Richiamo | 100 % | ~95–99 %, regolabile |
| Velocità | Lineare – O(n) | Quasi logaritmica |
| Adeguata fino a | ~1 milione di vettori | Decine di milioni e oltre |
| Costo | CPU per query | RAM per il grafo |
La ricerca esatta confronta la query con ogni vettore archiviato: perfetta, e perfettamente adeguata fino a circa un milione di vettori. Oltre quella soglia, HNSW – l’indice approssimato dominante – costruisce un grafo di prossimità a livelli (livelli superiori radi per i salti lunghi, un livello inferiore denso che contiene tutto) e scende in modo greedy dal grossolano al fine, saltando la maggior parte dei confronti. È un cugino semantico del B-tree: dove un B-tree indicizza “uguale a” e “minore di”, un indice ANN indicizza “simile a”. L’avvertenza onesta che i concorrenti ammorbidiscono: l’ANN può mancare il vero vicino più prossimo, i suoi parametri scambiano richiamo contro velocità e memoria, e il grafo vive in RAM – ed è per questo che dimensionare un database vettoriale è in realtà un discorso di memoria.
Indice vettoriale vs. database vettoriale
Una distinzione che la zuppa di termini offusca: una libreria di indici in memoria (come FAISS) calcola i vicini più prossimi ma non persiste, non aggiorna e non filtra – si reindicizza al riavvio e non esiste una clausola WHERE. Un database vettoriale avvolge l’indice con durabilità, aggiornamenti incrementali e filtro per metadati. Quel divario è esattamente il motivo per cui “basta usare una libreria” fallisce in produzione e per cui il database già in uso con un indice vettoriale è spesso la risposta giusta: ha già la durabilità, le transazioni e i permessi che alla libreria mancano.
Serve davvero un database vettoriale dedicato?
La risposta neutra che le pagine dei vendor non possono dare. Un database generico con supporto ai vettori – Postgres tramite pgvector, gli indici vettoriali HNSW di MongoDB sui campi array – serve comodamente circa fino a un milione di vettori per nodo, stando proprio accanto ai dati dell’applicazione e ai suoi permessi. Un motore dedicato si ripaga il costo operativo e la propria tassa di sincronizzazione fra due sistemi (tenere il deposito dei vettori coerente con il database che è fonte di verità) a scale davvero grandi: decine di milioni di vettori, frequenze di query molto elevate o un richiamo elevato richiesto sotto filtri pesanti. Sotto il milione di vettori circa, un deposito specializzato costa di solito più in codice collante di quanto restituisca in prestazioni – l’aritmetica che la maggior parte delle pagine “serve un database vettoriale” non può strutturalmente fare, perché sono loro il database vettoriale.
Il filtro per metadati è il confine di sicurezza
La similarità vettoriale ordina per significato e non sa nulla di chi può leggere che cosa – perciò la query di produzione non è mai “i dieci vicini più prossimi”, è “i dieci vicini più prossimi che questo utente ha il diritto di vedere”. Sbagliare l’ordine non è un bug di pertinenza, è una fuga di dati: il pre-filtro restringe i candidati all’insieme consentito prima della ricerca ANN (corretto); il post-filtro taglia dopo e insieme rivela l’esistenza degli elementi proibiti e restituisce in silenzio meno di k. Quando il filtro sono le ACL, il pre-filtro è la differenza fra una ricerca semantica e una violazione – la stessa lezione che il RAG impara per le vie difficili. Archiviare gli embedding nel database che già applica i permessi è il modo in cui il filtro arriva gratis.
Embedding da codice reale
// JavaScript — Cloud Code (cloud/main.js)
// Embeddings live as a field next to the data they describe
Parse.Cloud.beforeSave('Doc', async (req) => {
if (req.object.dirty('text')) {
// generate server-side; embedding API key stays on the server
req.object.set('embedding', await embed(req.object.get('text')));
req.object.set('embedModel', 'text-embed-v3'); // version it — models differ
}
});
// Similarity search, ACL-filtered: "nearest neighbors this user MAY see"
Parse.Cloud.define('semanticSearch', async (req) => {
const qVec = await embed(req.params.q);
return vectorSearch('Doc', qVec, { limit: 10, aclUser: req.user });
// The pre-filter is the security boundary, not a relevance tweak.
}); // Flutter / Dart — Back4app Flutter SDK
// The client searches by meaning — the vector math is server-side
final results = await ParseCloudFunction('semanticSearch')
.execute(parameters: {'q': 'how do refunds work?'});
for (final doc in results.result) print(doc['title']);
// "refund policy" matches "money back" though they share no keywords —
// because their embeddings are near each other. Filtered to your ACL. // iOS / Swift — Back4app Swift SDK
// The client searches by meaning — the vector math is server-side
let results: [[String: Any]] = try await Cloud.run(
name: "semanticSearch",
parameters: ["q": "how do refunds work?"])
for doc in results { print(doc["title"] ?? "") }
// "refund policy" matches "money back" though they share no keywords —
// because their embeddings are near each other. Filtered to your ACL. // Android / Kotlin — Back4app Android SDK
// The client searches by meaning — the vector math is server-side
val params = mapOf("q" to "how do refunds work?")
val results = ParseCloud.callFunction<List<Map<String, Any>>>(
"semanticSearch", params)
results.forEach { println(it["title"]) }
// "refund policy" matches "money back" though they share no keywords —
// because their embeddings are near each other. Filtered to your ACL. Si noti il campo embedModel: i vettori di modelli diversi – o di versioni diverse di uno stesso modello – non sono confrontabili, quindi cambiare modello di embedding significa ricalcolare gli embedding dell’intero corpus. Conviene archiviare il nome del modello insieme ai vettori, altrimenti un aggiornamento silenzioso trasforma l’indice in rumore.
Casi d’uso tipici
- Ricerca semantica – “soldi indietro” trova “politica di rimborso” anche se non condividono parole chiave.
- Recupero per il RAG – andare a prendere i chunk che ancorano la risposta di un LLM.
- Raccomandazioni – elementi vicini alla cronologia di un utente nello spazio degli embedding.
- Deduplicazione e clustering – contenuti quasi identici come vettori quasi identici.
- Rilevamento di anomalie e frodi – i valori anomali sono vettori lontani da ogni esempio normale.
Dove far vivere i vettori? Matrice decisionale
| Situazione | Scegliere |
|---|---|
| Corpus alla scala dell’applicazione (< ~1 milione di vettori) | L’indice vettoriale del database già in uso – accanto ai dati |
| I vettori devono rispettare i permessi degli utenti | Il posto dove le ACL già si trovano |
| Decine di milioni di vettori, QPS elevati | Un motore vettoriale dedicato |
| Contano sia i termini esatti sia il significato | Ricerca ibrida con fusione dei ranking |
| Un prototipo rapido | pgvector, o un deposito incorporato – niente sovraingegneria |
| Un solo processo, senza bisogno di persistenza | Una libreria di indici (FAISS) – accettandone i limiti |
Limiti e trade-off
- Gli embedding codificano la visione del mondo del modello. Pregiudizi, punti ciechi e data di taglio dell’addestramento viaggiano insieme; la geometria è buona solo quanto il modello che l’ha disegnata.
- L’ANN è approssimato di proposito. Il richiamo va tarato sulla posta in gioco; “trova di solito la corrispondenza migliore” è il patto firmato in cambio della velocità.
- La versione del modello è uno schema. Ricalcolare gli embedding di un corpus grande al cambio di modello è una migrazione vera, non un interruttore di configurazione.
- La memoria è il tetto. I grafi HNSW vivono in RAM; i limiti di vettori per nodo sono limiti di memoria con un’altra etichetta.
- La similarità non è pertinenza. Essere vicini nello spazio vettoriale è un segnale forte, non una garanzia – la ricerca ibrida e il reranking esistono perché la ricerca vettoriale pura manca i termini esatti.
I vettori su Back4app
Back4app è una piattaforma open-source di Backend as a Service (BaaS) che combina database gestito, API REST e GraphQL generate automaticamente, autenticazione, archiviazione di file e funzioni serverless con Cloud Code. Poiché gira su MongoDB, la storia dell’archiviazione è quella che questo articolo raccomanda: un embedding è un campo array sull’oggetto che descrive – il documento e il suo vettore nello stesso record – con l’indicizzazione vettoriale HNSW come meccanismo reale sottostante. Le conseguenze si concatenano in modo pulito: le ACL che governano già ogni query diventano gratuitamente il pre-filtro sulla ricerca per similarità, così il recupero non può attraversare un confine di permessi; gli embedding vengono generati in un trigger beforeSave di Cloud Code che chiama un modello di embedding con la chiave tenuta lato server; e non c’è nessun servizio vettoriale separato da tenere sincronizzato, da mettere in sicurezza e da pagare. Per i corpus alla scala di applicazione che la maggior parte dei prodotti ha davvero, “database vettoriale” non è un sistema da adottare: è un campo da aggiungere.
Domande frequenti
Che cos'è un embedding in parole semplici?
Un elenco di numeri che un modello assegna a un dato – testo, un'immagine, audio – in modo che le cose con significato simile ricevano numeri simili. Due documenti sullo stesso argomento finiscono come punti vicini in uno spazio a molte dimensioni, ed è questo che permette a un computer di misurare il "simile".
Che cos'è un database vettoriale?
Un sistema che archivia gli embedding e risponde in fretta alla domanda "quali elementi archiviati sono più simili a questo", usando indici approssimati dei vicini più prossimi invece di ricerche per corrispondenza esatta. La parte "database" – durabilità, aggiornamenti, filtro per metadati – è ciò che lo separa da una semplice libreria di indici in memoria.
Come funziona la ricerca per similarità?
La query viene trasformata in vettore con lo stesso modello, poi confrontata con i vettori archiviati tramite una metrica di distanza: cosseno (solo l'angolo), prodotto scalare (angolo e modulo) o euclidea (distanza in linea retta). Con vettori normalizzati tutte e tre ordinano i risultati in modo identico, e i modelli di embedding testuale sono di solito tarati per il cosseno.
Qual è la differenza tra ricerca esatta e approssimata?
La ricerca esatta (kNN) confronta la query con ogni vettore: richiamo perfetto, ma tempo lineare, adeguato fino a circa un milione di vettori. L'approssimata (ANN, di solito HNSW) salta la maggior parte dei confronti per una velocità quasi logaritmica, scambiando qualche punto percentuale di richiamo con query più rapide di ordini di grandezza. Mancare di tanto in tanto il vero vicino più prossimo è di solito accettabile.
Che cos'è HNSW?
Hierarchical Navigable Small World, l'indice ANN dominante in produzione. Costruisce un grafo di prossimità a più livelli: i livelli superiori, radi, offrono scorciatoie a lungo raggio; il livello inferiore, denso, contiene ogni vettore; e la ricerca scende in modo greedy dal grossolano al fine. I suoi parametri scambiano richiamo contro velocità e memoria, e il grafo vive in RAM.
Serve un database vettoriale dedicato?
Di solito no, alla scala di un'applicazione. Un database generico con supporto agli indici vettoriali – Postgres con pgvector, la ricerca vettoriale di MongoDB – gestisce comodamente fino a circa un milione di vettori per nodo, proprio accanto ai dati dell'applicazione e ai suoi permessi. I motori dedicati si ripagano a decine di milioni di vettori, con frequenze di query molto elevate o con un richiamo elevato richiesto sotto filtri pesanti.
Che cos'è il filtro per metadati e perché conta?
È il vincolo della ricerca per similarità su alcuni campi: tenant, categoria, data, permessi. Il pre-filtro restringe i candidati prima della ricerca ANN; il post-filtro taglia dopo e può restituire in silenzio meno risultati di quanti ne siano stati chiesti. Le query di produzione sono quasi sempre filtrate e, quando il filtro riguarda i permessi, è un confine di sicurezza.
A che cosa servono i database vettoriali oltre al RAG?
Ricerca semantica, raccomandazioni, rilevamento di quasi-duplicati e rilevamento di anomalie o frodi (i valori anomali sono vettori lontani da tutto il resto), più similarità e clustering di immagini e audio. La retrieval-augmented generation è l'uso famoso; la ricerca per similarità è la capacità generale che le sta sotto.