Creación de un almacén de conocimiento mediante REST

En Azure AI Search, un almacén de conocimiento es un repositorio de contenido generado con IA que se usa para escenarios que no son de búsqueda. Cree el almacén de conocimiento mediante un indexador y un conjunto de aptitudes y especifique Azure Storage para almacenar la salida. Después de completar un almacén de conocimiento, use herramientas como el Explorador de Storage o Power BI para explorar el contenido.

En este artículo, usará la API REST para ingerir, enriquecer y explorar un conjunto de reseñas de clientes sobre estancias en hotel en un almacén de conocimiento. El almacén de conocimiento incluye contenido de texto original que se extrajo del origen, además de contenido generado por IA que incluye una puntuación de opinión, la extracción de frases clave, la detección del idioma y la traducción de texto de comentarios de clientes que no están en inglés.

Para que el conjunto de datos inicial esté disponible, las reseñas de hotel se importan primero a Azure Blob Storage. Después del procesamiento, los resultados se guardan como almacén de conocimiento en Azure Table Storage.

Sugerencia

Este artículo usa REST para las explicaciones detalladas de cada paso. Descargue el archivo REST si quiere solo ejecutar los comandos. Como alternativa, también puede crear un almacén de conocimientos en Azure Portal.

Requisitos previos

El conjunto de aptitudes de este ejemplo usa los Servicios de Azure AI para el enriquecimiento. Dado que la carga de trabajo es tan pequeña, los servicios de Azure AI se aprovechan en segundo plano para proporcionar el procesamiento gratuito de hasta 20 transacciones al día. Una carga de trabajo pequeña significa que puede omitir la creación o la asociación de un recurso multiservicio de Azure AI.

Carga de datos en Azure Storage y obtención de una cadena de conexión

  1. Descarga de HotelReviews_Free.csv. Este archivo CSV contiene 19 comentarios de usuario sobre un mismo hotel (procede de Kaggle.com).

  2. En Azure Portal, busque su cuenta de almacenamiento y use el Explorador de almacenamiento para crear un contenedor de blobs llamado hotel-reviews.

  3. Seleccione Cargar en la parte superior de la página para cargar el archivo HotelReviews-Free.csv que descargó del paso anterior.

    Screenshot of Storage Browser with uploaded file and left nav pane

  4. A la izquierda, seleccione Claves de acceso, seleccione Mostrar claves y después copie la cadena de conexión de key1 o key2. Una cadena de conexión de acceso completo tiene el formato siguiente:

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

Nota:

Consulte Conectarse usando una identidad administrada si no quiere proporcionar datos confidenciales en la cadena de conexión.

Copia de una clave y una dirección URL

En este ejemplo, las llamadas REST requieren el punto de conexión del servicio de búsqueda y usan una clave API en cada solicitud. Puede obtener estos valores en Azure Portal.

  1. En Azure Portal, inicie sesión, vaya a la página Información general y copie la dirección URL. Un punto de conexión de ejemplo podría ser similar a https://mydemo.search.windows.net.

  2. En Configuración>Claves, copie una clave de administrador. Las claves de administrador se utilizan para agregar, modificar y eliminar objetos. Hay dos claves de administrador intercambiables. Copie una de las dos.

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

Una clave de API válida genera la confianza, solicitud a solicitud, entre la aplicación que la envía y el servicio que se encarga de ella.

Creación de un índice

Crear índice (REST) crea un índice de búsqueda en el servicio de búsqueda. Un índice de búsqueda no está relacionado con un almacén de conocimiento, pero el indexador requiere uno. El índice de búsqueda tiene el mismo contenido que el almacén de conocimiento, que puede explorar mediante el envío de solicitudes de consulta.

  1. Abra un nuevo archivo de texto en Visual Studio Code.

  2. Establezca variables en el punto de conexión de búsqueda y la clave de API que recopiló anteriormente.

    @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. Guarde el archivo con una extensión de archivo .rest.

  4. Pegue el ejemplo siguiente para crear la solicitud de índice.

    ### 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. Seleccione Enviar solicitud. Debe tener una respuesta HTTP/1.1 201 Created y el cuerpo de la respuesta debe incluir la representación JSON del esquema de índice.

Creación de un origen de datos

Crear origen de datos crea una conexión de origen de datos en Búsqueda de Azure AI.

  1. Pegue el ejemplo siguiente para crear el origen de datos.

    ### 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. Seleccione Enviar solicitud.

Creación de un conjunto de aptitudes

Un conjunto de aptitudes define enriquecimientos (aptitudes) y su almacén de conocimiento. Crear conjunto de aptitudes crea el objeto en el servicio de búsqueda.

  1. Pegue el ejemplo siguiente para crear el conjunto de aptitudes.

    ### 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": []
                    }
                ]
            }
        }
    

Puntos clave:

  • La aptitud Conformador es importante para la definición del almacén de conocimientos. Especifica cómo fluyen los datos en las tablas del almacén de conocimiento. Las entradas son las partes del documento enriquecido que desea almacenar. La salida es una consolidación de los nodos en una sola estructura.

  • Las proyecciones especifican las tablas, objetos y blobs del almacén de conocimiento. Cada elemento de proyección especifica el "name" de columna o campo que se va a crear en Azure Storage. El "source" especifica qué parte de la salida del conformador se asigna a ese campo o columna.

Creación de un indexador

Crear indexador crea y ejecuta el indexador. La ejecución del indexador comienza descifrando los documentos, extrayendo texto e imágenes e inicializando el conjunto de aptitudes. El indexador comprueba los demás objetos que ha creado: el origen de datos, el índice y el conjunto de aptitudes.

  1. Pegue el ejemplo siguiente para crear el indexador.

    ### 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. Seleccione Enviar solicitud para crear y ejecutar el indexador. Este paso tarda varios minutos en completarse.

Puntos clave:

  • El objeto parameters/configuration controla cómo ingiere el indexador los datos. En este caso, los datos de entrada se encuentran en un único archivo .csv con una línea de encabezado y valores separados por comas.

  • Las asignaciones de campos crean "AzureSearch_DocumentKey", que es un identificador único para cada documento generado por el indexador de blobs (según la ruta de acceso del almacenamiento de metadatos).

  • Las asignaciones de campos de salida especifican cómo se asignan los campos enriquecidos a los campos de un índice de búsqueda. Las asignaciones de campos de salida no se usan en almacenes de conocimiento (los almacenes de conocimiento usan formas y proyecciones para expresar las estructuras de datos físicas).

Comprobar estado

Después de enviar cada solicitud, el servicio de búsqueda debe responder con un mensaje de confirmación 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}}

Después de varios minutos, puede consultar el índice para inspeccionar el contenido. Incluso si no usa el índice, este paso es una manera cómoda de confirmar que el conjunto de aptitudes produjo la salida esperada.

### 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
  }

Comprobación de tablas en Azure Portal

En Azure Portal, cambie a la cuenta de Azure Storage y use el explorador de almacenamiento para ver las nuevas tablas. Debería ver seis tablas, una para cada proyección definida en el conjunto de aptitudes.

Cada tabla se genera con los identificadores necesarios para la vinculación cruzada de las tablas en las consultas. Al abrir una tabla, desplácese más allá de estos campos para ver los campos de contenido que ha agregado la canalización.

Screenshot of the knowledge store tables in Storage Browser

En este tutorial, el almacén de conocimiento se compone de varias tablas que muestran diferentes maneras de formar y estructurar una tabla. De la tabla uno a la tabla tres se usa la salida de una aptitud de conformador para determinar las columnas y filas. Las tablas cuatro, cinco y seis están creadas a partir de instrucciones de modelado insertado, integradas dentro de la propia proyección. Puede usar cualquiera de los enfoques para lograr el mismo resultado.

Tabla Descripción
hotelReviews1Document Contiene campos que trasladan desde el archivo CSV, como reviews_date y reviews_text.
hotelReviews2Pages Contiene campos enriquecidos creados por el conjunto de aptitudes, como la puntuación de opinión y el texto traducido.
hotelReviews3KeyPhrases Contiene una larga lista con solo las frases clave.
hotelReviews4InlineProjectionDocument Alternativa a la primera tabla, mediante el modelado insertado, en lugar de la aptitud de conformador para dar forma a los datos de la proyección.
hotelReviews5InlineProjectionPages Alternativa a la segunda tabla, mediante el modelado insertado.
hotelreviews6InlineProjectionKeyPhrases Alternativa a la tercera tabla, mediante el modelado insertado.

Limpieza

Cuando trabaje con su propia suscripción, es una buena idea al final de un proyecto identificar si todavía se necesitan los recursos que ha creado. Los recursos que se dejan en ejecución pueden costarle mucho dinero. Puede eliminar los recursos de forma individual o eliminar el grupo de recursos para eliminar todo el conjunto de recursos.

Puede encontrar y administrar recursos en el portal, mediante el vínculo Todos los recursos o Grupos de recursos en el panel de navegación izquierdo.

Pasos siguientes

Ahora que ha enriquecido los datos con los servicios de Azure AI y ha proyectado los resultados en un almacén de conocimiento, puede usar el Explorador de Storage u otras aplicaciones para explorar el conjunto de datos enriquecido.