Aller au contenu principal

Bases de données vectorielles (Pinecone, Qdrant, Weaviate)

Objectifs

  • Comprendre pourquoi les bases vectorielles sont nécessaires
  • Comparer Pinecone, Qdrant, Weaviate, Chroma et pgvector
  • Implémenter une recherche avec chacune d’entre elles

Pourquoi une base vectorielle ?

L’index NumPy de la leçon précédente fonctionne pour quelques milliers de documents. Au-delà, vous avez besoin de :

  • Recherche ANN (Approximate Nearest Neighbors) pour des réponses en millisecondes sur des millions de vecteurs
  • Filtrage par métadonnées combiné à la recherche vectorielle
  • Persistance et mise à jour en temps réel
  • Scaling horizontal pour la production

Pinecone

Service managé, aucune infrastructure à gérer :

from pinecone import Pinecone
from openai import OpenAI

pc = Pinecone(api_key="votre-cle-pinecone")
openai_client = OpenAI()

# Créer un index
pc.create_index(
    name="mon-corpus",
    dimension=3072,
    metric="cosine",
    spec={"serverless": {"cloud": "aws", "region": "eu-west-1"}}
)

index = pc.Index("mon-corpus")

# Indexer des documents
documents = [
    {"id": "doc1", "texte": "Guide d'installation Python",
     "categorie": "tutoriel"},
    {"id": "doc2", "texte": "Déployer une application Flask",
     "categorie": "tutoriel"},
    {"id": "doc3", "texte": "Rapport trimestriel Q1 2026",
     "categorie": "rapport"},
]

# Générer les embeddings
textes = [d["texte"] for d in documents]
response = openai_client.embeddings.create(
    input=textes,
    model="text-embedding-3-large"
)

# Upserter dans Pinecone
vecteurs = [
    {
        "id": doc["id"],
        "values": emb.embedding,
        "metadata": {"texte": doc["texte"], "categorie": doc["categorie"]}
    }
    for doc, emb in zip(documents, response.data)
]
index.upsert(vectors=vecteurs)

# Rechercher
query_emb = openai_client.embeddings.create(
    input="comment installer Python",
    model="text-embedding-3-large"
).data[0].embedding

resultats = index.query(
    vector=query_emb,
    top_k=3,
    include_metadata=True,
    filter={"categorie": {"$eq": "tutoriel"}}
)

for match in resultats.matches:
    print(f"[{match.score:.3f}] {match.metadata['texte']}")

Qdrant

Open source, auto-hébergeable, excellentes performances :

from qdrant_client import QdrantClient
from qdrant_client.models import (
    Distance, VectorParams, PointStruct, Filter,
    FieldCondition, MatchValue
)
from openai import OpenAI

qclient = QdrantClient(url="http://localhost:6333")
openai_client = OpenAI()

# Créer une collection
qclient.create_collection(
    collection_name="mon-corpus",
    vectors_config=VectorParams(
        size=3072,
        distance=Distance.COSINE
    )
)

# Indexer des documents
points = []
for i, doc in enumerate(documents):
    emb = openai_client.embeddings.create(
        input=doc["texte"],
        model="text-embedding-3-large"
    ).data[0].embedding

    points.append(PointStruct(
        id=i,
        vector=emb,
        payload={"texte": doc["texte"], "categorie": doc["categorie"]}
    ))

qclient.upsert(collection_name="mon-corpus", points=points)

# Rechercher avec filtre
query_emb = openai_client.embeddings.create(
    input="déployer une application web",
    model="text-embedding-3-large"
).data[0].embedding

resultats = qclient.search(
    collection_name="mon-corpus",
    query_vector=query_emb,
    limit=3,
    query_filter=Filter(
        must=[FieldCondition(
            key="categorie",
            match=MatchValue(value="tutoriel")
        )]
    )
)

for r in resultats:
    print(f"[{r.score:.3f}] {r.payload['texte']}")

Weaviate

Base vectorielle avec recherche hybride native :

import weaviate
from openai import OpenAI

wclient = weaviate.connect_to_local()
openai_client = OpenAI()

# Créer une collection
from weaviate.classes.config import Property, DataType

collection = wclient.collections.create(
    name="Document",
    properties=[
        Property(name="texte", data_type=DataType.TEXT),
        Property(name="categorie", data_type=DataType.TEXT),
    ]
)

# Indexer
for doc in documents:
    emb = openai_client.embeddings.create(
        input=doc["texte"],
        model="text-embedding-3-large"
    ).data[0].embedding

    collection.data.insert(
        properties={"texte": doc["texte"], "categorie": doc["categorie"]},
        vector=emb
    )

# Rechercher
query_emb = openai_client.embeddings.create(
    input="installer Python",
    model="text-embedding-3-large"
).data[0].embedding

resultats = collection.query.near_vector(
    near_vector=query_emb,
    limit=3
)

Chroma et pgvector

Chroma — idéal pour le prototypage

import chromadb
from openai import OpenAI

chroma = chromadb.PersistentClient(path="./chroma_db")
openai_client = OpenAI()

collection = chroma.get_or_create_collection("mon-corpus")

# Indexer
for doc in documents:
    emb = openai_client.embeddings.create(
        input=doc["texte"],
        model="text-embedding-3-large"
    ).data[0].embedding

    collection.add(
        ids=[doc["id"]],
        embeddings=[emb],
        documents=[doc["texte"]],
        metadatas=[{"categorie": doc["categorie"]}]
    )

# Rechercher
query_emb = openai_client.embeddings.create(
    input="comment installer Python",
    model="text-embedding-3-large"
).data[0].embedding

resultats = collection.query(query_embeddings=[query_emb], n_results=3)

pgvector — si vous avez déjà PostgreSQL

-- Extension pgvector
CREATE EXTENSION vector;

CREATE TABLE documents (
    id SERIAL PRIMARY KEY,
    texte TEXT,
    categorie TEXT,
    embedding vector(3072)
);

-- Index HNSW pour la performance
CREATE INDEX ON documents
USING hnsw (embedding vector_cosine_ops);

-- Recherche des 5 plus proches
SELECT id, texte, 1 - (embedding <=> $1::vector) AS score
FROM documents
ORDER BY embedding <=> $1::vector
LIMIT 5;

Comparatif

CritèrePineconeQdrantWeaviateChromapgvector
TypeManagéOpen sourceOpen sourceOpen sourceExtension
HébergementCloudSelf-hosted/CloudSelf-hosted/CloudLocal/EmbedPostgreSQL
Recherche hybride✅ NativeVia SQL
Production⚠️ Prototypage
Facilité✅✅✅✅

Résumé

  • Chroma pour le prototypage rapide
  • pgvector si vous avez déjà PostgreSQL
  • Pinecone pour du managé sans infrastructure
  • Qdrant pour l’auto-hébergement performant
  • Weaviate pour la recherche hybride native