Embeddings de texte pour RAG et recherche - Python, Ollama, API compatibles OpenAI
Intégration RAG - Python, Ollama, API OpenAI.
Si vous travaillez sur la génération augmentée par récupération (RAG), cette section explique les incorporations de texte (text embeddings) en termes simples : ce qu’elles sont, comment elles s’intègrent dans la recherche et la récupération, et comment appeler deux configurations locales courantes depuis Python en utilisant Ollama ou une API HTTP compatible OpenAI (comme le font de nombreux serveurs basés sur llama.cpp).

Pour les clients Go et les comparaisons de SDK pour Ollama, consultez SDK Go pour Ollama — comparaison avec des exemples.
Qu’est-ce qu’une incorporation de texte ?
Une incorporation de texte est un vecteur (une liste de nombres à virgule flottante) produit par un modèle d’incorporation. Le modèle mappe du texte de longueur variable dans un espace à dimensions fixes, de sorte que les textes ayant un sens similaire tendent à se situer proche les uns des autres selon une mesure de distance ou de similarité (souvent la similarité cosinus sur des vecteurs normalisés en L2).
Les incorporations ne sont pas la même chose que les identifiants de jetons (token IDs) ni la même chose qu’une complétion de chat. Elles constituent une couche de représentation que vous utilisez pour la recherche, le regroupement (clustering), la déduplication et, dans le contexte de la RAG, la récupération.
Cas d’utilisation courants
| Cas d’utilisation | Rôle des incorporations |
|---|---|
| Recherche sémantique / Récupération RAG | Incorporer les requêtes et les extraits de documents ; classer par similarité pour récupérer des passages pertinents. |
| Reclassement avec des modèles d’incorporation | Incorporer la requête et chaque candidat ; noter les paires par similarité (voir Reclassement avec des modèles d’incorporation). |
| Regroupement et déduplication | Regrouper ou dédupliciter des éléments dans l’espace d’incorporation sans étiqueter manuellement chaque exemple. |
| Notation de style classification | Comparer le texte à des descriptions de prototypes ou à des noms de classes dans le même espace (les modèles varient selon le modèle). |
Pour les configurations multimodales (image–texte et concepts connexes), consultez Incorporations intermodales.
Incorporations dans un pipeline RAG
Un parcours hors ligne typique est le suivant :
- Fragmenter les documents (la taille, le chevauchement et la structure comptent — voir Stratégies de fragmentation dans RAG).
- Incorporer chaque fragment ; stocker facultativement des métadonnées (ID source, section, ACL).
- Indexer les vecteurs en mémoire, dans un index de bibliothèque ou dans une base de données vectorielle (compromis dans Stores vectoriels pour RAG — comparaison).
Au moment de la requête :
- Incorporer la requête utilisateur (une courte chaîne ou un petit lot).
- Récupérer les k meilleurs fragments similaires par recherche vectorielle (facultativement avec recherche hybride / mots-clés).
- Construire un prompt à partir des fragments de texte brut récupérés et appeler votre modèle de chat.
Nuance importante — les grands modèles de langage dans les API de chat consomment du texte (et des outils), pas des tenseurs d’incorporation arbitraires. Vous utilisez les incorporations pour choisir quel texte injecter. Si vous voyez « interroger le LLM avec des incorporations précalculées », en pratique, cela signifie récupérer avec des incorporations, puis envoyer le texte sélectionné au LLM.
Obtenir des incorporations avec Ollama (Python)
Ollama expose une API HTTP. Pour les incorporations, appelez POST /api/embed sur votre hôte Ollama (par défaut http://127.0.0.1:11434). Le corps JSON inclut un nom de model et un input (une chaîne ou une liste de chaînes). La réponse inclut embeddings, une liste de vecteurs alignés avec vos entrées.
Installez httpx (ou utilisez requests de la même manière).
import httpx
OLLAMA = "http://127.0.0.1:11434"
MODEL = "nomic-embed-text" # remplacez par un modèle d'incorporation que vous avez téléchargé
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 = "Qu'est-ce que la génération augmentée par récupération ?"
chunks = [
"RAG combine la récupération avec la génération.",
"Les incorporations mappent le texte dans un espace vectoriel pour la recherche de similarité.",
]
qv = embed_ollama([q])[0]
doc_vs = embed_ollama(chunks)
print(len(qv), len(doc_vs), len(doc_vs[0]))
Notes opérationnelles
- Téléchargez d’abord le modèle (
ollama pull …pour votre balise choisie). Pour les modèles de classe Qwen3 sur Ollama, consultez Modèles d’incorporation et de reclassement Qwen3 sur Ollama. - Sous charge, le débit d’incorporation interagit avec la façon dont Ollama planifie le travail — voir Comment Ollama gère les requêtes parallèles.
Obtenir des incorporations avec un serveur compatible OpenAI (Python)
De nombreux serveurs locaux (y compris les configurations HTTP courantes de llama.cpp) exposent des routes compatibles OpenAI telles que POST /v1/embeddings. Vous pouvez utiliser le package Python officiel openai et pointer base_url vers la racine …/v1 de votre serveur.
from openai import OpenAI
# Exemple — remplacez l'hôte, le port et l'ID de modèle par les valeurs de votre serveur
client = OpenAI(
base_url="http://127.0.0.1:8080/v1",
api_key="not-needed", # beaucoup de serveurs locaux ignorent ceci
)
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("bonjour de llama.cpp", "your-embedding-model-id")
print(len(v))
Pourquoi garder les deux modèles sur une seule page ? Les concepts (fragmenter, incorporer, indexer, requêter, récupérer le texte) sont identiques ; seule la surface HTTP change. Un article de style atelier évite de dupliquer le même récit sous deux URL.
Persister les vecteurs et les interroger
Au minimum, vous devez stocker trois éléments par fragment — le vecteur, le texte et les métadonnées (ID source, offsets, ACL). Pour un prototype rapide, vous pouvez tout conserver dans une liste Python et utiliser la similarité cosinus avec NumPy ou scikit-learn. Pour des données en croissance, utilisez une base de données vectorielle ou un index de bibliothèque (FAISS, etc.) ; consultez Stores vectoriels pour RAG — comparaison pour les compromis au niveau du produit.
Boucle de requête conceptuelle :
query_vec = embed(query)neighbors = index.search(query_vec, k)context = "\n\n".join(chunk.text for chunk in neighbors)- Envoyer
contextet la question de l’utilisateur à votre API de chat.
Reclassement après récupération
Un reclasseur (souvent un cross-encoder ou un second modèle de notation) peut réorganiser les meilleurs candidats après la récupération vectorielle. Ce site propose des exemples en Python et en Go, notamment Reclassement avec des modèles d’incorporation et Reclassement avec Ollama et Qwen3 Embedding en Go.
Sur ce site — articles connexes
| Sujet | Article |
|---|---|
| Architecture RAG complète | Tutoriel RAG — architecture, implémentation, production |
| Fragmentation avant incorporation | Stratégies de fragmentation dans RAG |
| Choix de la DB vectorielle | Stores vectoriels pour RAG — comparaison |
| Qwen3 sur Ollama | Qwen3 Embedding & Reranker sur Ollama |
| Intermodal | Incorporations intermodales |
| CLI et astuces Ollama | Fiche de référence Ollama |
| Go + Ollama | Utiliser Ollama en Go — comparaison SDK |
Liens utiles
- Ollama — modèles et runtime
- API Ollama — embed — référence API en amont pour
/api/embed - Bibliothèque Python OpenAI — fonctionne avec n’importe quelle
base_urlcompatible OpenAI