Stocker et interroger des incorporations avec pgvector

Effectué

Les incorporations vectorielles transforment du texte, des images et d’autres contenus en représentations numériques qui capturent la signification sémantique. Azure Database pour PostgreSQL prend en charge le stockage et l’interrogation de ces incorporations via l’extension pgvector, ce qui vous permet d’ajouter des fonctionnalités de recherche vectorielle à votre base de données PostgreSQL existante sans gérer un magasin vectoriel distinct.

Cette unité couvre l’activation de l’extension pgvector, la conception de schémas pour le stockage vectoriel, l’insertion et la mise à jour d’incorporations et l’exécution de requêtes de similarité de base. Ces opérations fondamentales constituent la base de la création de fonctionnalités de recherche sémantique et de récupération dans vos applications IA.

Activer l’extension pgvector

L’extension pgvector ajoute des types de données vectorielles et des opérateurs de recherche de similarité à PostgreSQL. Avant de pouvoir stocker des incorporations, vous devez activer l’extension dans votre base de données. Azure Database pour PostgreSQL inclut pgvector comme l’une des extensions prises en charge, le rendant disponible sans installation supplémentaire.

Pour activer pgvector, connectez-vous à votre base de données et exécutez la CREATE EXTENSION commande. Vous avez besoin des autorisations appropriées pour créer des extensions, généralement accordées à l’administrateur du serveur ou aux utilisateurs disposant du azure_pg_admin rôle.

CREATE EXTENSION IF NOT EXISTS vector;

Après avoir activé l’extension, vous pouvez vérifier qu’elle est disponible en interrogeant les extensions installées :

SELECT * FROM pg_extension WHERE extname = 'vector';

L’extension pgvector introduit le vector type de données, qui stocke les incorporations sous forme de tableaux de nombres à virgule flottante à simple précision. Chaque vecteur a un nombre fixe de dimensions que vous spécifiez lors de la création d’une colonne. L’extension fournit également des opérateurs pour calculer les distances entre les vecteurs et les types d’index pour la recherche de similarité rapide.

Concevoir des schémas pour le stockage vectoriel

Une conception de schéma efficace pour le stockage vectoriel combine les incorporations avec les métadonnées dont votre application a besoin pour filtrer et afficher. Lorsque vous définissez une colonne vectorielle, vous spécifiez le nombre de dimensions à l’aide de la vector(n) syntaxe, où n doit correspondre la dimension de sortie de votre modèle d’incorporation.

Les dimensions d’incorporation courantes varient selon le modèle. Les modèles transformateurs de phrases produisent généralement des vecteurs 384 dimensionnels. Le modèle d'intégration de texte text-embedding-ada-002 d’OpenAI génère 1 536 dimensions, tandis que le modèle text-embedding-3-large peut produire jusqu’à 3 072 dimensions. L’utilisation du nombre de dimensions incorrect provoque des erreurs d’insertion. Vérifiez donc la dimension de sortie de votre modèle avant de créer des tables.

L’exemple suivant crée une table qui stocke des documents juridiques avec des incorporations avec des métadonnées utiles pour le filtrage et l’affichage :

CREATE TABLE documents (
    id SERIAL PRIMARY KEY,
    title TEXT NOT NULL,
    content TEXT,
    category TEXT,
    practice_area TEXT,
    created_at TIMESTAMPTZ DEFAULT NOW(),
    updated_at TIMESTAMPTZ DEFAULT NOW(),
    embedding vector(1536)
);

Ce schéma stocke l’incorporation du document dans la même ligne que ses métadonnées. Cette approche simplifie les requêtes, car vous n’avez pas besoin de jointures pour récupérer les documents similaires et leurs détails. Pour les champs de contenu volumineux, envisagez de stocker le texte intégral dans une table distincte et de conserver uniquement des résumés ou des titres dans la table principale pour réduire les données transférées pendant les recherches de similarité.

Lors de la conception pour plusieurs modèles d’incorporation ou l’incorporation de différents types de contenu (tels que les titres et le contenu complet), vous pouvez ajouter plusieurs colonnes vectorielles :

CREATE TABLE documents (
    id SERIAL PRIMARY KEY,
    title TEXT NOT NULL,
    content TEXT,
    title_embedding vector(384),
    content_embedding vector(1536)
);

Insérer et mettre à jour des incorporations

Après avoir créé votre schéma, vous insérez des incorporations à l’aide d’instructions SQL INSERT standard. Les vecteurs sont représentés en tant que littéraux de chaîne au format de tableau et convertis en type vector . Votre code d’application génère l’incorporation à l’aide d’une API d’incorporation (par exemple, Azure OpenAI) et la transmet à la base de données en tant que paramètre.

INSERT INTO documents (title, content, category, practice_area, embedding)
VALUES (
    'Corporate Merger Agreement Template',
    'This agreement outlines the terms and conditions for the merger of...',
    'contracts',
    'corporate',
    '[0.0123, -0.0456, 0.0789, -0.0321, ...]'::vector
);

Pour les insertions par lots lors du chargement de jeux de données volumineux, utilisez des instructions multi-lignes INSERT ou la commande COPY pour améliorer les performances.

INSERT INTO documents (title, content, category, embedding)
VALUES
    ('Document 1', 'Content...', 'legal', '[...]'::vector),
    ('Document 2', 'Content...', 'legal', '[...]'::vector),
    ('Document 3', 'Content...', 'legal', '[...]'::vector);

Lorsque le contenu du document change, mettez à jour l’incorporation pour refléter la nouvelle signification sémantique :

UPDATE documents
SET content = 'Updated document content...',
    embedding = '[0.0234, -0.0567, ...]'::vector,
    updated_at = NOW()
WHERE id = 42;

Pour les applications avec des mises à jour fréquentes, envisagez de regrouper la régénération des incrustations pendant les heures creuses plutôt que de synchroniser la mise à jour des incrustations avec les modifications de contenu. Cette approche réduit la latence des mises à jour de contenu et consolide les appels à l’API d’incorporation.

Vecteurs de requête avec opérateurs de distance

L’extension pgvector fournit trois opérateurs de distance pour mesurer la similarité entre les vecteurs. Chaque opérateur calcule un type de distance différent, et le choix de celui qui convient dépend de votre modèle d’incorporation et de votre cas d’usage.

La distance L2 (distance Euclidean) mesure la distance droite entre deux vecteurs dans l’espace incorporé. Utilisez l'opérateur <-> pour la distance L2. Les valeurs plus petites indiquent des vecteurs plus similaires. Cette métrique fonctionne bien lorsque l’ampleur des vecteurs porte une signification.

SELECT id, title, embedding <-> '[0.0123, -0.0456, ...]'::vector AS distance
FROM documents
ORDER BY distance
LIMIT 10;

La distance cosinus mesure l’angle entre deux vecteurs, ignorant leurs grandeurs. Utilisez l’opérateur <=> pour la distance de cosinus. Les valeurs vont de 0 (direction identique) à 2 (directions opposées). La distance de cosinus est le choix le plus courant pour les incorporations de texte, car elle se concentre sur la direction de la signification plutôt que sur la longueur du vecteur.

SELECT id, title, embedding <=> '[0.0123, -0.0456, ...]'::vector AS distance
FROM documents
ORDER BY distance
LIMIT 10;

Le produit interne négatif calcule le produit point de deux vecteurs et le annule. Utilisez l’opérateur <#> . Cette métrique est utile pour la recherche maximale de produits internes, où les produits point plus volumineux indiquent des vecteurs plus similaires. La négation la convertit à une distance où les valeurs plus petites sont meilleures, correspondant au comportement des autres opérateurs.

SELECT id, title, embedding <#> '[0.0123, -0.0456, ...]'::vector AS distance
FROM documents
ORDER BY distance
LIMIT 10;

La plupart des modèles d’incorporation, y compris les incorporations d’OpenAI, sont optimisés pour la similarité cosinus. Consultez la documentation de votre modèle d’incorporation pour confirmer la métrique de distance recommandée.

Types de données vectorielles et précision

L’extension pgvector offre trois types de données pour stocker des vecteurs, chacun avec des caractéristiques de stockage et de performances différentes.

Le type de vecteur stocke les éléments sous forme de nombres à virgule flottante à précision unique (32 bits). Il s’agit du type standard pour la plupart des cas d’usage et fournit un bon équilibre entre précision et efficacité du stockage. Un vecteur de 1536 dimensions utilise environ 6 Ko de stockage.

Le type halfvec stocke les éléments sous forme de nombres à virgule flottante demi-précision (16 bits). Ce type réduit de moitié le stockage par rapport à vector tout en conservant une précision suffisante pour la plupart des tâches de recherche de similarité. Utilisez halfvec quand le stockage est un problème et que vous avez vérifié que la précision réduite n’a pas d’impact significatif sur votre qualité de recherche.

CREATE TABLE documents_compact (
    id SERIAL PRIMARY KEY,
    title TEXT NOT NULL,
    embedding halfvec(1536)
);

Le type éparsevec stocke les vecteurs épars où la plupart des éléments sont zéro. Au lieu de stocker toutes les dimensions, il stocke uniquement les valeurs non nulles et leurs positions. Ce type est utile pour les modèles qui produisent des incorporations éparses, telles que certaines représentations de document. Spécifiez le nombre maximal de dimensions lors de la création de la colonne.

CREATE TABLE sparse_documents (
    id SERIAL PRIMARY KEY,
    title TEXT NOT NULL,
    embedding sparsevec(10000)
);

Note

Les index HNSW sur sparsevec colonnes prennent en charge jusqu’à 1 000 éléments non nuls. Si vos vecteurs éparses dépassent cette limite, envisagez de réduire la dimensionnalité ou d’autres stratégies d’indexation.

Pour la plupart des applications IA utilisant des incorporations denses à partir de modèles comme OpenAI ou transformateurs de phrases, utilisez le type standard vector . N’envisagez halfvec que lorsque l’analyse comparative confirme que la demi-précision fournit une qualité de recherche acceptable pour votre cas d’usage spécifique.