分享方式:


使用 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 入口網站中,尋找您的儲存體帳戶,並使用儲存體瀏覽器建立名為 hotel-reviews 的 Blob 容器。

  3. 請選取頁面頂端的 [上傳],載入在上個步驟所下載的 HotelReviews-Free.csv 檔案。

    儲存體瀏覽器的螢幕擷取畫面,其中包含上傳的檔案和左側的瀏覽窗格

  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. 在 [設定 > 金鑰] 下面,複製系統管理金鑰。 系統管理金鑰可用來新增、修改和刪除物件。 有兩個可交換的系統管理密鑰。 複製任一個。

    Azure 入口網站中 URL 和 API 金鑰的螢幕擷取畫面。

有效的 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=2024-07-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=2024-07-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. 選取 [傳送要求]

建立技能集

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

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

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

重點︰

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

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

建立索引子

建立索引子會建立並執行索引子。 索引子執行首先會萃取文件、擷取文字和影像,以及初始化技能。 索引子會檢查您所建立的其他物件:資料來源、索引和技能。

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

    ### Create indexer
    POST {{baseUrl}}/indexers?api-version=2024-07-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=2024-07-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=2024-07-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 儲存體帳戶,並使用儲存體瀏覽器來檢視新的資料表。 您應當會看到六份資料表,在技能集中定義的每個投影各有一份。

每份資料表產生時都附有在查詢中交叉連結資料表時所需的識別碼。 當您開啟資料表時,請捲動這些欄位以檢視由管線新增的內容欄位。

儲存體瀏覽器中知識存放區資料表的螢幕擷取畫面

本次逐步解說之中,知識存放區是由各種資料表所組成,示範資料表不同的塑形和建構方式。 第一到三份資料表會使用塑形器技能的輸出內容來判斷資料行和資料列。 資料表四到六是以內嵌的塑形指令所建立,內嵌在投影本身。 使用任一種方法皆可達成相同的結果。

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

清理

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

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

下一步

既然您已經使用 Azure AI 服務擴充資料,並將結果投射到知識存放區,接下來即可使用儲存體總管或其它應用程式來探索擴充的資料集。