Hai un modello di embedding che produce vettori da 1536 dimensioni, una collezione di 100.000 documenti e un'applicazione RAG che deve rispondere in meno di due secondi. Il problema non è più generare gli embedding, ma dove metterli e come interrogarli in modo efficiente. Chroma, Pinecone e Weaviate sono le tre risposte più frequenti – ma sono molto diverse tra loro. Sbagliare scelta significa o pagare per infrastruttura che non usi, o bloccarti su un prodotto che non scala. Noi di Meteora Web abbiamo integrato tutti e tre in progetti reali. Questa guida ti dà i criteri operativi per decidere, con codice che puoi copiare e testare subito.
Il problema reale: dove finiscono i tuoi embedding?
Immagina di aver tokenizzato un manuale di 500 pagine, generato un embedding per ogni paragrafo e di voler fare semantic search. Se metti i vettori in una lista Python e fai cosine similarity per ogni richiesta, per 10.000 documenti sei già a ~50 ms, per 500.000 sopra il secondo. Non scala. Un vector database (o motore di indicizzazione vettoriale) fa due cose: indicizza i vettori con strutture come HNSW o IVF, e permette di fare approximate nearest neighbor (ANN) in tempi logaritmici o sub-lineari.
Chroma: la semplicità che ti fa partire in 5 minuti
Chroma nasce per sviluppatori che vogliono prototipare velocemente. È open source, leggero, e usa SQLite o DuckDB come backend. Perfetto per progetti personali, demo o applicazioni con poche decine di migliaia di documenti.
Sponsored Protocol
Installazione e primo esempio
pip install chromadbimport chromadb
from chromadb.utils import embedding_functions
client = chromadb.Client()
collection = client.create_collection("manuale_tecnico")
# Aggiungi documenti con embedding generati on-the-fly (default: all-MiniLM-L6-v2)
collection.add(
documents=[
"Il server si avvia in 30 secondi.",
"La configurazione di rete richiede un indirizzo IP statico."
],
ids=["doc1", "doc2"]
)
# Query semantica
results = collection.query(query_texts=["come avviare il server"], n_results=1)
print(results['documents'][0]) # ['Il server si avvia in 30 secondi.']Attenzione: Chroma di default include un modello di embedding locale, ma in produzione conviene passare embedding pre-generati da un modello esterno (es. OpenAI text-embedding-ada-002) per coerenza tra add e query.
Quando usare Chroma
Vantaggi: zero configurazione, nessun server esterno, persistenza su file, ideale per CI/CD e test. Limiti: la scalabilità è legata alla memoria del processo; oltre 500K vettori inizia a rallentare. Inoltre, non offre ricerca ibrida (vettoriale + lessicale) out-of-the-box.
Conviene se: stai sviluppando un proof-of-concept, hai < 200K documenti, non vuoi gestire un database separato, e la tua applicazione può tollerare riavvii della collection.
Sponsored Protocol
Pinecone: produzione serverless senza mal di testa
Pinecone è un servizio cloud gestito, progettato per scalare a miliardi di vettori con latenza sotto i 10 ms. Non devi installare nulla, né preoccuparti di server o indici: tutto è astratto via API REST. Attenzione però: è a pagamento e il prezzo cresce linearmente con il numero di vettori e la dimensionalità.
Configurazione e query
pip install pinecone-clientimport pinecone
pinecone.init(api_key="YOUR_API_KEY", environment="us-west1-gcp")
# Crea un indice
if "manuale" not in pinecone.list_indexes():
pinecone.create_index("manuale", dimension=1536, metric="cosine")
index = pinecone.Index("manuale")
# Inserisci (passa tuoi embedding)
index.upsert([
("doc1", [0.1]*1536, {"testo": "Il server si avvia in 30 secondi."}),
("doc2", [0.2]*1536, {"testo": "La configurazione di rete richiede un IP statico."})
])
# Query con embedding
query_embedding = [0.15]*1536
result = index.query(query_embedding, top_k=1, include_metadata=True)
print(result['matches'][0]['metadata']['testo'])Vantaggi: zero manutenzione, scalabilità orizzontale automatica, namespace per multi-tenancy, integrazione nativa con LangChain. Limiti: vendor lock-in (dati escono solo via API), costi non trascurabili ($70+/mese per un milione di vettori 1536D), niente ricerca ibrida unless usi Pinecone's sparse-dense.
Sponsored Protocol
Conviene se: hai >500K vettori, priorità alla latenza e uptime, non vuoi gestire infrastruttura, budget disponibile.
Weaviate: il coltellino svizzero open source
Weaviate è un database vettoriale open source con supporto nativo per ricerca ibrida (vettoriale + lessicale), moduli di embedding integrati (OpenAI, Cohere, Hugging Face), multi-tenancy, e la possibilità di girare in Docker o Kubernetes. È il più flessibile, ma richiede competenze DevOps per gestirlo in produzione.
Avvio e query con Docker
docker run -d -p 8080:8080 \
-e AUTHENTICATION_ANONYMOUS_ACCESS_ENABLED=true \
-e PERSISTENCE_DATA_PATH='/var/lib/weaviate' \
semitechnologies/weaviate:latestpip install weaviate-clientimport weaviate
client = weaviate.Client("http://localhost:8080")
# Crea una classe (schema) con modulo vettoriale 'text2vec-openai'
class_obj = {
"class": "Documento",
"vectorizer": "text2vec-openai",
"moduleConfig": {
"text2vec-openai": {
"model": "ada",
"modelVersion": "002"
}
},
"properties": [
{"name": "testo", "dataType": ["text"]}
]
}
client.schema.create_class(class_obj)
# Importa dati (il vettore viene generato automaticamente da OpenAI)
client.data_object.create({
"testo": "Il server si avvia in 30 secondi."
}, "Documento")
# Query ibrida (vettoriale + BM25)
where_filter = {
"path": ["testo"],
"operator": "Like",
"valueString": "*avvia*"
}
result = client.query.get("Documento", ["testo"]).with_hybrid(query="avvio server", alpha=0.7).with_where(where_filter).do()
print(result['data']['Get']['Documento'])Vantaggi: open source, ricerca ibrida potente, auto-vectorizzazione, replica e sharding nativi, supporto per migliaia di classi (multi-modello). Limiti: operatività complessa (Docker/K8s, backup, tuning), consumo risorse elevato, curva di apprendimento maggiore.
Sponsored Protocol
Conviene se: hai competenze DevOps, vuoi evitare lock-in, hai bisogno di ricerca vettoriale + full-text, volumi fino a centinaia di milioni di vettori.
Tabella comparativa
(Pensala come un foglio di calcolo decisionale. I costi sono indicativi, aggiornali al tuo fornitore.)
| Caratteristica | Chroma | Pinecone | Weaviate |
|---|---|---|---|
| Installazione | pip install | API key (cloud) | Docker / K8s |
| Ricerca ibrida | No (solo vettoriale) | Sì (sparse-dense) | Sì (BM25 + vettoriale) |
| Scalabilità | Decine di k vettori | Miliardi | Centinaia di M |
| Costo (1M vettori 1536D) | 0€ (locale) | ~$70/mese | $0€ + costi server |
| Controllo dati | Full (file SQLite) | Vendor | Full (self-hosted) |
| Multi-tenancy | Separate collection | Namespace | Tenant per classe |
| Latenza (100k vettori) | ~20ms | ~5ms | ~10ms |
| Moduli AI integrati | Solo embedding locale | No (devi passare vettori) | OpenAI, Cohere, HuggingFace, ... |
Criteri di scelta: il nostro flusso decisionale
Noi, di Meteora Web, partiamo sempre da tre domande:
Sponsored Protocol
- Quanti vettori devi indicizzare oggi – e tra 6 mesi? Sotto 200K -> Chroma è sufficiente. Fino a 5M -> Weaviate (se hai DevOps) o Pinecone (se vuoi zero gestione). Oltre 50M -> Pinecone scala meglio.
- Hai bisogno di ricerca ibrida (keyword + vettoriale)? Se sì, Weaviate è la scelta più matura. Pinecone ha sparse-dense ma è meno flessibile.
- Qual è la tua priorità tra costo operativo e latenza? Budget basso e competenze tecniche -> Weaviate (auto-hosted) o Chroma. Budget di produzione e zero stress -> Pinecone.
Un caso tipico: stai costruendo un assistente per un'azienda con 50K documenti tecnici. Non vuoi gestire server. In `LangChain`, puoi usare `PineconeVectorStore` in 10 righe. Se invece devi rispettare GDPR e i dati non possono uscire dall'infrastruttura aziendale, Weaviate su un server on-prem è la strada.
In sintesi – cosa fare adesso
- Installa Chroma e fai un test con un dataset di 10K documenti: capisci se fa al caso tuo.
- Se la latenza o la scalabilità diventano un problema, prova Pinecone con il tier gratuito (1M vettori).
- Se hai bisogno di ricerca ibrida o vuoi evitare lock-in, lancia Weaviate in Docker e importa i tuoi dati.
- In ogni caso, non ottimizzare prima del tempo: parti con lo strumento più semplice e migra solo quando misuri il collo di bottiglia.
Per approfondire l'integrazione con LangChain, leggi la nostra Pillar Guide su LangChain e LLM.