For the complete documentation index, see llms.txt. Markdown versions of documentation pages are available by appending .md to the page URL.
Navigation principale

Récupération

Recherchez dans vos données à l’aide de la similarité sémantique.

L’ API Retrieval vous permet d’effectuer une recherche sémantique dans vos données. Cette technique fait ressortir des résultats dont le sens est proche de votre requête, même s’ils ne partagent que peu ou pas de mots-clés avec elle. La récupération est utile en elle-même, mais devient particulièrement puissante lorsqu’elle est associée à nos modèles pour synthétiser des réponses.

Illustration de la récupération

L’API Retrieval s’appuie sur des bases vectorielles, qui servent d’index pour vos données. Ce guide explique comment effectuer une recherche sémantique et présente en détail les bases vectorielles.

Démarrage rapide

  • Créez une base vectorielle et importez des fichiers.

  • Création d’une base vectorielle avec des fichiers
    from openai import OpenAI
    
    client = OpenAI()
    
    vector_store = client.vector_stores.create(        # Create vector store
        name="Support FAQ",
    )
    
    client.vector_stores.files.upload_and_poll(        # Upload file
        vector_store_id=vector_store.id,
        file=open("customer_policies.txt", "rb")
    )
  • Envoyez une requête de recherche pour obtenir des résultats pertinents.

  • Requête de recherche
    user_query = "What is the return policy?"
    
    results = client.vector_stores.search(
        vector_store_id=vector_store.id,
        query=user_query,
    )

    Pour savoir comment utiliser les résultats avec nos modèles, consultez la section Synthèse des réponses.

    La recherche sémantique est une technique qui utilise des plongements vectoriels pour faire ressortir des résultats pertinents sur le plan du sens. Elle permet notamment de trouver des résultats qui partagent peu ou pas de mots-clés avec la requête et que les techniques de recherche classiques pourraient manquer.

    Examinons par exemple les résultats possibles pour "When did we go to the moon?" :

    TexteSimilarité des mots-clésSimilarité sémantique
    Le premier alunissage a eu lieu en juillet 1969.0 %65 %
    Le premier homme sur la Lune était Neil Armstrong.27 %43 %
    Quand j’ai mangé le gâteau de lune, je l’ai trouvé délicieux.40 %28 %

    (La similarité des mots-clés utilise le rapport entre l’intersection et l’union ; la similarité sémantique utilise la similarité cosinus avec text-embedding-3-small.)

    Remarquez que le résultat le plus pertinent ne contient aucun des mots de la requête de recherche. Cette souplesse fait de la recherche sémantique une technique puissante pour interroger des bases de connaissances de toute taille.

    La recherche sémantique s’appuie sur des bases vectorielles, que nous présentons en détail plus loin dans ce guide. Cette section se concentre sur le fonctionnement de la recherche sémantique.

    Vous pouvez interroger une base vectorielle à l’aide de la fonction search, en précisant une requête en langage naturel dans query. Vous obtenez une liste de résultats, chacun comprenant les segments pertinents, les scores de similarité et le fichier d’origine.

    Requête de recherche
    results = client.vector_stores.search(
        vector_store_id=vector_store.id,
        query="How many woodchucks are allowed per passenger?",
    )
    Résultats
    {
      "object": "vector_store.search_results.page",
      "search_query": "How many woodchucks are allowed per passenger?",
      "data": [
        {
          "file_id": "file-12345",
          "filename": "woodchuck_policy.txt",
          "score": 0.85,
          "attributes": {
            "region": "North America",
            "author": "Wildlife Department"
          },
          "content": [
            {
              "type": "text",
              "text": "According to the latest regulations, each passenger is allowed to carry up to two woodchucks."
            },
            {
              "type": "text",
              "text": "Ensure that the woodchucks are properly contained during transport."
            }
          ]
        },
        {
          "file_id": "file-67890",
          "filename": "transport_guidelines.txt",
          "score": 0.75,
          "attributes": {
            "region": "North America",
            "author": "Transport Authority"
          },
          "content": [
            {
              "type": "text",
              "text": "Passengers must adhere to the guidelines set forth by the Transport Authority regarding the transport of woodchucks."
            }
          ]
        }
      ],
      "has_more": false,
      "next_page": null
    }

    Par défaut, une réponse contient au maximum 10 résultats, mais vous pouvez porter cette limite à 50 à l’aide du paramètre max_num_results.

    Reformulation des requêtes

    Certaines formulations de requêtes donnent de meilleurs résultats. Nous proposons donc un paramètre qui reformule automatiquement vos requêtes pour optimiser les performances. Activez cette fonctionnalité en définissant rewrite_query=true lors d’un appel à search.

    La requête reformulée sera disponible dans le champ search_query du résultat.

    Requête d’origineRequête reformulée
    J’aimerais connaître la hauteur du bâtiment principal des bureaux.hauteur bâtiment principal bureaux
    Quelles sont les règles de sécurité pour le transport de matières dangereuses ?règles de sécurité matières dangereuses
    Comment déposer une réclamation concernant un problème de service ?procédure de dépôt de réclamation service

    Filtrage par attributs

    Le filtrage par attributs permet d’affiner les résultats en appliquant des critères, par exemple en limitant les recherches à une plage de dates précise. Vous pouvez définir et combiner des critères dans attribute_filter pour sélectionner les fichiers selon leurs attributs avant d’effectuer la recherche sémantique.

    Utilisez des filtres de comparaison pour comparer une clé key précise dans les attributes d’un fichier à une valeur value donnée, et des filtres composés pour combiner plusieurs filtres à l’aide de and et or.

    Filtre de comparaison
    {
      "type": "eq" | "ne" | "gt" | "gte" | "lt" | "lte" | "in" | "nin",  // comparison operators
      "key": "attributes_key",                           // attributes key
      "value": "target_value"                             // value to compare against
    }
    Filtre composé
    {
      "type": "and" | "or",                                // logical operators
      "filters": [...]
    }

    Voici quelques exemples de filtres.

    Filtre par région
    {
      "type": "eq",
      "key": "region",
      "value": "us"
    }

    Classement

    Si les résultats de votre recherche de fichiers ne sont pas suffisamment pertinents, vous pouvez ajuster ranking_options pour améliorer la qualité des réponses. Vous pouvez notamment spécifier un ranker, comme auto ou default-2024-08-21, et définir un score_threshold compris entre 0.0 et 1.0. Une valeur plus élevée de score_threshold limite les résultats aux segments les plus pertinents, mais peut en exclure certains qui seraient utiles. Lorsque ranking_options.hybrid_search est fourni, vous pouvez également ajuster hybrid_search.embedding_weight (rrf_embedding_weight) et hybrid_search.text_weight (rrf_text_weight) pour contrôler l’équilibre, lors de la fusion par rangs réciproques, entre les correspondances sémantiques fondées sur les plongements vectoriels et les correspondances par mots-clés fondées sur des représentations creuses. Augmentez le premier poids pour privilégier la similarité sémantique, ou le second pour privilégier les éléments textuels communs, et veillez à ce qu’au moins un des poids soit supérieur à zéro.

    Bases vectorielles

    Les bases vectorielles sont les conteneurs sur lesquels repose la recherche sémantique de l’API Retrieval et de l’outil de recherche de fichiers. Lorsque vous ajoutez un fichier à une base vectorielle, il est automatiquement découpé en segments, converti en plongements vectoriels et indexé.

    Les bases vectorielles contiennent des objets vector_store_file, qui s’appuient chacun sur un objet file.

    Type d’objet
    Description
    fileReprésente le contenu importé via l’API Files. Souvent utilisé avec les bases vectorielles, mais aussi pour l’affinage et d’autres cas d’utilisation.
    vector_storeConteneur de fichiers dans lesquels effectuer des recherches.
    vector_store.fileType enveloppe représentant spécifiquement un objet file découpé en segments, converti en plongements vectoriels et associé à un objet vector_store.
    Contient le dictionnaire attributes utilisé pour le filtrage.

    Tarifs

    La facturation dépend du stockage total utilisé par l’ensemble de vos bases vectorielles, calculé à partir de la taille des segments analysés et des plongements vectoriels correspondants.

    StockageCoût
    Jusqu’à 1 Go (toutes bases confondues)Gratuit
    Au-delà de 1 Go0,10 $/Go/jour

    Consultez les politiques d’expiration pour connaître les options permettant de réduire les coûts.

    Opérations sur les bases vectorielles

    Création d’une base vectorielle
    client.vector_stores.create(
        name="Support FAQ",
        file_ids=["file_123"]
    )

    Opérations sur les fichiers d’une base vectorielle

    Certaines opérations, comme create pour vector_store.file, sont asynchrones et peuvent prendre du temps. Utilisez nos fonctions utilitaires, comme create_and_poll, pour bloquer l’exécution jusqu’à leur achèvement. Vous pouvez aussi vérifier leur état. La suppression de fichiers d’une base vectorielle suit un modèle de cohérence à terme : les résultats de recherche peuvent donc encore inclure du contenu provenant d’un fichier supprimé pendant un court laps de temps.

    L’ajout de fichiers est soumis à une limite de débit par identifiant de base vectorielle. Les requêtes vers /vector_stores/{vector_store_id}/files et /vector_stores/{vector_store_id}/file_batches partagent une limite de 300 requêtes par minute et par base vectorielle.

    Créer un fichier dans une base vectorielle
    client.vector_stores.files.create_and_poll(
        vector_store_id="vs_123",
        file_id="file_123"
    )

    Opérations par lots

    Création d’un lot
    client.vector_stores.file_batches.create_and_poll(
        vector_store_id="vs_123",
        files=[
            {
                "file_id": "file_123",
                "attributes": {"department": "finance"}
            },
            {
                "file_id": "file_456",
                "chunking_strategy": {
                    "type": "static",
                    "max_chunk_size_tokens": 1200,
                    "chunk_overlap_tokens": 200
                }
            }
        ]
    )

    Lors de la création d’un lot, vous pouvez soit fournir file_ids avec les paramètres facultatifs attributes et/ou chunking_strategy, soit utiliser le tableau files pour transmettre des objets contenant, pour chaque fichier, un file_id ainsi que les paramètres facultatifs attributes et chunking_strategy. Ces deux options sont mutuellement exclusives : vous pouvez ainsi choisir clairement entre des paramètres communs à tous les fichiers et des paramètres propres à chaque fichier.

    Pour augmenter le débit d’ingestion dans une même base vectorielle, nous recommandons la création par lots dès que possible. Un lot peut inclure jusqu’à 500 fichiers dans une seule requête, ce qui réduit généralement la contention et la latence de bout en bout par rapport à l’envoi de nombreuses requêtes de création portant chacune sur un seul fichier.

    Attributs

    Chaque vector_store.file peut être associé à attributes, un dictionnaire de valeurs utilisables lors d’une recherche sémantique avec filtrage par attributs. Ce dictionnaire peut contenir au maximum 16 clés, chacune limitée à 256 caractères.

    Créez un fichier avec des attributs dans une base vectorielle
    client.vector_stores.files.create(
        vector_store_id="<vector_store_id>",
        file_id="file_123",
        attributes={
            "region": "US",
            "category": "Marketing",
            "date": 1672531200      # Jan 1, 2023
        }
    )

    Politiques d’expiration

    Vous pouvez définir une politique d’expiration pour les objets vector_store à l’aide de expires_after. Lorsqu’une base vectorielle expire, tous les objets vector_store.file associés sont supprimés et ne vous sont plus facturés.

    Définissez une politique d’expiration pour une base vectorielle
    client.vector_stores.update(
        vector_store_id="vs_123",
        expires_after={
            "anchor": "last_active_at",
            "days": 7
        }
    )

    Limites

    La taille maximale d’un fichier est de 512 Mo. Chaque fichier ne doit pas contenir plus de 5 000 000 de tokens (ce nombre est calculé automatiquement lorsque vous joignez un fichier).

    Découpage en segments

    Par défaut, max_chunk_size_tokens est défini sur 800 et chunk_overlap_tokens sur 400. Chaque fichier est donc indexé après avoir été découpé en segments de 800 tokens, avec un chevauchement de 400 tokens entre les segments consécutifs.

    Vous pouvez ajuster ce découpage en définissant chunking_strategy lors de l’ajout de fichiers à la base vectorielle. Cette stratégie comporte certaines limites :

    • max_chunk_size_tokens doit être compris entre 100 et 4096 inclus.
    • chunk_overlap_tokens doit être supérieur ou égal à zéro et ne devrait pas dépasser max_chunk_size_tokens / 2.

    Synthèse des réponses

    Après avoir effectué une requête, vous souhaiterez peut-être formuler une réponse qui synthétise les résultats. Pour cela, vous pouvez fournir les résultats et la requête initiale à nos modèles afin d’obtenir une réponse ancrée dans ces résultats.

    Effectuez une recherche pour obtenir des résultats
    from openai import OpenAI
    
    client = OpenAI()
    
    user_query = "What is the return policy?"
    
    results = client.vector_stores.search(
        vector_store_id=vector_store.id,
        query=user_query,
    )
    Formulez une réponse à partir des résultats
    # Use results and user_query from the preceding search step.
    formatted_results = format_results(results.data)
    
    "\n".join("\n".join(c.text for c in result.content) for result in results.data)
    
    completion = client.chat.completions.create(
        model="gpt-6-astra",
        messages=[
            {
                "role": "developer",
                "content": "Produce a concise answer to the query based on the provided sources.",
            },
            {
                "role": "user",
                "content": f"Sources: {formatted_results}\n\nQuery: '{user_query}'",
            },
        ],
    )
    
    print(completion.choices[0].message.content)
    "Our return policy allows returns within 30 days of purchase."

    Cet exemple utilise une fonction format_results, dont voici une implémentation possible :

    Exemple de fonction de mise en forme des résultats
    def format_results(results):
        formatted_results = ""
        for result in results.data:
            formatted_result = (
                f"<result file_id='{result.file_id}' file_name='{result.file_name}'>"
            )
            for part in result.content:
                formatted_result += f"<content>{part.text}</content>"
            formatted_results += formatted_result + "</result>"
        return f"<sources>{formatted_results}</sources>"