Créer une base de connaissances avec REST

Dans Recherche Azure AI, une base de connaissances est un référentiel de contenu généré par l’IA utilisé pour les scénarios de non-recherche. Vous créez la base de connaissances à l’aide d’un indexeur et d’un ensemble de compétences, puis spécifiez Stockage Azure pour stocker la sortie. Une fois la base de connaissances remplie, utilisez des outils comme Explorateur Stockage ou Power BI pour explorer le contenu.

Dans cet article, vous utilisez l’API REST pour ingérer, enrichir et explorer un ensemble d’évaluations de séjours hôteliers par des clients dans une base de connaissances. La base de connaissances contient le contenu texte d’origine extrait de la source, plus le contenu généré par l’IA, qui comprend un score de sentiment, l’extraction des expressions clés, la détection de la langue et la traduction texte des commentaires des clients non anglophones.

Pour que le jeu de données initial soit disponible, les avis de l’hôtel sont d’abord importés dans le Stockage Blob Azure. Post-traitement, les résultats sont enregistrés sous la forme d’une base de connaissances dans le service Stockage Table Azure.

Conseil

Cet article utilise REST pour expliquer en détail chaque étape. Téléchargez le fichier REST si vous souhaitez juste exécuter les commandes. Vous pouvez également créer une base de connaissances dans le portail Azure.

Prérequis

L’ensemble de compétences de cet exemple utilise Azure AI Services pour les enrichissements. En raison de la taille réduite de la charge de travail, Azure AI Services est utilisé en arrière-plan pour traiter gratuitement jusqu’à 20 transactions par jour. Une petite charge de travail signifie que vous pouvez ignorer la création ou l’attachement d’une ressource multiservices Azure AI.

Charger des données dans Stockage Azure et obtenir une chaîne de connexion

  1. Téléchargez le fichier HotelReviews_Free.csv. Ce CSV contient 19 commentaires de clients sur un seul hôtel (provient de Kaggle.com).

  2. Dans le portail Azure, localisez votre compte de stockage et utilisez Navigateur de stockage pour créer un conteneur de blobs nommé hotel-reviews.

  3. Sélectionnez Charger en haut de la page pour charger le fichier HotelReviews-Free.csv que vous avez téléchargé à l’étape précédente.

    Screenshot of Storage Browser with uploaded file and left nav pane

  4. Sur la gauche, sélectionnez Clés d’accès et Afficher les clés, puis copiez la chaîne de connexion pour key1 ou key2. Une chaîne de connexion d’accès complet a le format suivant :

"knowledgeStore": {
    "storageConnectionString": "DefaultEndpointsProtocol=https;AccountName=<YOUR-ACCOUNT-NAME>;AccountKey=<YOUR-ACCOUNT-KEY>;EndpointSuffix=core.windows.net;"
}

Remarque

Consultez Se connecter en utilisant une identité managée si vous ne souhaitez pas fournir de données sensibles sur la chaîne de connexion.

Copier une clé et une URL

Dans cet exemple, les appels REST ont besoin du point de terminaison de service de recherche et d’une clé API sur chaque requête. Vous pouvez obtenir ces valeurs dans le portail Azure.

  1. Connectez-vous au portail Azure, accédez à la page Vue d’ensemble et copiez l’URL. Voici un exemple de point de terminaison : https://mydemo.search.windows.net.

  2. Sous Paramètres>Clés, copiez une clé d’administration. Les clés d’administration sont utilisées pour ajouter, modifier et supprimer des objets. Il existe deux clés d’administration interchangeables. Copiez l’une ou l’autre.

    Screenshot of the URL and API keys in the Azure portal.

Une clé API valide permet d’établir, en fonction de chaque requête, une relation de confiance entre l’application qui envoie la requête et le service de recherche qui en assure le traitement.

Création d'un index

Créer un index (REST) permet de créer un index de recherche sur le service de recherche. Un index de recherche n’est pas lié à une base de connaissances, mais l’indexeur en a besoin d’une. L’index de recherche contient le même contenu que la base de connaissances, que vous pouvez explorer en envoyant des requêtes.

  1. Ouvrez un nouveau fichier texte dans Visual Studio Code.

  2. Définissez les variables sur le point de terminaison de recherche et la clé API que vous avez collectée précédemment.

    @baseUrl = PUT-YOUR-SEARCH-SERVICE-URL-HERE
    @apiKey = PUT-YOUR-ADMIN-API-KEY-HERE
    @storageConnection = PUT-YOUR-STORAGE-CONNECTION-STRING-HERE
    @blobContainer = PUT-YOUR-CONTAINER-NAME-HERE (hotel-reviews)
    
  3. Enregistrez le fichier avec une extension de fichier .rest.

  4. Collez l’exemple suivant pour créer la requête d’index.

    ### Create a new index
    POST {{baseUrl}}/indexes?api-version=2023-11-01  HTTP/1.1
        Content-Type: application/json
        api-key: {{apiKey}}
    
        {
            "name": "hotel-reviews-kstore-idx",  
            "fields": [
                { "name": "name", "type": "Edm.String", "filterable": false, "sortable": false, "facetable": false },
                { "name": "reviews_date", "type": "Edm.DateTimeOffset", "searchable": false, "filterable": false, "sortable": false, "facetable": false },
                { "name": "reviews_rating", "type": "Edm.String", "searchable": false, "filterable": false, "sortable": false, "facetable": false },
                { "name": "reviews_text", "type": "Edm.String", "filterable": false,  "sortable": false, "facetable": false },
                { "name": "reviews_title", "type": "Edm.String", "searchable": false, "filterable": false, "sortable": false, "facetable": false },
                { "name": "reviews_username", "type": "Edm.String", "searchable": false, "filterable": false, "sortable": false, "facetable": false },
                { "name": "AzureSearch_DocumentKey", "type": "Edm.String", "searchable": false, "filterable": false, "sortable": false, "facetable": false, "key": true },
                { "name": "language", "type": "Edm.String", "filterable": true, "sortable": false, "facetable": true },
                { "name": "translated_text", "type": "Edm.String", "filterable": false, "sortable": false, "facetable": false },
                { "name": "sentiment", "type": "Collection(Edm.String)", "searchable": false, "filterable": true, "retrievable": true, "sortable": false, "facetable": true },
                { "name": "keyphrases", "type": "Collection(Edm.String)", "filterable": true, "sortable": false, "facetable": true }
            ]
        }
    
  5. Sélectionnez Envoyer une demande. Vous devriez avoir une réponse HTTP/1.1 201 Created et le corps de la réponse devrait inclure la représentation JSON du schéma d’index.

Création d'une source de données

Créer une source de données permet de créer une connexion de source de données sur Recherche Azure AI.

  1. Collez l’exemple suivant pour créer la source de données.

    ### Create a data source
    POST {{baseUrl}}/datasources?api-version=2023-11-01  HTTP/1.1
      Content-Type: application/json
      api-key: {{apiKey}}
    
        {
            "name": "hotel-reviews-kstore-ds",
            "description": null,
            "type": "azureblob",
            "subtype": null,
            "credentials": {
                "connectionString": "{{storageConnectionString}}"
            },
            "container": {
                "name": "{{blobContainer}}",
                "query": null
            },
            "dataChangeDetectionPolicy": null,
            "dataDeletionDetectionPolicy": null
        }
    
  2. Sélectionnez Envoyer une demande.

Créer un ensemble de compétences

Un ensemble de compétences définit des enrichissements (compétences) et votre base de connaissances. Créer un ensemble de compétences permet de créer l’objet sur votre service de recherche.

  1. Collez l’exemple suivant pour créer l’ensemble de compétences.

    ### Create a skillset
    POST {{baseUrl}}/skillsets?api-version=2023-11-01  HTTP/1.1
        Content-Type: application/json
        api-key: {{apiKey}}
    
        {
            "name": "hotel-reviews-kstore-ss",
            "description": "Skillset to detect language, translate text, extract key phrases, and score sentiment",
            "skills": [ 
                {
                    "@odata.type": "#Microsoft.Skills.Text.SplitSkill", 
                    "context": "/document/reviews_text", "textSplitMode": "pages", "maximumPageLength": 5000,
                    "inputs": [ 
                        { "name": "text", "source": "/document/reviews_text" }
                    ],
                    "outputs": [
                        { "name": "textItems", "targetName": "pages" }
                    ]
                },
                {
                    "@odata.type": "#Microsoft.Skills.Text.V3.SentimentSkill",
                    "context": "/document/reviews_text/pages/*",
                    "inputs": [
                        { "name": "text", "source": "/document/reviews_text/pages/*" },
                        { "name": "languageCode", "source": "/document/language" }
                    ],
                    "outputs": [
                        { "name": "sentiment", "targetName": "sentiment" }
                    ]
                },
                {
                    "@odata.type": "#Microsoft.Skills.Text.LanguageDetectionSkill",
                    "context": "/document",
                    "inputs": [
                        { "name": "text", "source": "/document/reviews_text" }
                    ],
                    "outputs": [
                        { "name": "languageCode", "targetName": "language" }
                    ]
                },
                {
                    "@odata.type": "#Microsoft.Skills.Text.TranslationSkill",
                    "context": "/document/reviews_text/pages/*",
                    "defaultFromLanguageCode": null,
                    "defaultToLanguageCode": "en",
                    "inputs": [
                        { "name": "text", "source": "/document/reviews_text/pages/*" }
                    ],
                    "outputs": [
                        { "name": "translatedText", "targetName": "translated_text" }
                    ]
                },
                {
                    "@odata.type": "#Microsoft.Skills.Text.KeyPhraseExtractionSkill",
                    "context": "/document/reviews_text/pages/*",
                    "inputs": [
                        { "name": "text",  "source": "/document/reviews_text/pages/*" },
                        { "name": "languageCode",  "source": "/document/language" }
                    ],
                    "outputs": [
                        { "name": "keyPhrases" , "targetName": "keyphrases" }
                    ]
                },
                {
                    "@odata.type": "#Microsoft.Skills.Util.ShaperSkill",
                    "context": "/document",
                    "inputs": [
                        { "name": "name",  "source": "/document/name" },
                        { "name": "reviews_date",  "source": "/document/reviews_date" },
                        { "name": "reviews_rating",  "source": "/document/reviews_rating" },
                        { "name": "reviews_text",  "source": "/document/reviews_text" },
                        { "name": "reviews_title",  "source": "/document/reviews_title" },
                        { "name": "reviews_username",  "source": "/document/reviews_username" },
                        { "name": "AzureSearch_DocumentKey",  "source": "/document/AzureSearch_DocumentKey" },
                        {
                        "name": "pages",
                        "sourceContext": "/document/reviews_text/pages/*",
                        "inputs": [
                            {
                            "name": "languageCode",
                            "source": "/document/language"
                            },
                            {
                            "name": "translatedText",
                            "source": "/document/reviews_text/pages/*/translated_text"
                            },
                            { 
                            "name": "sentiment",
                            "source": "/document/reviews_text/pages/*/sentiment"
                            },
                            {
                            "name": "keyPhrases",
                            "source": "/document/reviews_text/pages/*/keyphrases/*"
                            },
                            {
                            "name": "Page",
                            "source": "/document/reviews_text/pages/*"
                            }
                        ]
                        }
                    ],
                    "outputs": [
                        { "name": "output" , "targetName": "tableprojection" }
                    ]
                }
            ],
            "knowledgeStore": {
                "storageConnectionString": "{{storageConnectionString}}",
                "projections": [
                    {
                        "tables": [
                            { "tableName": "hotelReviews1Document", "generatedKeyName": "Documentid", "source": "/document/tableprojection" },
                            { "tableName": "hotelReviews2Pages", "generatedKeyName": "Pagesid", "source": "/document/tableprojection/pages/*" },
                            { "tableName": "hotelReviews3KeyPhrases", "generatedKeyName": "KeyPhrasesid", "source": "/document/tableprojection/pages/*/keyPhrases/*" }
                        ],
                        "objects": []
                    },
                    {
                        "tables": [
                            { 
                                "tableName": "hotelReviews4InlineProjectionDocument", "generatedKeyName": "Documentid", "sourceContext": "/document",
                                "inputs": [
                                    { "name": "name", "source": "/document/name"},
                                    { "name": "reviews_date", "source": "/document/reviews_date"},
                                    { "name": "reviews_rating", "source": "/document/reviews_rating"},
                                    { "name": "reviews_username", "source": "/document/reviews_username"},
                                    { "name": "reviews_title", "source": "/document/reviews_title"},
                                    { "name": "reviews_text", "source": "/document/reviews_text"},
                                    { "name": "AzureSearch_DocumentKey", "source": "/document/AzureSearch_DocumentKey" }
                                ]
                            },
                            { 
                                "tableName": "hotelReviews5InlineProjectionPages", "generatedKeyName": "Pagesid", "sourceContext": "/document/reviews_text/pages/*",
                                "inputs": [
                                    { "name": "Sentiment", "source": "/document/reviews_text/pages/*/sentiment"},
                                    { "name": "LanguageCode", "source": "/document/language"},
                                    { "name": "Keyphrases", "source": "/document/reviews_text/pages/*/keyphrases"},
                                    { "name": "TranslatedText", "source": "/document/reviews_text/pages/*/translated_text"},
                                    { "name": "Page", "source": "/document/reviews_text/pages/*" }
                                ]
                            },
                            { 
                                "tableName": "hotelReviews6InlineProjectionKeyPhrases", "generatedKeyName": "kpidv2", "sourceContext": "/document/reviews_text/pages/*/keyphrases/*",
                                "inputs": [
                                    { "name": "Keyphrases", "source": "/document/reviews_text/pages/*/keyphrases/*" }
                                ]
                            }
                        ],
                        "objects": []
                    }
                ]
            }
        }
    

Points essentiels :

  • La compétence Modélisateur est importante pour la définition de la base de connaissances. Elle spécifie la façon dont les données circulent dans les tables de la base de connaissances. Les entrées sont les parties du document enrichi que vous souhaitez stocker. La sortie est un regroupement des nœuds dans une structure unique.

  • Les projections spécifient les tables, les objets et les blobs de votre base de connaissances. Chaque élément de projection spécifie le "name" de la colonne ou du champ à créer dans Stockage Azure. La "source" spécifie quelle partie de la sortie du modélisateur est affectée à ce champ ou cette colonne.

Créer un indexeur

Créer un indexeur permet de créer et d’exécuter l’indexeur. L’exécution de l’indexeur commence par ouvrir les documents, extraire le texte et les images, et initialiser l’ensemble de compétences. L’indexeur recherche les autres objets que vous avez créés : la source de données, l’index et l’ensemble de compétences.

  1. Collez l’exemple suivant pour créer l’indexeur.

    ### Create indexer
    POST {{baseUrl}}/indexers?api-version=2023-11-01  HTTP/1.1
        Content-Type: application/json
        api-key: {{apiKey}}
    
        {
            "name": "hotel-reviews-kstore-idxr",
            "dataSourceName": "hotel-reviews-kstore-ds",
            "skillsetName": "hotel-reviews-kstore-ss",
            "targetIndexName": "hotel-reviews-kstore-idx",
            "parameters": {
                "configuration": {
                    "dataToExtract": "contentAndMetadata",
                    "parsingMode": "delimitedText",
                    "firstLineContainsHeaders": true,
                    "delimitedTextDelimiter": ","
        }
    },
    "fieldMappings": [
        {
            "sourceFieldName": "AzureSearch_DocumentKey",
            "targetFieldName": "AzureSearch_DocumentKey",
            "mappingFunction": { "name": "base64Encode" }
        }
    ],
    "outputFieldMappings": [
        { "sourceFieldName": "/document/reviews_text/pages/*/Keyphrases/*", "targetFieldName": "Keyphrases" },
        { "sourceFieldName": "/document/Language", "targetFieldName": "Language" },
        { "sourceFieldName": "/document/reviews_text/pages/*/Sentiment", "targetFieldName": "Sentiment" }
        ]
    }
    
  2. Sélectionnez Envoyer la demande pour créer et exécuter l’indexeur. Cette étape prend plusieurs minutes.

Points essentiels :

  • L’objet parameters/configuration contrôle la manière dont l’indexeur ingère les données. Dans ce cas, les données d’entrée se trouvent dans un même fichier CSV qui comporte une ligne d’en-tête et des valeurs séparées par des virgules.

  • Les mappages de champs créent « AzureSearch_DocumentKey », qui est un identificateur unique pour chaque document généré par l’indexeur d’objets blob (basé sur le chemin de stockage des métadonnées).

  • Les mappages de champs de sortie spécifient comment les champs enrichis sont mappés aux champs d’un index de recherche. Les mappages de champs de sortie ne sont pas utilisés dans les bases de connaissances (les bases de connaissances utilisent des formes et des projections pour exprimer les structures de données physiques).

Vérification du statut

Une fois que vous avez envoyé chaque demande, le service de recherche doit répondre avec un message de réussite 201.

### Get Indexer Status (wait several minutes for the indexer to complete)
GET {{baseUrl}}/indexers/hotel-reviews-kstore-idxr/status?api-version=2023-11-01  HTTP/1.1
  Content-Type: application/json
  api-key: {{apiKey}}

Après plusieurs minutes, vous pouvez interroger l’index pour inspecter le contenu. Même si vous n’utilisez pas l’index, cette étape est un moyen pratique de confirmer que l’ensemble de compétences a produit la sortie attendue.

### Query the index (indexer status must be "success" before querying the index)
POST {{baseUrl}}/indexes/hotel-reviews-kstore-idxr/docs/search?api-version=2023-11-01  HTTP/1.1
  Content-Type: application/json
  api-key: {{apiKey}}
  
  {
    "search": "*",
    "select": "reviews_title, reviews_username, language, translated_text, sentiment",
    "count": true
  }

Vérifier les tables dans le portail Azure

Dans le portail Azure, basculez sur votre compte de stockage Azure et utilisez Navigateur de stockage pour visualiser les nouvelles tables. Vous devez voir six tables, une pour chaque projection définie dans l’ensemble de compétences.

Chaque table est générée avec les ID nécessaires à la liaison croisée des tables dans les requêtes. Quand vous ouvrez une table, faites défiler au-delà de ces champs pour voir les champs de contenu ajoutés par le pipeline.

Screenshot of the knowledge store tables in Storage Browser

Dans cette procédure pas à pas, la base de connaissances se compose de différentes tables montrant différentes façons de mettre en forme et de structurer une table. Les tables un à trois utilisent la sortie d’une compétence Modélisateur pour déterminer les colonnes et les lignes. Les tables quatre à six sont créées à partir d’instructions de mise en forme incluse, incorporées dans la projection elle-même. Vous pouvez utiliser l’une ou l’autre approche pour obtenir le même résultat.

Table Description
hotelReviews1Document Contient des champs provenant du fichier CSV, comme reviews_date et reviews_text.
hotelReviews2Pages Contient des champs enrichis créés par l’ensemble de compétences, comme le score de sentiment et le texte traduit.
hotelReviews3KeyPhrases Contient une longue liste des expressions clés uniquement.
hotelReviews4InlineProjectionDocument Alternative à la première table, utilisant la mise en forme incluse au lieu de la compétence Modélisateur pour mettre en forme les données de la projection.
hotelReviews5InlineProjectionPages Alternative à la deuxième table, utilisant une mise en forme incluse.
hotelreviews6InlineProjectionKeyPhrases Alternative à la troisième table, utilisant une mise en forme incluse.

Nettoyer

Lorsque vous travaillez dans votre propre abonnement, il est recommandé, à la fin de chaque projet, de déterminer si vous avez toujours besoin des ressources que vous avez créées. Les ressources laissées en cours d’exécution peuvent vous coûter de l’argent. Vous pouvez supprimer les ressources une par une, ou choisir de supprimer le groupe de ressources afin de supprimer l’ensemble des ressources.

Vous pouvez rechercher et gérer les ressources dans le portail à l’aide des liens Toutes les ressources ou Groupes de ressources situés dans le volet de navigation de gauche.

Étapes suivantes

Maintenant que vous avez enrichi vos données en utilisant Azure AI Services et que vous avez projeté les résultats dans une base de connaissances, vous pouvez utiliser l’Explorateur Stockage ou d’autres applications pour explorer votre jeu de données enrichi.