You are currently viewing Qdrant : base vectorielle open source pour le RAG et la recherche sémantique

Qdrant : base vectorielle open source pour le RAG et la recherche sémantique

Qdrant : base vectorielle open source pour le RAG et la recherche sémantique

Les modèles de langage ne retiennent pas vos données. Pour que votre LLM réponde avec précision sur un corpus interne : documents, notices, bases de connaissances, il faut lui fournir du contexte au moment de la requête. C’est le principe du RAG (Retrieval-Augmented Generation). Et au cœur de tout pipeline RAG, il y a une base vectorielle. Qdrant est aujourd’hui l’une des solutions open source les plus matures : performante, auto-hébergeable, et dotée d’une API REST claire.

Pourquoi une base vectorielle

Un texte transformé en vecteur (embedding) capture sa sémantique sous forme d’un tableau de nombres. Deux phrases proches sémantiquement auront des vecteurs proches dans cet espace, même si elles n’ont aucun mot en commun. Une base vectorielle stocke ces vecteurs et permet de retrouver, pour une requête donnée, les k vecteurs les plus proches par similarité cosinus ou distance euclidienne. C’est la brique de recherche au fondement des pipelines RAG modernes.

Les bases relationnelles classiques ne sont pas conçues pour cette opération : une recherche par similarité sur des millions de vecteurs de haute dimension requiert des index spécialisés (HNSW, IVF). Qdrant implémente HNSW en natif, avec des performances adaptées à la production.

Présentation de Qdrant

Qdrant est une base vectorielle écrite en Rust, publiée sous licence Apache 2.0. Elle expose une API REST et une API gRPC, un client Python officiel, et une interface web légère pour inspecter collections et points. Elle prend en charge les vecteurs denses (embeddings standards), les vecteurs épars (BM25-style) et le mode sparse + dense combiné, appelé hybrid search.

Qdrant stocke, avec chaque vecteur, un payload JSON arbitraire — titre, URL, horodatage, catégorie — filtrable lors des requêtes. Cela permet de combiner filtre métadonnées + similarité vectorielle dans une seule requête, sans post-traitement applicatif.

Déploiement Docker

L’installation la plus directe repose sur Docker :

docker run -d \
  --name qdrant \
  -p 6333:6333 \
  -p 6334:6334 \
  -v qdrant_storage:/qdrant/storage \
  qdrant/qdrant

Le port 6333 expose l’API REST, le port 6334 l’API gRPC. L’interface web est accessible à http://localhost:6333/dashboard. Pour une stack Docker Compose, ajoutez simplement le service qdrant avec un volume nommé et un restart: unless-stopped.

Variables de configuration utiles

Qdrant se configure via un fichier config/production.yaml ou par variables d’environnement. Les paramètres les plus utiles en production :

  • QDRANT__SERVICE__API_KEY — clé d’API pour protéger l’accès
  • QDRANT__STORAGE__WAL__WAL_CAPACITY_MB — capacité du write-ahead log
  • QDRANT__STORAGE__ON_DISK_PAYLOAD — stockage du payload sur disque (mémoire réduite)
  • QDRANT__CLUSTER__ENABLED — mode cluster distribué (disponible en version enterprise)

Créer une collection et indexer des documents

Une collection regroupe des vecteurs de même dimension. Voici un exemple complet en Python, en combinant Qdrant avec un modèle d’embedding local via Ollama (voir l’article sur Ollama) :

from qdrant_client import QdrantClient
from qdrant_client.models import Distance, VectorParams, PointStruct
import ollama

client = QdrantClient(url="http://localhost:6333")

# Création de la collection (1 536 dimensions pour nomic-embed-text)
client.recreate_collection(
    collection_name="documents",
    vectors_config=VectorParams(size=768, distance=Distance.COSINE),
)

# Indexation de quelques textes
textes = [
    {"id": 1, "texte": "CKAN est un portail de données open source.", "titre": "CKAN"},
    {"id": 2, "texte": "Keycloak gère l'authentification SSO.", "titre": "Keycloak"},
    {"id": 3, "texte": "Qdrant stocke des vecteurs pour la recherche sémantique.", "titre": "Qdrant"},
]

points = []
for doc in textes:
    embedding = ollama.embeddings(model="nomic-embed-text", prompt=doc["texte"])["embedding"]
    points.append(PointStruct(
        id=doc["id"],
        vector=embedding,
        payload={"titre": doc["titre"], "texte": doc["texte"]},
    ))

client.upsert(collection_name="documents", points=points)
print(f"{len(points)} documents indexés.")

Requête de recherche sémantique

Pour retrouver les documents les plus pertinents face à une question :

question = "Comment gérer les identités dans ma stack ?"
query_vector = ollama.embeddings(model="nomic-embed-text", prompt=question)["embedding"]

résultats = client.search(
    collection_name="documents",
    query_vector=query_vector,
    limit=3,
    with_payload=True,
)

for r in résultats:
    print(f"Score {r.score:.3f} — {r.payload['titre']} : {r.payload['texte']}")

Qdrant retourne les documents triés par score de similarité. Ces passages peuvent être directement injectés dans le prompt envoyé à votre LLM pour former un pipeline RAG complet.

Hybrid search : combiner sémantique et lexical

La recherche purement vectorielle peut manquer des correspondances exactes sur des termes techniques (noms propres, acronymes, identifiants). Le mode hybrid search de Qdrant combine un vecteur dense (embedding) et un vecteur épars (représentation BM25-like via sparse vectors) dans la même requête, avec pondération configurable. Pour les corpus techniques : documentation, CKAN, tickets, ce mode améliore significativement la pertinence.

Intégration dans un pipeline RAG complet

L’architecture typique avec les outils couverts sur ce site :

  • Sources : fichiers CSV/JSON depuis CKAN, documents Nextcloud, exports PostgreSQL
  • Embedding : Ollama (nomic-embed-text, mxbai-embed-large) ou sentence-transformers en local
  • Stockage : Qdrant (base vectorielle) — les chunks de texte avec leurs métadonnées
  • Retrieval : requête sémantique + filtre payload (date, source, catégorie)
  • Génération : LLM local via Ollama (Llama 3, Mistral, Gemma) avec le contexte récupéré
  • Orchestration : LangChain, LlamaIndex, ou n8n pour assembler le pipeline

Persistance, snapshots et sauvegarde

Qdrant stocke ses données dans le volume monté (/qdrant/storage). Pour les sauvegardes, l’API fournit un endpoint de snapshot :

# Créer un snapshot de la collection "documents"
curl -X POST http://localhost:6333/collections/documents/snapshots

# Lister les snapshots disponibles
curl http://localhost:6333/collections/documents/snapshots

Les fichiers de snapshot peuvent être envoyés sur MinIO, S3 ou sauvegardés avec BorgBackup (voir l’article dédié). La restauration se fait via le même endpoint avec une requête POST sur /collections/{name}/snapshots/recover.

Dimensionnement et performance

Quelques règles pratiques pour calibrer votre déploiement Qdrant :

  • 1 million de vecteurs de 768 dimensions occupent environ 3 Go en RAM avec l’index HNSW en mémoire
  • Pour réduire l’empreinte mémoire, activez on_disk_payload: true et le quantization (scalar ou product)
  • Le paramètre m de l’index HNSW contrôle le rapport qualité/mémoire (défaut : 16)
  • Pour les cas d’usage RAG courants (< 500 000 chunks), une instance single-node suffit largement

Alternatives open source

Qdrant n’est pas la seule base vectorielle open source. Chroma est plus simple à démarrer (pensé pour le prototypage Python). Weaviate inclut des modules d’embedding intégrés mais est plus lourd. Milvus est orienté scalabilité extrême avec une architecture distribuée. pgvector (extension PostgreSQL) convient si vous souhaitez éviter un service supplémentaire et que votre volume de vecteurs reste modéré. Pour une stack auto-hébergée en production, Qdrant offre le meilleur équilibre entre performance, légèreté et maturité opérationnelle.

Conclusion

Qdrant complète naturellement une stack AI open source : aux côtés d’Ollama pour l’inférence et les embeddings, de n8n pour l’orchestration, et de PostgreSQL ou CKAN comme sources de données, il forme le pivot de tout pipeline RAG auto-hébergé. Son API claire, ses snapshots intégrés et sa faible empreinte opérationnelle en font un choix solide dès les premiers prototypes jusqu’à la mise en production.