Démarrage rapide : Recherche vectorielle avec Python dans Azure Cosmos DB

Utilisez la recherche vectorielle dans Azure Cosmos DB avec la bibliothèque cliente Python. Stockez et interrogez efficacement les données vectorielles dans vos applications.

Ce guide de démarrage rapide utilise un jeu de données d'hôtel d'exemple au format JSON, avec des vecteurs du modèle text-embedding-3-small. Le jeu de données comprend des noms d’hôtel, des emplacements, des descriptions et des incorporations vectorielles.

Recherchez l’exemple de code avec le provisionnement de ressources sur GitHub.

Prerequisites

Créer un fichier de données avec des vecteurs

  1. Créez un nouveau répertoire de données pour le fichier de données des hôtels :

    mkdir data
    
  2. Téléchargez le fichier de données raw avec des vecteurs dans votre répertoire data :

    curl -o data/HotelsData_toCosmosDB_Vector.json https://raw.githubusercontent.com/Azure-Samples/cosmos-db-vector-samples/refs/heads/main/data/HotelsData_toCosmosDB_Vector.json
    

Créer un projet Python

  1. Créez un répertoire frère pour votre projet, au même niveau que le répertoire de données, puis ouvrez-le dans Visual Studio Code :

    mkdir vector-search-quickstart
    code vector-search-quickstart
    
  2. Dans le terminal, créez et activez un environnement virtuel Python :

    python -m venv .venv
    
    source .venv/bin/activate
    
  3. Créez un requirements.txt fichier à la racine de votre projet avec le contenu suivant :

    azure-cosmos>=4.7.0
    azure-identity>=1.18.0
    openai>=1.57.0
    python-dotenv>=1.0.1
    
  4. Installez les packages nécessaires :

    pip install -r requirements.txt
    
    • azure-cosmos - bibliothèque cliente Azure Cosmos DB pour les opérations de base de données
    • azure-identity - bibliothèque d’authentification Azure pour les connexions sans mot de passe (identité managée)
    • openai - Kit de développement logiciel (SDK) OpenAI pour générer des incorporations avec Azure OpenAI
    • python-dotenv - Charge des variables d’environnement à partir d’un .env fichier
  5. Créez un .env fichier à la racine de votre projet pour les variables d’environnement :

    # Identity for local developer authentication with Azure CLI
    AZURE_TOKEN_CREDENTIALS=AzureCliCredential
    
    # Azure OpenAI Embedding Settings
    AZURE_OPENAI_EMBEDDING_MODEL=text-embedding-3-small
    AZURE_OPENAI_EMBEDDING_API_VERSION=2024-08-01-preview
    AZURE_OPENAI_EMBEDDING_ENDPOINT=
    
    # Cosmos DB configuration
    AZURE_COSMOSDB_ENDPOINT=
    
    # Data file
    DATA_FILE_WITH_VECTORS=../data/HotelsData_toCosmosDB_Vector.json
    FIELD_TO_EMBED=Description
    EMBEDDED_FIELD=DescriptionVector
    EMBEDDING_DIMENSIONS=1536
    

    Remplacez les valeurs de substitution dans le fichier .env par vos propres informations.

    • AZURE_OPENAI_EMBEDDING_ENDPOINT : URL de point de terminaison de ressource OpenAI de votre Azure
    • AZURE_COSMOSDB_ENDPOINT : URL de votre point de terminaison de Azure Cosmos DB

Comprendre le schéma du document

Avant de créer l’application, découvrez comment les vecteurs sont stockés dans des documents Azure Cosmos DB. Chaque document d’hôtel contient :

  • Champs standard : HotelId, HotelName, Description, Category, etc.
  • Champ vecteur : DescriptionVector - tableau de 1536 nombres à virgule flottante représentant la signification sémantique de la description de l’hôtel

Voici un exemple simplifié de structure de document d’hôtel :

{
  "HotelId": "1",
  "HotelName": "Stay-Kay City Hotel",
  "Description": "This classic hotel is fully-refurbished...",
  "Rating": 3.6,
  "DescriptionVector": [
    -0.04886505,
    -0.02030743,
    0.01763356,
    ...
    // 1536 dimensions total
  ]
}

Points clés sur le stockage des incorporations :

  • Les tableaux vectoriels sont stockés en tant que tableaux JSON standard dans vos documents
  • La stratégie vectorielle définit le chemin d’accès (/DescriptionVector), le type de données (float32), les dimensions (1536) et la fonction de distance (cosinus)
  • La stratégie d’indexation crée un index vectoriel sur le champ vectoriel pour une recherche de similarité efficace
  • Le champ vecteur doit être exclu de l’indexation standard pour optimiser les performances d’insertion

Ces stratégies sont définies dans les modèles Bicep pour les métriques de distance pour cet exemple de projet. Pour plus d’informations sur les stratégies vectorielles et l’indexation, consultez Recherche de vecteurs dans Azure Cosmos DB.

Créez un src répertoire pour vos fichiers Python. Ajoutez deux fichiers : vector_search.py et utils.py pour votre implémentation de recherche vectorielle :

mkdir src
touch src/__init__.py
touch src/vector_search.py
touch src/utils.py

Collez le code suivant dans le vector_search.py fichier.

"""Azure Cosmos DB NoSQL Vector Search — main entry point.

Loads hotel data, bulk-inserts into the selected container (DiskANN or
QuantizedFlat), generates a query embedding via Azure OpenAI, and
executes a VectorDistance() similarity search.
"""

import os
import sys
from pathlib import Path

from dotenv import load_dotenv

sys.path.insert(0, str(Path(__file__).parent))

from utils import (
    get_clients_passwordless,
    get_clients,
    insert_data,
    print_search_results,
    read_file_return_json,
    validate_field_name,
    get_query_activity_id,
)

# ---------------------------------------------------------------------------
# Load environment
# ---------------------------------------------------------------------------
load_dotenv()

ALGORITHM_CONFIGS: dict[str, dict[str, str]] = {
    "diskann": {
        "container_name": "hotels_diskann",
        "algorithm_name": "DiskANN",
    },
    "quantizedflat": {
        "container_name": "hotels_quantizedflat",
        "algorithm_name": "QuantizedFlat",
    },
}


def _build_config() -> dict[str, str | int]:
    """Build runtime configuration from environment variables."""
    return {
        "query": "quintessential lodging near running trails, eateries, retail",
        "db_name": os.getenv("AZURE_COSMOSDB_DATABASENAME", "Hotels"),
        "algorithm": os.getenv("VECTOR_ALGORITHM", "diskann").strip().lower(),
        "data_file": os.getenv("DATA_FILE_WITH_VECTORS", "../data/HotelsData_toCosmosDB_Vector.json"),
        "embedded_field": os.getenv("EMBEDDED_FIELD", "DescriptionVector"),
        "embedding_dimensions": int(os.getenv("EMBEDDING_DIMENSIONS", "1536")),
        "deployment": os.getenv("AZURE_OPENAI_EMBEDDING_MODEL", "text-embedding-3-small"),
        "distance_function": os.getenv("VECTOR_DISTANCE_FUNCTION", "cosine"),
    }


def main() -> None:
    """Run the vector search demonstration."""
    config = _build_config()

    # Try passwordless auth first, fall back to key-based
    clients = get_clients_passwordless()
    if not clients["ai_client"] or not clients["db_client"]:
        clients = get_clients()

    ai_client = clients["ai_client"]
    db_client = clients["db_client"]

    try:
        algorithm = config["algorithm"]
        if algorithm not in ALGORITHM_CONFIGS:
            valid = ", ".join(ALGORITHM_CONFIGS)
            raise ValueError(
                f"Invalid algorithm '{algorithm}'. Must be one of: {valid}"
            )

        if not ai_client:
            raise RuntimeError(
                "Azure OpenAI client is not configured. "
                "Please check your environment variables."
            )
        if not db_client:
            raise RuntimeError(
                "Cosmos DB client is not configured. "
                "Please check your environment variables."
            )

        algo_cfg = ALGORITHM_CONFIGS[algorithm]
        container_name = algo_cfg["container_name"]

        database = db_client.get_database_client(config["db_name"])
        print(f"Connected to database: {config['db_name']}")

        container = database.get_container_client(container_name)
        print(f"Connected to container: {container_name}")
        print(f"\n📊 Vector Search Algorithm: {algo_cfg['algorithm_name']}")
        print(f"📏 Distance Function: {config['distance_function']}")

        # Verify the container exists
        try:
            container.read()
        except Exception as e:
            status_code = getattr(e, "status_code", None)
            if status_code == 404:
                raise RuntimeError(
                    f"Container or database not found. Ensure database "
                    f"'{config['db_name']}' and container '{container_name}' "
                    f"exist before running this script."
                ) from e
            raise

        data_path = Path(__file__).parent.parent / config["data_file"]
        data = read_file_return_json(str(data_path))
        insert_data(container, data)

        embedding_response = ai_client.embeddings.create(
            model=config["deployment"],
            input=[config["query"]],
        )
        query_embedding = embedding_response.data[0].embedding

        safe_field = validate_field_name(config["embedded_field"])
        query_text = (
            f"SELECT TOP 5 c.HotelName, c.Description, c.Rating, "
            f"VectorDistance(c.{safe_field}, @embedding) AS SimilarityScore "
            f"FROM c "
            f"ORDER BY VectorDistance(c.{safe_field}, @embedding)"
        )

        print("\n--- Executing Vector Search Query ---")
        print(f"Query: {query_text}")
        print(
            f"Parameters: @embedding (vector with {len(query_embedding)} dimensions)"
        )
        print("--------------------------------------\n")

        results = list(
            container.query_items(
                query=query_text,
                parameters=[{"name": "@embedding", "value": query_embedding}],
                enable_cross_partition_query=True,
            )
        )

        # Extract diagnostics
        response_headers = container.client_connection.last_response_headers
        activity_id = get_query_activity_id(response_headers)
        if activity_id:
            print(f"Query activity ID: {activity_id}")

        request_charge_raw = response_headers.get("x-ms-request-charge", "0") if response_headers else "0"
        try:
            request_charge = float(request_charge_raw)
        except (ValueError, TypeError):
            request_charge = 0.0

        print_search_results(results, request_charge)

    except Exception as error:
        print(f"App failed: {error}", file=sys.stderr)
        sys.exit(1)


if __name__ == "__main__":
    main()

Ce code :

  • Configure un algorithme DiskANN ou un algorithme vectoriel quantizedFlat à partir de variables d’environnement.
  • Se connecte à Azure OpenAI et Azure Cosmos DB à l’aide de l’authentification sans mot de passe.
  • Charge les données d’hôtel pré vectorisées à partir d’un fichier JSON.
  • Insère des données dans le conteneur approprié.
  • Génère une incorporation pour une requête en langage naturel (quintessential lodging near running trails, eateries, retail).
  • Exécute une VectorDistance requête SQL pour récupérer les 5 meilleurs hôtels les plus sémantiquement similaires classés par score de similarité.
  • Gère les erreurs pour les clients manquants, la sélection d’algorithmes non valides et les conteneurs/bases de données inexistants.

Comprendre le code : Générer des incorporations avec Azure OpenAI

Le code crée des incorporations pour le texte de requête :

embedding_response = ai_client.embeddings.create(
    model=config["deployment"],  # OpenAI embedding model, e.g. "text-embedding-3-small"
    input=[config["query"]],     # List of description strings to embed
)
query_embedding = embedding_response.data[0].embedding

Cet appel d’API OpenAI pour client.embeddings.create convertit du texte tel que « hébergement idéal près des sentiers de course » en un vecteur de 1536 dimensions qui capture sa signification sémantique. Pour plus d’informations sur la génération d’incorporations, consultez la documentation sur les incorporations Azure OpenAI.

Comprendre le code : Stocker des vecteurs dans Azure Cosmos DB

Tous les documents avec des tableaux vectoriels sont insérés à l’aide de la upsert_item fonction :

for item in data:
    doc = {"id": item["HotelId"], **item}
    response = container.upsert_item(body=doc)

Cela insère des documents d’hôtel, y compris leurs tableaux prédéfinis DescriptionVector dans le conteneur. Chaque document obtient un id champ mappé à partir de HotelId, et la fonction gère les upserts afin que les documents puissent être réinsérés en toute sécurité.

Le code effectue une recherche vectorielle à l’aide de la VectorDistance fonction :

query_text = (
    f"SELECT TOP 5 c.HotelName, c.Description, c.Rating, "
    f"VectorDistance(c.{safe_field}, @embedding) AS SimilarityScore "
    f"FROM c "
    f"ORDER BY VectorDistance(c.{safe_field}, @embedding)"
)

results = list(
    container.query_items(
        query=query_text,
        parameters=[{"name": "@embedding", "value": query_embedding}],
        enable_cross_partition_query=True,
    )
)

Ce code génère une requête SQL paramétrable qui utilise la fonction VectorDistance pour comparer le vecteur d’incorporation de la requête (@embedding) par rapport au champ de vecteur stocké de chaque document (DescriptionVector), en retournant les 5 premiers hôtels avec leur nom et leur score de similarité, classés de la plus similaire au moins similaire. L’incorporation de requête est passée en tant que paramètre pour éviter l’injection et provient d’un appel prioritaire à embeddings.create d'Azure OpenAI.

Ce que cette requête retourne :

  • Top 5 des hôtels les plus similaires basés sur la distance vectorielle
  • Propriétés de l’hôtel : HotelName, Description, Rating
  • SimilarityScore: valeur numérique indiquant la similitude entre chaque hôtel et votre requête
  • Résultats classés de la plupart similaires à moins similaires

Pour plus d’informations sur la fonction, consultez la VectorDistancedocumentation VectorDistance.

Créer des fonctions utilitaires

Collez le code suivant dans utils.py:

"""Shared utilities for Azure Cosmos DB NoSQL vector search.

Provides client initialization (passwordless and key-based), JSON I/O,
bulk insert with RU tracking, field validation, and result formatting.
"""

import json
import os
import re
import time
from typing import Any, Optional


def get_clients() -> dict[str, Any]:
    """Get Azure OpenAI and Cosmos DB clients using key-based authentication.

    Returns dict with 'ai_client' and 'db_client' (either may be None if
    the required environment variables are missing).
    """
    from azure.cosmos import CosmosClient
    from openai import AzureOpenAI

    ai_client = None
    db_client = None

    api_key = os.getenv("AZURE_OPENAI_EMBEDDING_KEY", "")
    api_version = os.getenv("AZURE_OPENAI_EMBEDDING_API_VERSION", "")
    endpoint = os.getenv("AZURE_OPENAI_EMBEDDING_ENDPOINT", "")
    deployment = os.getenv("AZURE_OPENAI_EMBEDDING_MODEL", "")

    if api_key and api_version and endpoint and deployment:
        ai_client = AzureOpenAI(
            api_key=api_key,
            api_version=api_version,
            azure_endpoint=endpoint,
            azure_deployment=deployment,
        )

    cosmos_endpoint = os.getenv("AZURE_COSMOSDB_ENDPOINT", "")
    cosmos_key = os.getenv("AZURE_COSMOSDB_KEY", "")

    if cosmos_endpoint and cosmos_key:
        db_client = CosmosClient(url=cosmos_endpoint, credential=cosmos_key)

    return {"ai_client": ai_client, "db_client": db_client}


def get_clients_passwordless() -> dict[str, Any]:
    """Get Azure OpenAI and Cosmos DB clients using DefaultAzureCredential.

    Uses managed identity / Azure CLI credentials for passwordless auth.
    Returns dict with 'ai_client' and 'db_client' (either may be None).
    """
    from azure.cosmos import CosmosClient
    from azure.identity import DefaultAzureCredential, get_bearer_token_provider
    from openai import AzureOpenAI

    ai_client = None
    db_client = None

    api_version = os.getenv("AZURE_OPENAI_EMBEDDING_API_VERSION", "")
    endpoint = os.getenv("AZURE_OPENAI_EMBEDDING_ENDPOINT", "")
    deployment = os.getenv("AZURE_OPENAI_EMBEDDING_MODEL", "")

    if api_version and endpoint and deployment:
        credential = DefaultAzureCredential()
        token_provider = get_bearer_token_provider(
            credential, "https://cognitiveservices.azure.com/.default"
        )
        ai_client = AzureOpenAI(
            api_version=api_version,
            azure_endpoint=endpoint,
            azure_deployment=deployment,
            azure_ad_token_provider=token_provider,
        )

    cosmos_endpoint = os.getenv("AZURE_COSMOSDB_ENDPOINT", "")

    if cosmos_endpoint:
        credential = DefaultAzureCredential()
        db_client = CosmosClient(url=cosmos_endpoint, credential=credential)

    return {"ai_client": ai_client, "db_client": db_client}


def read_file_return_json(file_path: str) -> list[dict[str, Any]]:
    """Read a JSON file and return its parsed contents."""
    print(f"Reading JSON file from {file_path}")
    try:
        with open(file_path, "r", encoding="utf-8") as f:
            return json.load(f)
    except FileNotFoundError:
        print(f"Error: File '{file_path}' not found")
        raise
    except json.JSONDecodeError as e:
        print(f"Error: Invalid JSON in file '{file_path}': {e}")
        raise


def write_file_json(file_path: str, json_data: Any) -> None:
    """Serialize data to a JSON file."""
    try:
        with open(file_path, "w", encoding="utf-8") as f:
            json.dump(json_data, f, indent=2, ensure_ascii=False)
        print(f"Wrote JSON file to {file_path}")
    except IOError as e:
        print(f"Error writing to file '{file_path}': {e}")
        raise


def _get_document_count(container: Any) -> int:
    """Return the number of documents in a Cosmos DB container."""
    query = "SELECT VALUE COUNT(1) FROM c"
    results = list(container.query_items(query=query, enable_cross_partition_query=True))
    return results[0] if results else 0


def insert_data(
    container: Any, data: list[dict[str, Any]]
) -> dict[str, Any]:
    """Bulk-insert documents into a Cosmos DB container.

    Skips insertion if the container already has documents.
    Each item gets an 'id' field mapped from 'HotelId'.

    Returns a dict with total, inserted, failed, skipped, and requestCharge.
    """
    existing_count = _get_document_count(container)

    if existing_count > 0:
        print(f"Container already has {existing_count} documents. Skipping insert.")
        return {
            "total": 0,
            "inserted": 0,
            "failed": 0,
            "skipped": existing_count,
            "requestCharge": 0.0,
        }

    print(f"Inserting {len(data)} items...")

    inserted = 0
    failed = 0
    total_request_charge = 0.0

    start_time = time.time()

    for item in data:
        doc = {"id": item["HotelId"], **item}
        try:
            response = container.upsert_item(body=doc)
            inserted += 1
            ru = _extract_ru_from_headers(container.client_connection.last_response_headers)
            total_request_charge += ru
        except Exception as e:
            status_code = getattr(e, "status_code", None)
            if status_code == 409:
                inserted += 1
            else:
                failed += 1
                print(f"  Insert failed for item {item.get('HotelId', '?')}: {e}")

    duration = time.time() - start_time
    print(f"Bulk insert completed in {duration:.2f}s")
    print(f"\nInsert Request Charge: {total_request_charge:.2f} RUs\n")

    return {
        "total": len(data),
        "inserted": inserted,
        "failed": failed,
        "skipped": 0,
        "requestCharge": total_request_charge,
    }


def _extract_ru_from_headers(headers: Optional[dict[str, str]]) -> float:
    """Extract the request charge (RU) from Cosmos DB response headers."""
    if not headers:
        return 0.0
    raw = headers.get("x-ms-request-charge", "0")
    try:
        return float(raw)
    except (ValueError, TypeError):
        return 0.0


def validate_field_name(field_name: str) -> str:
    """Validate a field name is a safe SQL identifier.

    Prevents NoSQL injection when interpolating field names into queries.
    Allows only letters, digits, and underscores; must start with a letter
    or underscore.

    Raises ValueError if the field name is invalid.
    """
    pattern = re.compile(r"^[A-Za-z_][A-Za-z0-9_]*$")
    if not pattern.match(field_name):
        raise ValueError(
            f'Invalid field name: "{field_name}". '
            "Field names must start with a letter or underscore and "
            "contain only letters, numbers, and underscores."
        )
    return field_name


def print_search_results(
    search_results: list[dict[str, Any]],
    request_charge: Optional[float] = None,
) -> None:
    """Print vector search results in a consistent format."""
    print("\n--- Search Results ---")
    if not search_results:
        print("No results found.")
        return

    for i, result in enumerate(search_results, 1):
        score = result.get("SimilarityScore", 0.0)
        name = result.get("HotelName", "Unknown")
        print(f"{i}. {name}, Score: {score:.4f}")

    if request_charge is not None:
        print(f"\nVector Search Request Charge: {request_charge:.2f} RUs")
    print("")


def get_query_activity_id(response_headers: Optional[dict[str, str]]) -> Optional[str]:
    """Extract the activity ID from Cosmos DB query response headers."""
    if not response_headers:
        return None
    return response_headers.get("x-ms-activity-id")


def get_bulk_operation_rus(headers: Optional[dict[str, str]]) -> float:
    """Extract total RU cost from Cosmos DB response headers."""
    return _extract_ru_from_headers(headers)

Ce module utilitaire fournit les fonctions clés suivantes :

  • get_clients_passwordless : crée et retourne des clients pour Azure OpenAI et Azure Cosmos DB à l’aide de l’authentification sans mot de passe. Activez RBAC sur les deux ressources et connectez-vous à Azure CLI
  • insert_data : insère des données dans un conteneur Azure Cosmos DB et effectue le suivi des unités de requête (RU) pour chaque opération
  • print_search_results: imprime les résultats d’une recherche vectorielle, y compris le score et le nom de l’hôtel
  • validate_field_name: valide qu’un nom de champ existe dans les données
  • get_bulk_operation_rus : extrait le coût total des RU à partir des en-têtes de réponse Azure Cosmos DB

S’authentifier avec Azure CLI

Connectez-vous à Azure CLI avant d’exécuter l’application afin que l’application puisse accéder en toute sécurité aux ressources Azure.

az login

Le code utilise l’authentification de votre développeur local pour accéder à Azure Cosmos DB et Azure OpenAI avec la fonction get_clients_passwordless à partir de utils.py. Lorsque vous définissez AZURE_TOKEN_CREDENTIALS=AzureCliCredential, vous sélectionnez de manière déterministe les informations d’identification que DefaultAzureCredential utilise dans sa chaîne d'informations d'identification. La fonction s’appuie sur DefaultAzureCredential de azure-identity, qui parcourt une chaîne ordonnée de fournisseurs d’informations d’identification, mais prend en compte la variable d’environnement pour résoudre d’abord en les informations d'identification Azure CLI. Découvrez comment authentifier les applications Python aux services Azure à l’aide de la bibliothèque Azure Identity.

Exécuter l’application

Utilisez la variable d’environnement pour sélectionner l’implémentation VECTOR_ALGORITHM d’index vectoriel à exécuter. La variable contrôle le conteneur Azure Cosmos DB auquel l'application se connecte.

Linux/macOS :

VECTOR_ALGORITHM=diskann python -m src.vector_search

Windows :

$env:VECTOR_ALGORITHM="diskann"; python -m src.vector_search

La journalisation et la sortie de l’application indiquent :

  • État de la connexion de conteneur
  • État d’insertion des données
  • Résultats de recherche avec des noms d’hôtel et des scores de similarité
Connected to database: Hotels
Connected to container: hotels_diskann

📊 Vector Search Algorithm: DiskANN
📏 Distance Function: cosine

Reading JSON file from ..\data\HotelsData_toCosmosDB_Vector.json
Container already has 50 documents. Skipping insert.

--- Executing Vector Search Query ---
Query: SELECT TOP 5 c.HotelName, c.Description, c.Rating, VectorDistance(c.DescriptionVector, @embedding) AS SimilarityScore FROM c ORDER BY VectorDistance(c.DescriptionVector, @embedding)
Parameters: @embedding (vector with 1536 dimensions)
--------------------------------------

Query activity ID: <ACTIVITY_ID>

--- Search Results ---
1. Royal Cottage Resort, Score: 0.4991
2. Country Comfort Inn, Score: 0.4786
3. Nordick's Valley Motel, Score: 0.4635
4. Economy Universe Motel, Score: 0.4461
5. Roach Motel, Score: 0.4388

Vector Search Request Charge: 5.33 RUs

Métriques de distance

Azure Cosmos DB prend en charge trois fonctions de distance pour la similarité vectorielle :

Fonction de distance Plage de score Interprétation Idéal pour
Cosinus (valeur par défaut) 0.0 à 1.0 Des scores plus élevés (plus proches de 1,0) indiquent une plus grande similarité Similarité de texte générale, incorporations Azure OpenAI (utilisées dans ce guide de démarrage rapide)
Euclidien (L2) 0,0 à ∞ Inférieur = plus similaire Données spatiales, quand l’ampleur importe
Dot Product -∞ à +∞ Plus élevé = plus similaire Lorsque les magnitudes de vecteur sont normalisées

La fonction de distance est définie dans la stratégie d’incorporation de vecteurs lors de la création du conteneur. Cela est fourni dans l’infrastructure du référentiel d'exemples. Elle est définie dans le cadre de la définition du conteneur.

{
    name: 'hotels_diskann'
    partitionKeyPaths: [
        '/HotelId'
    ]
    indexingPolicy: {
        indexingMode: 'consistent'
        automatic: true
        includedPaths: [
        {
            path: '/*'
        }
        ]
        excludedPaths: [
        {
            path: '/_etag/?'
        }
        {
            path: '/DescriptionVector/*'
        }
        ]
        vectorIndexes: [
        {
            path: '/DescriptionVector'
            type: 'diskANN'
        }
        ]
    }
    vectorEmbeddingPolicy: {
        vectorEmbeddings: [
        {
            path: '/DescriptionVector'
            dataType: 'float32'
            dimensions: 1536
            distanceFunction: 'cosine'
        }
        ]
    }
}

Ce code Bicep définit une configuration de conteneur Azure Cosmos DB pour le stockage de documents d’hôtel avec des fonctionnalités de recherche vectorielle.

Propriété Description
partitionKeyPaths Partitionne les documents par HotelId pour le stockage distribué.
indexingPolicy Configure l’indexation automatique sur toutes les propriétés de document (/*) à l’exception du champ système _etag et du DescriptionVector tableau pour optimiser les performances d’écriture. Les champs vectoriels n’ont pas besoin d’indexation standard, car ils utilisent plutôt une configuration spécialisée vectorIndexes .
vectorIndexes Crée un index DiskANN ou quantizedFlat sur le chemin d’accès /DescriptionVector pour des recherches de similarité efficaces.
vectorEmbeddingPolicy Définit les caractéristiques du champ vecteur : float32 type de données avec 1536 dimensions (correspondant à la sortie du text-embedding-3-small modèle) et cosinus comme fonction de distance pour mesurer la similarité entre les vecteurs pendant les requêtes.

Interpréter les scores de similarité

Dans l’exemple de sortie utilisant la similarité cosinus :

  • 0.4991 (Royal Cottage Resort) - Similarité la plus élevée, meilleure correspondance pour « hébergement près des sentiers de course, restaurants, vente au détail »
  • 0.4388 (Roach Motel) - Similarité inférieure, toujours pertinente mais moins correspondante
  • Les scores plus proches de 1,0 indiquent une similarité sémantique plus forte
  • Les scores proches de 0 indiquent peu de similarité

Remarques importantes :

  • Les valeurs de score absolu dépendent de votre modèle d’incorporation et de vos données
  • Concentrez-vous sur le classement relatif plutôt que sur les seuils absolus
  • Les intégrations Azure OpenAI fonctionnent mieux avec la similarité par cosinus

Pour plus d’informations sur les fonctions de distance, consultez Qu’est-ce que les fonctions de distance ?

Afficher et gérer des données dans Visual Studio Code

  1. Sélectionnez l’extension Cosmos DB dans Visual Studio Code pour vous connecter à votre compte Azure Cosmos DB.

  2. Affichez les données et les index dans la base de données Hotels.

    Capture d’écran de Visual Studio Code montrant l’extension Azure Cosmos DB avec des éléments de base de données Hotels et un éditeur de document JSON.

Nettoyer les ressources

Lorsque vous n’avez plus besoin de l’API pour le compte NoSQL, vous pouvez supprimer le groupe de ressources correspondant.

  1. Accédez au groupe de ressources que vous avez créé précédemment dans le portail Azure.

    Tip

    Dans ce guide de démarrage rapide, nous avons recommandé le nom msdocs-cosmos-quickstart-rg.

  2. Sélectionnez Supprimer le groupe de ressources.

    Capture d’écran de l’option Supprimer le groupe de ressources dans la barre de navigation d’un groupe de ressources.

  3. Dans la boîte de dialogue Supprimer , entrez le nom du groupe de ressources, puis sélectionnez Supprimer.

    Capture d’écran de la page de confirmation de suppression d’un groupe de ressources.