使用 REST 建立知識存放區

在 Azure AI 搜尋中,知識存放區是 AI 產生的內容存放庫,用於非搜尋案例。 您可以使用索引器和技能集建立知識存放區,並指定 Azure 儲存體 來儲存輸出。 填入知識存放區之後,請使用 儲存體總管Power BI 之類的工具來探索內容。

在本文中,您會使用 REST API 來擷取、豐富和探索一組客戶對旅館停留在知識存放區中的評論。 知識存放區包含從來源提取的原始文字內容,加上 AI 產生的內容,其中包含情感分數、關鍵片語擷取、語言偵測,以及非英文客戶批注的文字翻譯。

若要讓初始數據集可供使用,酒店評論會先匯入 Azure Blob 儲存體。 後續處理后,結果會儲存為 Azure 數據表中的知識存放區 儲存體。

提示

本文會使用 REST 來取得每個步驟的詳細說明。 如果您想要執行命令,請下載 REST 檔案 。 或者,您也可以在 Azure 入口網站 中建立知識存放區。

必要條件

此範例中的技能集會使用 Azure AI 服務進行擴充。 因為工作負載太小了,所以 Azure AI 服務會在幕後點選,每天最多 20 筆交易提供免費處理。 小型工作負載表示您可以略過建立或連結 Azure AI 多服務資源。

將數據上傳至 Azure 儲存體 並取得 連接字串

  1. 下載HotelReviews_Free.csv。 此 CSV 包含 19 份關於單一酒店的客戶意見反應(源自 Kaggle.com)。

  2. 在 Azure 入口網站 中,尋找您的記憶體帳戶,並使用 儲存體 Browser 來建立名為 hotel-reviews 的 Blob 容器。

  3. 選取 頁面頂端的 [上傳 ],以載入 您從上一個步驟下載的HotelReviews-Free.csv 檔案。

    Screenshot of Storage Browser with uploaded file and left nav pane

  4. 在左側,選取 [存取密鑰],選取 [顯示密鑰],然後複製 key1 或 key2 的 連接字串。 完整存取 連接字串 具有下列格式:

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

注意

如果您不想在 連接字串 上提供敏感數據,請參閱使用受控識別 連線。

複製金鑰和 URL

在此範例中,REST 呼叫需要搜尋服務端點,並在每個要求上使用 API 金鑰。 您可以從 Azure 入口網站 取得這些值。

  1. 登入 Azure 入口網站,流覽至 [概觀] 頁面,然後複製 URL。 範例端點看起來可能像 https://mydemo.search.windows.net

  2. 在 [設定> Keys] 底下,複製管理密鑰。 管理員 索引鍵可用來新增、修改和刪除物件。 有兩個可交換的系統管理密鑰。 複製任一個。

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

有效的 API 金鑰會根據每個要求,在傳送要求的應用程式與處理要求的搜尋服務之間建立信任。

建立索引

建立索引 (REST) 會在搜尋服務上建立搜尋索引。 搜尋索引與知識存放區無關,但索引器需要一個。 搜尋索引包含與知識存放區相同的內容,您可以藉由傳送查詢要求來探索。

  1. 在 Visual Studio Code 中開啟新的文字檔。

  2. 將變數設定為您稍早收集的搜尋端點和 API 金鑰。

    @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. 以擴展名儲存 .rest 盤案。

  4. 貼上下列範例以建立索引要求。

    ### 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. 選取 [ 傳送要求]。 您應該有 HTTP/1.1 201 Created 回應,而響應主體應該包含索引架構的 JSON 表示法。

建立資料來源

建立數據源 會在 Azure AI 搜尋上建立數據源連線。

  1. 貼上下列範例以建立數據源。

    ### 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. 選取 [ 傳送要求]。

建立技能集

技能集會定義擴充(技能)和您的知識存放區。 建立 Skillset 會在您的搜尋服務上建立 物件。

  1. 貼上下列範例以建立技能集。

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

重點︰

  • Shaper 技能 對於知識存放區定義很重要。 它會指定數據如何流入知識存放區的數據表。 輸入是您想要儲存之擴充檔的各個部分。 輸出是將節點合併成單一結構。

  • 投影會指定知識存放區的數據表、物件和 Blob。 每個投影專案會"name"指定要在 Azure 儲存體 中建立的數據行或欄位。 "source"指定將圖形器輸出的哪個部分指派給該欄位或數據行。

建立索引子

建立索引器 會建立並執行索引器。 索引器執行首先會破解檔、擷取文字和影像,以及初始化技能集。 索引器會檢查您所建立的其他對象:數據源、索引和技能集。

  1. 貼上下列範例以建立索引器。

    ### 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. 選取 [ 傳送要求 ] 以建立並執行索引器。 此步驟需要幾分鐘的時間才能完成。

重點︰

  • 物件 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=2023-11-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-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
  }

檢查 Azure 入口網站 中的數據表

在 Azure 入口網站 中,切換至您的 Azure 儲存體 帳戶,並使用 儲存體 Browser 來檢視新的數據表。 您應該會看到六個數據表,其中一個用於技能集中定義的每個投影。

每個數據表都會以在查詢中交叉鏈接數據表所需的標識碼產生。 當您開啟數據表時,卷動超過這些欄位以檢視管線新增的內容欄位。

Screenshot of the knowledge store tables in Storage Browser

在本逐步解說中,知識存放區是由各種數據表所組成,其中顯示不同方式的成形和建構數據表。 數據表一到三會使用 Shaper 技能的輸出來判斷數據行和數據列。 表格四到六是從內嵌成形指令建立,內嵌在投影本身內。 您可以使用這兩種方法來達成相同的結果。

資料表 Description
hotelReviews1Document 包含從 CSV 轉送的欄位,例如reviews_date和reviews_text。
hotelReviews2Pages 包含技能集所建立的擴充字段,例如情感分數和翻譯文字。
hotelReviews3KeyPhrases 只包含關鍵片語的完整清單。
hotelReviews4InlineProjectionDocument 第一個表格的替代方案,使用內嵌成形,而不是使用Shaper技能來塑造投影的數據。
hotelReviews5InlineProjectionPages 使用內嵌成形來替代第二個數據表。
hotelreviews6InlineProjectionKeyPhrases 使用內嵌成形來替代第三個數據表。

清理

如果您是在自己的訂用帳戶中進行,建議您在專案結束時判斷自己是否仍需要先前所建立的資源。 資源若繼續執行,將需付費。 您可以個別刪除資源,或刪除資源群組以刪除整組資源。

您可以使用左側瀏覽窗格中的 [ 所有資源 ] 或 [資源群組 ] 連結,在入口網站中找到和管理資源。

下一步

既然您已使用 Azure AI 服務擴充數據,並將結果投影到知識存放區,您可以使用 儲存體總管 或其他應用程式來探索擴充的數據集。