Implémenter des modèles de requête de recherche vectorielle

Effectué

Avec les vecteurs stockés et une stratégie de recherche choisie, vous êtes prêt à écrire des requêtes. Cette unité couvre les fonctions T-SQL qui alimentent la recherche vectorielle et vous montrent comment les combiner efficacement.

Les requêtes de recherche vectorielle suivent un modèle courant : générer ou récupérer un vecteur de requête, calculer les distances des vecteurs stockés et retourner les correspondances les plus proches. SQL Server fournit quatre fonctions qui fonctionnent ensemble pour prendre en charge ce modèle : VECTOR_DISTANCE, , VECTOR_SEARCHVECTOR_NORMALIZE, et VECTORPROPERTY.

Calculer les distances avec VECTOR_DISTANCE

La VECTOR_DISTANCE fonction calcule la distance entre deux vecteurs à l’aide de la métrique que vous spécifiez. Cette fonction effectue exactement la recherche voisine la plus proche, en calculant la distance à chaque ligne éligible. En pratique, il compare votre intégration de recherche à l’ensemble des intégrations stockées afin d’identifier les plus proches, comme si l’on parcourait tout un catalogue pour repérer les correspondances les plus pertinentes.

VECTOR_DISTANCE(metric, vector1, vector2)

La métrique doit être 'cosine', 'euclidean'ou 'dot'. Les deux vecteurs doivent avoir le même nombre de dimensions.

Voici un modèle classique pour rechercher des produits similaires basés sur une description incorporée :

-- Generate an embedding for the user's search phrase
DECLARE @searchVector VECTOR(1536);
SELECT @searchVector = AI_GENERATE_EMBEDDINGS('lightweight hiking boots' USE MODEL MyEmbeddingModel);

SELECT TOP 10 
    ProductID,
    Name,
    VECTOR_DISTANCE('cosine', @searchVector, DescriptionVector) AS Distance
FROM dbo.Products
ORDER BY Distance;

Cette requête fonctionne en deux étapes. Tout d’abord, il convertit l’expression de recherche « chaussures de randonnée légères » en un embedding à l’aide du même modèle que celui qui a créé les valeurs stockées DescriptionVector. Ensuite, il calcule la distance cosinus entre @searchVector et chaque ligne DescriptionVector. La ORDER BY Distance clause trie les résultats de la plus petite distance (la plus similaire) au plus grand et TOP 10 retourne uniquement les 10 premières lignes. Étant donné que les distances plus petites signifient des vecteurs plus similaires, cette combinaison vous donne les 10 produits les plus sémantiquement liés aux « bottes de randonnée légères ».

Vous pouvez également utiliser VECTOR_DISTANCE dans une clause WHERE pour rechercher tous les vecteurs dans un seuil de distance spécifique :

SELECT ProductID, Name
FROM dbo.Products
WHERE VECTOR_DISTANCE('cosine', @searchVector, DescriptionVector) < 0.3
ORDER BY VECTOR_DISTANCE('cosine', @searchVector, DescriptionVector);

Cette approche recherche tous les produits au sein d’un seuil de similarité plutôt que de retourner un nombre fixe. La valeur 0.3 est un exemple. La distance de cosinus varie de 0 (vecteurs identiques) à 2 (complètement opposé), mais ce qui compte comme « assez similaire » dépend entièrement de vos données et du modèle d’incorporation. Pour trouver le seuil approprié, exécutez des requêtes de test, examinez les valeurs de distance dans vos résultats et identifiez l’endroit où les résultats pertinents s’arrêtent et le bruit commence. Utilisez ce modèle lorsque vous souhaitez que tout réponde à une barre de qualité plutôt qu’un nombre fixe de résultats.

Utiliser VECTOR_SEARCH pour une récupération approximative

Lorsque votre table augmente au-delà de dizaines de milliers de lignes, le calcul des distances à chaque ligne devient lente. La VECTOR_SEARCH fonction utilise un index vectoriel pour trouver rapidement les voisins les plus proches.

VECTOR_SEARCH(
    TABLE = object AS alias,
    COLUMN = vector_column,
    SIMILAR_TO = query_vector,
    METRIC = 'cosine' | 'euclidean' | 'dot',
    TOP_N = k
)

Cette fonction retourne un jeu de résultats contenant toutes les colonnes de la table source et une distance colonne. Voici comment l’utiliser :

DECLARE @searchVector VECTOR(1536);
SELECT @searchVector = AI_GENERATE_EMBEDDINGS('lightweight hiking boots' USE MODEL MyEmbeddingModel);

SELECT t.ProductID, t.Name, s.distance
FROM VECTOR_SEARCH(
    TABLE = dbo.Products AS t,
    COLUMN = DescriptionVector,
    SIMILAR_TO = @searchVector,
    METRIC = 'cosine',
    TOP_N = 10
) AS s
ORDER BY s.distance;

La fonction retourne environ 10 voisins les plus proches. Si un index vectoriel correspondant existe avec DescriptionVector la même métrique, VECTOR_SEARCH l’utilise pour une récupération rapide. Sans index, il revient à la recherche exacte et déclenche un avertissement.

Gérer soigneusement le post-filtrage

VECTOR_SEARCH applique toutes les conditions de clause WHERE après avoir trouvé les voisins les plus proches, pas avant. Prenons par exemple la requête suivante :

SELECT t.ProductID, t.Name, s.distance
FROM VECTOR_SEARCH(
    TABLE = dbo.Products AS t,
    COLUMN = DescriptionVector,
    SIMILAR_TO = @searchVector,
    METRIC = 'cosine',
    TOP_N = 10
) AS s
WHERE t.CategoryID = 5
ORDER BY s.distance;

Cette requête recherche d’abord les 10 vecteurs les plus proches dans toutes les catégories, puis filtre uniquement la catégorie 5. Si aucun des 10 produits les plus proches n’est dans la catégorie 5, vous n’obtenez aucun résultat. Pour contourner ce problème, demandez plus de candidats que vous n’en avez besoin :

SELECT TOP 10 t.ProductID, t.Name, s.distance
FROM VECTOR_SEARCH(
    TABLE = dbo.Products AS t,
    COLUMN = DescriptionVector,
    SIMILAR_TO = @searchVector,
    METRIC = 'cosine',
    TOP_N = 50
) AS s
WHERE t.CategoryID = 5
ORDER BY s.distance;

En demandant 50 candidats de VECTOR_SEARCH, puis en prenant les 10 premiers après le filtrage, vous avez plus de chances d'obtenir suffisamment de résultats dans la catégorie cible.

Normaliser les vecteurs pour les comparaisons cohérentes

Différents modèles d’incorporation produisent des vecteurs avec des longueurs différentes (magnitudes). Lorsque vous comparez des vecteurs provenant de plusieurs sources ou lorsque votre modèle ne normalise pas les sorties, vous pouvez utiliser VECTOR_NORMALIZE pour mettre à l’échelle des vecteurs en longueur unitaire.

VECTOR_NORMALIZE(vector, norm_type)

Le norm_type peut être :

  • 'norm2': norme euclide (la plus courante)
  • 'norm1': Somme des valeurs absolues
  • 'norminf': Valeur absolue maximale
DECLARE @v VECTOR(3) = '[3, 4, 0]';
SELECT VECTOR_NORMALIZE(@v, 'norm2') AS NormalizedVector;
-- Returns: [0.6, 0.8, 0.0]

La normalisation garantit que la distance cosinus et le produit point se comportent de manière cohérente. La plupart des modèles d’incorporation modernes (comme ceux d’OpenAI) produisent des vecteurs normalisés. Vous n’avez donc souvent pas besoin de cette étape. Toutefois, si vous utilisez des incorporations à partir de modèles qui ne se normalisent pas, l’application VECTOR_NORMALIZE avant de stocker ou de comparer garantit des scores de similarité cohérents.

Vous pouvez calculer l’ampleur d’un vecteur à l’aide de la fonction associée VECTOR_NORM :

DECLARE @v VECTOR(3) = '[3, 4, 0]';
SELECT VECTOR_NORM(@v, 'norm2') AS Magnitude;
-- Returns: 5.0

Inspecter des vecteurs avec VECTORPROPERTY

La VECTORPROPERTY fonction retourne des métadonnées sur un vecteur. Ces métadonnées sont utiles pour valider des données ou déboguer des incompatibilités de dimension.

VECTORPROPERTY(vector, property)

Deux propriétés sont prises en charge :

  • 'Dimensions': retourne le nombre de dimensions sous forme d’entier
  • 'BaseType': retourne le nom du type de données (actuellement toujours float)
DECLARE @v VECTOR(1536) = '[0.1, 0.2, ...]';
SELECT VECTORPROPERTY(@v, 'Dimensions') AS Dims;
-- Returns: 1536

Cette fonction permet de résoudre les problèmes de requêtes où des vecteurs peuvent avoir des dimensions incompatibles, un problème courant lors de l’utilisation de différents modèles d’incorporation.

Choisir la fonction appropriée pour votre scénario

Chaque fonction sert un objectif distinct dans la recherche vectorielle :

Scénario Fonction Quand utiliser
Petits jeux de données ou requêtes filtrées VECTOR_DISTANCE Sous 50 000 vecteurs, ou lorsqu’une clause WHERE réduit considérablement les candidats
Jeu de données volumineux avec index vectoriel VECTOR_SEARCH Des centaines de milliers de vecteurs ou plus, quand la vitesse importe
Comparaison de vecteurs à partir de différents modèles VECTOR_NORMALIZE Lorsque les sources incorporées varient ou que le modèle ne produit pas de vecteurs normalisés
Validation des données vectorielles VECTORPROPERTY Vérification des dimensions lors de la résolution des problèmes ou de la validation des données

Points clés à prendre

Les requêtes de recherche vectorielle dans SQL suivent un modèle prévisible : préparez un vecteur de requête, recherchez des voisins à l’aide de VECTOR_DISTANCE (exact) ou VECTOR_SEARCH (approximatif), et ordonnez par distance. VECTOR_NORMALIZE et VECTORPROPERTY soutiennent la qualité et la cohérence des données. N’oubliez pas que les VECTOR_SEARCH filtres s’appliquent après avoir trouvé des voisins les plus proches. Demandez donc plus de candidats que vous n’en avez besoin lors de la combinaison avec des clauses WHERE. Dans l’unité suivante, vous allez apprendre à combiner la recherche vectorielle avec la recherche en texte intégral dans les requêtes hybrides.