Tutoriel

Statut éditorial : En attente de relecture

Implémenter une recherche sémantique avec Qdrant en Python

Indexer des textes avec leurs embeddings dans Qdrant, interroger les voisins proches et filtrer les résultats par métadonnées.

Classification du contenu

Types

  • RAG et recherche vectorielle

Technologies

Niveau
Intermédiaire
Publié le
24 août 2026
Dernière relecture
Relecture en attente
Prochaine vérification
24 octobre 2026

Une recherche sémantique compare le sens d’une requête à celui des documents. Le modèle d’embeddings transforme chaque texte en vecteur ; Qdrant stocke ces vecteurs et retrouve les plus proches.

Démarrer Qdrant

~~~bash docker run --name qdrant -p 6333:6333 -p 6334:6334 \ -v "$(pwd)/qdrant_storage:/qdrant/storage:z" qdrant/qdrant ~~~

Le tableau de bord local est disponible sur "http://localhost:6333/dashboard". Cette configuration n’active pas l’authentification : ne l’exposez pas sur Internet.

Installez le client avec FastEmbed :

~~~bash python -m venv .venv source .venv/bin/activate pip install -U 'qdrant-client[fastembed]' ~~~

Indexer les documents

~~~python from qdrant_client import QdrantClient, models

COLLECTION = "articles" MODEL = "sentence-transformers/paraphrase-multilingual-MiniLM-L12-v2"

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

documents = [ "FastAPI permet de créer des API Python asynchrones.", "Qdrant stocke et interroge des vecteurs.", "PostgreSQL est une base de données relationnelle.", ]

client.add( collection_name=COLLECTION, documents=documents, metadata=[ {"topic": "python", "lang": "fr"}, {"topic": "vectordb", "lang": "fr"}, {"topic": "database", "lang": "fr"}, ], ids=[1, 2, 3], ) ~~~

Le mode FastEmbed simplifie le tutoriel. Pour un pipeline contrôlé, calculez vous-même les embeddings, créez la collection avec la dimension exacte du modèle, puis envoyez des "PointStruct". Le modèle utilisé à la requête doit être identique à celui de l’indexation.

Interroger l’index

~~~python results = client.query( collection_name=COLLECTION, query_text="Comment retrouver des textes proches par leur sens ?", limit=3, )

for result in results: print(round(result.score, 3), result.document, result.metadata) ~~~

Selon la version du client, l’API bas niveau moderne est "query_points". Elle accepte un vecteur de requête et retourne les points triés par similarité.

Filtrer par métadonnées

~~~python from fastembed import TextEmbedding from qdrant_client.models import FieldCondition, Filter, MatchValue

embedding_model = TextEmbedding(MODEL) query_vector = next( embedding_model.query_embed("base vectorielle pour recherche sémantique") ).tolist()

points = client.query_points( collection_name=COLLECTION, query=query_vector, query_filter=Filter( must=[FieldCondition(key="lang", match=MatchValue(value="fr"))] ), with_payload=True, limit=5, ).points ~~~

Le vecteur de requête utilise le même encodeur que l’index. Créez des index de payload pour les champs souvent filtrés ; sinon le filtrage peut devenir coûteux à grande échelle.

Évaluer la recherche

Préparez des requêtes avec leurs documents attendus et mesurez recall@k ou MRR. Analysez séparément les requêtes sans réponse, les textes trop courts et les doublons. Le score Qdrant n’est pas une probabilité universelle : ne fixez pas un seuil sans données d’évaluation.

Production

Versionnez le modèle et la collection, utilisez des identifiants stables, conservez le texte source dans le payload ou un stockage associé, et réindexez vers une nouvelle collection lors d’un changement d’embedding. Activez TLS et clé API, sauvegardez les données et surveillez mémoire, latence, taille des segments et profondeur de réplication.

FAQ

Faut-il normaliser les vecteurs ?

Cela dépend du modèle et de la distance. Suivez la recommandation du modèle d’embeddings et conservez le même traitement à l’indexation et à la requête.

Pourquoi les résultats sont-ils hors sujet ?

Vérifiez d’abord le modèle, la langue, le découpage et l’absence de mélange entre deux versions d’embeddings. Un reranker peut ensuite améliorer l’ordre des premiers candidats.

Sources utilisées