Создание хранилища знаний с помощью REST

Примечание.

Хранилища знаний представляют собой вторичное хранилище, которое существует в служба хранилища Azure и содержит выходные данные из наборов умений Поиск с использованием ИИ Azure. Они отделены от источников знаний и баз знаний, которые используются в рабочих процессах агентного извлечения.

В Поиск с использованием ИИ Azure хранилище знаний — это репозиторий содержимого, созданного навыками, который используется для сценариев не связанных с поиском. Вы создаете хранилище знаний с помощью индексатора и набора навыков и задаете служба хранилища Azure для хранения выходных данных. После заполнения хранилища знаний используйте такие средства, как Обозреватель службы хранилища или Power BI для изучения содержимого.

В этой статье вы используете REST API для приема, обогащения и изучения набора отзывов клиентов о пребывании в магазине знаний. Хранилище знаний содержит исходное текстовое содержимое, полученное из источника, а также содержимое, созданное СИ, которое включает оценку тональности, извлечение ключевых фраз, обнаружение языка и перевод комментариев клиентов, отличных от английского языка.

Чтобы сделать исходный набор данных доступным, отзывы о отелях сначала импортируются в Хранилище BLOB-объектов Azure. После обработки результаты сохраняются в качестве базы знаний в сервисе Azure Table Storage.

Совет

В этой статье используется REST для подробных объяснений каждого шага. Скачайте REST-файл, если вы хотите просто выполнить команды.

Предварительные требования

Набор навыков в этом примере использует средства Foundry для обогащения. Поскольку рабочая нагрузка настолько мала, средства Foundry Tools задействуются в фоновом режиме для обеспечения бесплатной обработки до 20 транзакций ежедневно. Небольшая рабочая нагрузка означает, что вы можете пропустить создание или присоединение ресурса Microsoft Foundry.

Загрузите данные в служба хранилища Azure и получите строку подключения

  1. Скачайте HotelReviews_data.csv. Этот CSV-файл содержит 19 частей отзывов клиентов об одном отеле (происходит из Kaggle.com).

  2. В Azure portal найдите учетную запись storage и используйте браузер Storage для создания контейнера BLOB-объектов с именем hotel-reviews.

  3. Выберите "Отправить" в верхней части страницы, чтобы загрузить файлHotelReviews_data.csv , скачанный на предыдущем шаге.

    Снимок экрана браузера хранилища с загруженным файлом и левой панелью навигации

  4. Слева выберите Access Keys, выберите Show Keys, и скопируйте строку подключения для key1 или key2. Строка подключения для полного доступа имеет следующий формат:

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

Примечание.

Ознакомьтесь с разделом Подключение с помощью управляемого удостоверения, если вы предпочитаете не указывать конфиденциальные данные в строке подключения.

Копирование ключа и URL-адреса

В этом примере вызовы REST требуют конечную точку поисковой службы и используют ключ API при каждом запросе. Эти значения можно получить из Azure portal.

  1. Перейдите в службу поиска в портал Azure.

  2. На странице обзора скопируйте URL-адрес конечной точки. Пример конечной точки может выглядеть как https://mydemo.search.windows.net.

  3. В разделе "Ключи> параметров" скопируйте ключ администратора. Ключи администратора используются для добавления, изменения и удаления объектов. Существует два взаимозаменяемых ключа администратора. Скопируйте любой из них.

    Снимок экрана URL-адреса и ключей API в портале Azure.

Допустимый ключ API устанавливает доверие между приложением, посылающим запрос, и службой поиска, обрабатывающей его, на основе каждого отдельного запроса.

Создание индекса

Create Index (REST) создает индекс поиска в search service. Индекс поиска не связан с хранилищем знаний, но индексатору требуется один. Индекс поиска содержит то же содержимое, что и хранилище знаний, которое можно исследовать, отправляя запросы.

  1. Откройте новый текстовый файл в коде Visual Studio.

  2. Задайте переменные в конечную точку поиска и ключ API, собранный ранее.

    @baseUrl = PUT-YOUR-SEARCH-SERVICE-URL-HERE
    @apiKey = PUT-YOUR-ADMIN-API-KEY-HERE
     @storageConnectionString = PUT-YOUR-STORAGE-CONNECTION-STRING-HERE
    @blobContainer = PUT-YOUR-CONTAINER-NAME-HERE (hotel-reviews)
    
  3. Сохраните файл с расширением .rest файла.

  4. Вставьте следующий пример, чтобы создать запрос индекса.

    ### Create a new index
    POST {{baseUrl}}/indexes?api-version=2025-09-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. Щелкните Отправить запрос. У вас должен быть ответ HTTP/1.1 201 Created, а текст ответа должен содержать JSON представление схемы индекса.

Создание источника данных

Create Data Source создает подключение к источнику данных на Поиск с использованием ИИ Azure.

  1. Вставьте приведённый ниже пример, чтобы создать источник данных.

    ### Create a data source
    POST {{baseUrl}}/datasources?api-version=2025-09-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. Щелкните Отправить запрос.

Создание набора навыков

Набор навыков определяет обогащения (навыки) и хранилище знаний. Create Skillset создает объект в вашей поисковой службе.

  1. Вставьте следующий пример, чтобы создать набор навыков.

    ### Create a skillset
    POST {{baseUrl}}/skillsets?api-version=2025-09-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": []
                    }
                ]
            }
        }
    

Основные моменты:

  • Навык Shaper важен для конфигурации хранилища знаний. Он указывает, как данные передаются в таблицы хранилища знаний. Входные данные — это части обогащенного документа, который требуется сохранить. Выходные данные — это консолидация узлов в одну структуру.

  • Проекции указывают таблицы, объекты и BLOB'ы базы знаний. Каждый элемент проекции определяет "name" столбца или поля, который необходимо создать в служба хранилища Azure. Указатель "source" определяет, какая часть выходных данных фигуратора назначается данному полю или столбцу.

Создать индексатор

Функция Create Indexer создает и запускает индексатор. Выполнение индексатора начинается с взлома документов, извлечения текста и изображений и инициализации набора навыков. Индексатор проверяет наличие других созданных объектов: источника данных, индекса и набора навыков.

  1. Вставьте следующий пример и создайте индексатор.

    ### Create indexer
    POST {{baseUrl}}/indexers?api-version=2025-09-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. Выберите "Отправить запрос" , чтобы создать и запустить индексатор. Этот шаг занимает несколько минут.

Основные моменты:

  • Объект parameters/configuration управляет процессом приема данных индексатором. В этом примере входные данные находятся в одном CSV-файле со строкой заголовка и значениями, разделенными запятыми.

  • Сопоставление полей для AzureSearch_DocumentKey создает уникальный идентификатор для каждого документа, созданного индексатором BLOB (на основе пути хранения метаданных).

  • Сопоставления полей выходных данных определяют, как обогащенные поля сопоставляются с полями в индексе поиска. Сопоставления полей выходных данных не используются в хранилищах знаний (хранилища знаний используют фигуры и проекции для выражения структур физических данных).

Проверить состояние

После отправки каждого запроса поисковая служба должна ответить сообщением о успешном выполнении с кодом 201.

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

Через несколько минут можно запросить индекс для проверки содержимого. Даже если вы не используете индекс, этот шаг является удобным способом подтвердить, что набор навыков создал ожидаемые выходные данные.

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

Проверка таблиц в Azure portal

В Azure portal перейдите в учетную запись служба хранилища Azure и используйте браузер Storage для просмотра новых таблиц. Должны отобразиться шесть таблиц, каждая из которых соответствует одной из проекций, определенных в наборе умений.

Каждая таблица создается с идентификаторами, необходимыми для перекрестного связывания таблиц в запросах. При открытии таблицы прокрутите мимо этих полей, чтобы просмотреть содержательные поля, добавленные конвейером.

Скриншот таблиц хранилища данных знаний в Storage Browser

В этом пошаговом руководстве хранилище знаний состоит из различных таблиц, демонстрирующих различные способы формирования и структурирования данных. Таблицы один, два и три используют выходные данные из навыка Shaper для определения столбцов и строк. Таблицы с четвертой по шестую создаются из встроенных формовочных инструкций, внедренных в саму проекцию. Для достижения того же результата можно использовать любой из этих подходов.

Таблица Описание
hotelReviews1Document Содержит поля, перенесенные из CSV-файла, такие как reviews_date и reviews_text.
hotelReviews2Pages Содержит обогащенные поля, созданные набором навыков, например поля оценки тональности и переведенного текста.
hotelReviews3KeyPhrases Содержит длинный список только ключевых фраз.
hotelReviews4InlineProjectionDocument Альтернатива первой таблице, использующая встроенное формирование вместо инструмента Shaper для подготовки данных для проекции.
hotelReviews5InlineProjectionPages Альтернатива для второй таблицы с использованием встроенной формы.
hotelReviews6InlineProjectionKeyPhrases Альтернатива третьей таблице с использованием встроенного формирования.

Очистка

Когда вы работаете в собственной подписке, хорошей идеей будет в конце проекта определить, нужны ли вам всё ещё созданные ресурсы. Ресурсы, оставленные запущенными, могут привести к лишним расходам. Вы можете удалить ресурсы по отдельности либо удалить всю группу ресурсов.

Ресурсы Azure portal можно найти и управлять ими, используя ссылку All resources или Resource groups на панели навигации слева.

Следующие шаги

Теперь, когда вы обогатили данные с помощью средств Foundry и проецировали результаты в хранилище знаний, вы можете использовать Обозреватель службы хранилища или другие приложения для изучения обогащенного набора данных.