Embedding testuali per RAG e ricerca - Python, Ollama, API compatibili con OpenAI
Embedding RAG - Python, Ollama, API OpenAI.
Se stai approfondendo la generazione potenziata dal recupero (RAG), questa sezione illustra le embeddings testuali in termini semplici: cosa sono, come si integrano nella ricerca e nel recupero, e come invocare due configurazioni locali comuni da Python utilizzando Ollama o un’API HTTP compatibile con OpenAI (come espongono molti server basati su llama.cpp).

Per i client in Go e i confronti di SDK per Ollama, consulta SDK Go per Ollama — confronto con esempi.
Cos’è un embedding testuale?
Un embedding testuale è un vettore (una lista di numeri in virgola mobile) prodotto da un modello di embedding. Il modello mappa testo di lunghezza variabile in uno spazio a dimensioni fisse in modo che i testi con significato simile tendano a trovarsi vicini secondo una misura di distanza o similarità (spesso similarità del coseno su vettori normalizzati L2).
Gli embeddings non sono gli stessi degli ID dei token e non sono la stessa cosa di una chat di completamento. Sono uno strato di rappresentazione che si utilizza per la ricerca, il clustering, la deduplicazione e, nella RAG, per il recupero.
Casi d’uso comuni
| Caso d’uso | Ruolo degli embeddings |
|---|---|
| Ricerca semantica / Recupero RAG | Embedding delle query e dei frammenti dei documenti; ordinamento per similarità per recuperare passaggi pertinenti. |
| Reranking con modelli di embedding | Embedding della query e di ogni candidato; punteggio delle coppie in base alla similarità (vedi Reranking con modelli di embedding). |
| Clustering e deduplicazione | Raggruppare o deduplicare elementi nello spazio degli embedding senza etichettare manualmente ogni esempio. |
| Punteggio in stile classificazione | Confrontare il testo con descrizioni prototipo o nomi di classi nello stesso spazio (le variano in base al modello). |
Per impostazioni multimodali (immagine-testo e concetti correlati), vedi Embeddings cross-modali.
Embeddings all’interno di una pipeline RAG
Un percorso offline tipico è:
- Suddividere (chunking) i documenti (dimensione, sovrapposizione e struttura contano — vedi Strategie di chunking nella RAG).
- Creare l’embedding di ogni frammento; opzionalmente memorizzare metadati (ID sorgente, sezione, ACL).
- Indicizzare i vettori in memoria, in un indice di libreria o in un database vettoriale (compromessi in Archivi vettoriali per la RAG — confronto).
Al momento della query:
- Creare l’embedding della query dell’utente (una stringa breve o un piccolo batch).
- Recuperare i k frammenti più simili tramite ricerca vettoriale (opzionalmente più ricerca ibrida/keyword).
- Costruire un prompt dai frammenti di testo puro recuperati e invocare il modello di chat.
Sfumatura importante: i grandi modelli linguistici nelle API di chat consumano testo (e strumenti), non tensori di embedding arbitrari. Si usano gli embeddings per scegliere quale testo iniettare. Se vedi “interrogare il LLM con embedding precalcollati”, nella pratica ciò significa recuperare con gli embedding, poi inviare il testo selezionato al LLM.
Ottenere embeddings con Ollama (Python)
Ollama espone un’API HTTP. Per gli embedding, chiama POST /api/embed sul tuo host Ollama (default http://127.0.0.1:11434). Il corpo JSON include un nome model e un input (una stringa o una lista di stringhe). La risposta include embeddings, una lista di vettori allineata con i tuoi input.
Installa httpx (o usa requests allo stesso modo).
import httpx
OLLAMA = "http://127.0.0.1:11434"
MODEL = "nomic-embed-text" # sostituisci con un modello di embedding che hai scaricato
def embed_ollama(texts: list[str]) -> list[list[float]]:
r = httpx.post(
f"{OLLAMA}/api/embed",
json={"model": MODEL, "input": texts},
timeout=120.0,
)
r.raise_for_status()
data = r.json()
return data["embeddings"]
if __name__ == "__main__":
q = "Cos'è la generazione potenziata dal recupero?"
chunks = [
"La RAG combina il recupero con la generazione.",
"Gli embeddings mappano il testo in uno spazio vettoriale per la ricerca per similarità.",
]
qv = embed_ollama([q])[0]
doc_vs = embed_ollama(chunks)
print(len(qv), len(doc_vs), len(doc_vs[0]))
Note operative
- Scarica prima il modello (
ollama pull …per il tag scelto). Per i modelli di classe Qwen3 su Ollama, vedi Modelli di Embedding e Reranker Qwen3 su Ollama. - Sotto carico, il throughput degli embeddings interagisce con il modo in cui Ollama pianifica il lavoro — vedi Come Ollama gestisce le richieste parallele.
Ottenere embeddings con un server compatibile OpenAI (Python)
Molti server locali (incluse le comuni configurazioni HTTP di llama.cpp) espongono route compatibili con OpenAI come POST /v1/embeddings. Puoi utilizzare il pacchetto Python ufficiale openai e puntare base_url alla radice …/v1 del tuo server.
from openai import OpenAI
# Esempio — sostituisci host, porta e ID modello con i valori del tuo server
client = OpenAI(
base_url="http://127.0.0.1:8080/v1",
api_key="not-needed", # molti server locali ignorano questo
)
def embed_openai_compatible(text: str, model: str) -> list[float]:
r = client.embeddings.create(model=model, input=text)
return r.data[0].embedding
if __name__ == "__main__":
v = embed_openai_compatible("ciao da llama.cpp", "your-embedding-model-id")
print(len(v))
Perché mantenere entrambi i pattern in una pagina? I concetti (chunk, embed, indicizza, query, recupera testo) sono identici; cambia solo la superficie HTTP. Un articolo in stile workshop evita di duplicare la stessa narrazione sotto due URL.
Persistere vettori e interrogarli
Al minimo, devi memorizzare tre cose per frammento: vettore, testo e metadati (ID sorgente, offset, ACL). Per un prototipo rapido puoi tenere tutto in una lista Python e usare la similarità del coseno con NumPy o scikit-learn. Per dati in crescita, usa un database vettoriale o un indice di libreria (FAISS, ecc.); vedi Archivi vettoriali per la RAG — confronto per i compromessi a livello di prodotto.
Ciclo di query concettuale:
query_vec = embed(query)neighbors = index.search(query_vec, k)context = "\n\n".join(chunk.text for chunk in neighbors)- Invia
contexte la domanda dell’utente alla tua API di chat.
Reranking dopo il recupero
Un reranker (spesso un cross-encoder o un secondo modello di punteggio) può riordinare i candidati migliori dopo il recupero vettoriale. Questo sito ha esempi in Python e Go, inclusi Reranking con modelli di embedding e Reranking con Ollama e Qwen3 Embedding in Go.
Su questo sito — articoli correlati
| Argomento | Articolo |
|---|---|
| Architettura RAG completa | Tutorial RAG — architettura, implementazione, produzione |
| Chunking prima di creare l’embedding | Strategie di chunking nella RAG |
| Scelta del DB vettoriale | Archivi vettoriali per la RAG — confronto |
| Qwen3 su Ollama | Embedding e Reranker Qwen3 su Ollama |
| Cross-modale | Embeddings cross-modali |
| CLI e consigli Ollama | Ollama cheatsheet |
| Go + Ollama | Utilizzo di Ollama in Go — confronto SDK |
Link utili
- Ollama — modelli e runtime
- API Ollama — embed — riferimento API upstream per
/api/embed - Libreria Python OpenAI — funziona con qualsiasi
base_urlcompatibile con OpenAI