快速入門:QnA Maker 用戶端程式庫

開始使用 QnA Maker 用戶端程式庫。 請遵循下列步驟來安裝套件,並試用基本工作的程式碼範例。

注意

QnA Maker 服務將于 2025 年 3 月 31 日淘汰。 新版的問題和解答功能現在可做為 適用于語言的 Azure 認知服務一部分使用。 如需瞭解語言服務內的問題解答功能,請參閱問題解答。 從 2022 年 10 月 1 日開始,您將無法建立新的 QnA Maker 資源。 如需將現有 QnA Maker 知識庫移轉至問題解答的資訊,請參閱 移轉指南

必要條件

注意

本文件不適用於最新版本。 若要了解如何搭配使用 REST API 與最新版本,請參閱 REST API 問題解答快速入門

  • 最新版的 cURL。 快速入門會使用數個命令列參數,其記載於 cURL 文件中。

  • 您必須擁有 QnA Maker 資源,才能使用金鑰和資源名稱。 您已在資源建立期間輸入資源名稱,接下來系統會為您建立金鑰。 資源名稱會用來作為端點的子網域。 若要擷取您的金鑰和資源名稱,請在 Azure 入口網站中針對您的資源選取 [快速入門] 。 資源名稱是端點 URL 的第一個子網域:

    https://YOUR-RESOURCE-NAME.cognitiveservices.azure.com/qnamaker/v4.0

警告

下列 BASH 範例會使用 \ 行接續字元。 如果您的主控台或終端機使用不同的行接續字元,請使用此字元。

建立知識庫

若要使用 REST API 和 cURL 建立知識庫,您需要有下列資訊:

資訊 cURL 組態 目的
QnA Maker 資源名稱 URL 用於建構 URL
QnA Maker 資源金鑰 Ocp-Apim-Subscription-Key 標頭的 -h 參數 驗證 QnA Maker 服務
描述知識庫的 JSON -d 參數 JSON 的範例
JSON 的大小 (以位元組為單位) Content-Size 標頭的 -h 參數

cURL 命令是從 BASH 殼層執行。 使用您自己的資源名稱、資源金鑰,以及 JSON 值和 JSON 大小來編輯此命令。

curl https://REPLACE-WITH-YOUR-RESOURCE-NAME.cognitiveservices.azure.com/qnamaker/v4.0/knowledgebases/create \
-X POST \
-H "Ocp-Apim-Subscription-Key: REPLACE-WITH-YOUR-RESOURCE-KEY" \
-H "Content-Type:application/json" \
-H "Content-Size:107" \
-d '{ name: "QnA Maker FAQ",urls: [ "https://docs.microsoft.com/en-in/azure/cognitive-services/qnamaker/faqs"]}'

來自 QnA Maker 的 cURL 回應包含 operationId,這是取得作業狀態所需的項目。

{
  "operationState": "NotStarted",
  "createdTimestamp": "2020-02-27T04:11:22Z",
  "lastActionTimestamp": "2020-02-27T04:11:22Z",
  "userId": "9596077b3e0441eb93d5080d6a15c64b",
  "operationId": "95a4f700-9899-4c98-bda8-5449af9faef8"
}

取得作業的狀態

當您建立知識庫時,因為作業為非同步,回應會包含用以判斷狀態的資訊。

資訊 cURL 組態 目的
QnA Maker 資源名稱 URL 用於建構 URL
作業識別碼 URL 路由 /operations/REPLACE-WITH-YOUR-OPERATION-ID
QnA Maker 資源金鑰 Ocp-Apim-Subscription-Key 標頭的 -h 參數 驗證 QnA Maker 服務

cURL 命令是從 BASH 殼層執行。 使用您自己的資源名稱、資源金鑰和作業識別碼來編輯此命令。

curl https://REPLACE-WITH-YOUR-RESOURCE-NAME.cognitiveservices.azure.com/qnamaker/v4.0/operations/REPLACE-WITH-YOUR-OPERATION-ID \
-X GET \
-H "Ocp-Apim-Subscription-Key: REPLACE-WITH-YOUR-RESOURCE-KEY"

cURL 回應包含狀態。 如果作業狀態為成功,則 resourceLocation 包含知識庫識別碼。

{
   "operationState": "Succeeded",
   "createdTimestamp": "2020-02-27T04:54:07Z",
   "lastActionTimestamp": "2020-02-27T04:54:19Z",
   "resourceLocation": "/knowledgebases/fe3971b7-cfaa-41fa-8d9f-6ceb673eb865",
   "userId": "f596077b3e0441eb93d5080d6a15c64b",
   "operationId": "f293f218-d080-48f0-a766-47993e9b26a8"
}

發佈知識庫

查詢知識庫之前,您必須:

  • 發佈知識庫
  • 取得執行階段端點金鑰

此工作會發佈知識庫。 取得執行階段端點金鑰是個別的工作

資訊 cURL 組態 目的
QnA Maker 資源名稱 URL 用於建構 URL
QnA Maker 資源金鑰 Ocp-Apim-Subscription-Key 標頭的 -h 參數 驗證 QnA Maker 服務
知識庫識別碼 URL 路由 /knowledgebases/REPLACE-WITH-YOUR-KNOWLEDGE-BASE-ID

cURL 命令是從 BASH 殼層執行。 使用您自己的資源名稱、資源金鑰和知識庫識別碼來編輯此命令。

curl https://REPLACE-WITH-YOUR-RESOURCE-NAME.cognitiveservices.azure.com/qnamaker/v4.0/knowledgebases/REPLACE-WITH-YOUR-KNOWLEDGE-BASE-ID \
-v \
-X POST \
-H "Ocp-Apim-Subscription-Key: REPLACE-WITH-YOUR-RESOURCE-KEY" \
--data-raw ''

回應狀態為 204,沒有任何結果。 使用 -v 命令列參數來查看 cURL 命令的詳細資訊輸出。 這會包含 HTTP 狀態。

取得已發佈知識庫的執行階段端點金鑰

查詢知識庫之前,您必須:

  • 發佈知識庫
  • 取得執行階段端點金鑰

此工作會取得執行階段端點金鑰。 發佈知識庫是個別的工作

執行階段端點金鑰適用於使用 QnA Maker 資源的所有知識庫。

資訊 cURL 組態 目的
QnA Maker 資源名稱 URL 用於建構 URL
QnA Maker 資源金鑰 Ocp-Apim-Subscription-Key 標頭的 -h 參數 驗證 QnA Maker 服務

cURL 命令是從 BASH 殼層執行。 使用您自己的資源名稱、資源金鑰來編輯此命令。

curl https://REPLACE-WITH-YOUR-RESOURCE-NAME.cognitiveservices.azure.com/qnamaker/v4.0/endpointkeys \
-X GET \
-H "Ocp-Apim-Subscription-Key: REPLACE-WITH-YOUR-RESOURCE-KEY"

cURL 回應包含執行階段端點金鑰。 查詢時只要使用其中一個金鑰,即可從知識庫取得答案。

{
  "primaryEndpointKey": "93e88a14-694a-44d5-883b-184a68aa8530",
  "secondaryEndpointKey": "92c98c16-ca31-4294-8626-6c57454a5063",
  "installedVersion": "4.0.5",
  "lastStableVersion": "4.0.6"
}

從已發佈的知識庫查詢答案

從知識庫取得答案是從個別的執行階段完成,而不是管理知識庫。 因為這是個別的執行時間,所以您必須使用執行階段金鑰進行驗證。

資訊 cURL 組態 目的
QnA Maker 資源名稱 URL 用於建構 URL
QnA Maker 執行階段金鑰 Authorization 標頭的 -h 參數 金鑰是字串的一部分,其中包含 Endpointkey 這個字。 驗證 QnA Maker 服務
知識庫識別碼 URL 路由 /knowledgebases/REPLACE-WITH-YOUR-KNOWLEDGE-BASE-ID
描述查詢的 JSON -d 參數 JSON 的要求本文參數範例
JSON 的大小 (以位元組為單位) Content-Size 標頭的 -h 參數

cURL 命令是從 BASH 殼層執行。 使用您自己的資源名稱、資源金鑰和知識庫識別碼來編輯此命令。

curl https://REPLACE-WITH-YOUR-RESOURCE-NAME.azurewebsites.net/qnamaker/knowledgebases/REPLACE-WITH-YOUR-KNOWLEDGE-BASE-ID/generateAnswer \
-X POST \
-H "Authorization: EndpointKey REPLACE-WITH-YOUR-RUNTIME-KEY" \
-H "Content-Type:application/json" \
-H "Content-Size:159" \
-d '{"question": "How are QnA Maker and LUIS used together?","top": 6,"isTest": true,  "scoreThreshold": 20, "strictFilters": [], "userId": "sd53lsY="}'

成功的回應包括最佳答案,以及用戶端應用程式 (例如聊天 Bot) 向使用者顯示答案所需的其他資訊。

刪除知識庫

知識庫使用完畢後,請加以刪除。

資訊 cURL 組態 目的
QnA Maker 資源名稱 URL 用於建構 URL
QnA Maker 資源金鑰 Ocp-Apim-Subscription-Key 標頭的 -h 參數 驗證 QnA Maker 服務
知識庫識別碼 URL 路由 /knowledgebases/REPLACE-WITH-YOUR-KNOWLEDGE-BASE-ID

cURL 命令是從 BASH 殼層執行。 使用您自己的資源名稱、資源金鑰和知識庫識別碼來編輯此命令。

curl https://REPLACE-WITH-YOUR-RESOURCE-NAME.cognitiveservices.azure.com/qnamaker/v4.0/knowledgebases/REPLACE-WITH-YOUR-KNOWLEDGE-BASE-ID \
-X DELETE \
-v \
-H "Ocp-Apim-Subscription-Key: REPLACE-WITH-YOUR-RESOURCE-KEY"

回應狀態為 204,沒有任何結果。 使用 -v 命令列參數來查看 cURL 命令的詳細資訊輸出。 這會包含 HTTP 狀態。

其他資源

使用適用於 .NET 的 QnA Maker 用戶端程式庫來:

  • 建立知識庫
  • 更新知識庫
  • 發佈知識庫
  • 取得預測執行階段端點金鑰
  • 等候長時間執行的工作
  • 下載知識庫
  • 從知識庫取得答案
  • 刪除知識庫

參考文件 | 程式庫原始程式碼 | 套件 (NuGet) | C# 範例

注意

2019 年 7 月 1 日之後建立的新資源會使用自訂的子網域名稱。 如需詳細資訊和完整的區域端點清單,請參閱認知服務的自訂子網域名稱

必要條件

注意

本文件不適用於最新版本。 若要了解如何搭配使用 C# API 與最新版本,請參閱 C# API 問題解答快速入門

  • Azure 訂用帳戶 - 建立免費帳戶
  • Visual Studio IDE 或目前版本的 .NET Core
  • 擁有 Azure 訂用帳戶之後,請在 Azure 入口網站中建立 QnA Maker 資源,以取得您的撰寫金鑰和資源名稱。 在其部署後,選取 [前往資源]。
    • 您需要來自所建立資源的金鑰和資源名稱,以將應用程式連線至 QnA Maker API。 稍後會在快速入門中將金鑰和資源名稱貼到下列程式碼中。
    • 您可以使用免費定價層 (F0) 來試用服務,之後可升級至付費層以用於實際執行環境。

設定

CLI

在主控台視窗中 (例如 cmd、PowerShell 或 Bash),使用 dotnet new 命令建立名為 qna-maker-quickstart 的新主控台應用程式。 此命令會建立簡單的 "Hello World" C# 專案,內含單一原始程式檔:program.cs

dotnet new console -n qna-maker-quickstart

將目錄變更為新建立的應用程式資料夾。 您可以使用下列命令來建置應用程式:

dotnet build

建置輸出應該不會有警告或錯誤。

...
Build succeeded.
 0 Warning(s)
 0 Error(s)
...

在應用程式目錄中,使用下列命令安裝適用於 .NET 的 QnA Maker 用戶端程式庫:

dotnet add package Microsoft.Azure.CognitiveServices.Knowledge.QnAMaker --version 2.0.1

提示

想要立刻檢視整個快速入門程式碼檔案嗎? 您可以在 GitHub 上找到該檔案,其中包含本快速入門中的程式碼範例。

using 指示詞

從專案目錄中中開啟 program.cs 檔案,並新增下列 using 指示詞:

using Microsoft.Azure.CognitiveServices.Knowledge.QnAMaker;
using Microsoft.Azure.CognitiveServices.Knowledge.QnAMaker.Models;
using System;
using System.Collections.Generic;
using System.Threading.Tasks;

訂用帳戶金鑰和資源端點

在應用程式的 Main 方法中新增變數和程式碼 (如下列各節所示),以使用本快速入門中的一般工作。

  • 我們會交換使用訂用帳戶金鑰和撰寫金鑰。 如需撰寫金鑰的詳細資訊,請遵循 QnA Maker 中的金鑰

  • QNA_MAKER_ENDPOINT 的值具有 https://YOUR-RESOURCE-NAME.cognitiveservices.azure.com 格式。 移至 Azure 入口網站,並尋找您已在必要條件中建立的 QnA Maker 資源。 選取 [資源管理] 下的 [金鑰和端點] 頁面,以找出撰寫 (訂用帳戶) 金鑰和 QnA Maker 端點。

QnA Maker Authoring Endpoint

  • QNA_MAKER_RUNTIME_ENDPOINT 的值具有 https://YOUR-RESOURCE-NAME.azurewebsites.net 格式。 移至 Azure 入口網站,並尋找您已在必要條件中建立的 QnA Maker 資源。 選取 [自動化] 下的 [匯出範本] 頁面,以找出執行階段端點。

QnA Maker Runtime Endpoint

  • 在生產環境中,請考慮使用安全的方式來儲存及存取您的認證。 例如,Azure Key Vault 可提供安全的金鑰儲存。
var authoringKey = "PASTE_YOUR_QNA_MAKER_AUTHORING_SUBSCRIPTION_KEY_HERE";
var authoringURL = "PASTE_YOUR_QNA_MAKER_AUTHORING_ENDPOINT_HERE";
var queryingURL = "PASTE_YOUR_QNA_MAKER_RUNTIME_ENDPOINT_HERE";

物件模型

QnA Maker 使用兩種不同的物件模型:

  • QnAMakerClient 是用來建立、管理、發佈和下載知識庫的物件。
  • QnAMakerRuntime 是可讓您透過 GenerateAnswer API 查詢知識庫,並使用定型 API 傳送新的建議問題 (作為主動式學習的一部分) 的物件。

使用此範例知識庫

本快速入門中的知識庫起始於 2 個對話式 QnA 配對 (這是為了簡化範例,且在更新方法中有高度可預測的識別碼可供使用),且會將問題的後續提示與新的配對產生關聯。 這是本快速入門中的規劃作業,會依特定順序實作。

如果您日後要依據相依於現有 QnA 配對的後續提示來開發知識庫,您可以選擇:

  • 針對較大的知識庫,在支援自動化的文字編輯器或 TSV 工具中管理知識庫,然後立即將知識庫完全取代為更新。
  • 對於較小的知識庫,則完全在 QnA Maker 入口網站中管理後續提示。

本快速入門中使用的 QnA 配對詳細資料:

  • QnA 配對的類型 - 在更新之後,此知識庫中有 2 種類型的 QnA 配對:Chitchat 和網域專屬資訊。 這在繫結至交談應用程式 (例如聊天機器人) 的知識庫上很常見。
  • 雖然知識庫答案可以透過中繼資料進行篩選,或使用後續追蹤提示,但不在本快速入門的說明範圍中。 您可以在這裡找到不限定語言的 generateAnswer 範例。
  • 解答文字是 Markdown 格式,而且可以包含各式各樣的 Markdown,例如影像 (公開可用的網際網路影像)、連結 (公開可用的 URL) 和項目符號 (本快速入門不會用到此類型)。

QnAMakerClient 物件模型

製作 QnA Maker 用戶端是一種 QnAMakerClient 物件,會使用含有金鑰的 Microsoft.Rest.ServiceClientCredentials 向 Azure 進行驗證。

建立用戶端之後,請使用知識庫屬性來建立、管理和發佈知識庫。

藉由傳送 JSON 物件來管理知識庫。 針對立即性作業,方法通常會傳回可指出狀態的 JSON 物件。 針對長期作業,回應則是作業識別碼。 使用作業識別碼來呼叫 client.Operations.GetDetailsAsync 方法,以確定要求的狀態

QnAMakerRuntimeClient 物件模型

預測 QnA Maker 用戶端是一種 QnAMakerRuntimeClient 物件,會使用 Microsoft.Rest.ServiceClientCredentials 向 Azure 進行驗證,其中包含您的預測執行階段金鑰,這是在發佈知識庫後由製作用戶端呼叫 client.EndpointKeys.GetKeys 傳回的金鑰。

使用 GenerateAnswer 方法從查詢執行階段取得答案。

程式碼範例

這些程式碼片段會示範如何使用適用於 .NET 的 QnA Maker 用戶端程式庫來執行下列動作:

驗證用戶端以撰寫知識庫

使用您的金鑰將用戶端物件具現化,並將其與您的資源搭配使用以建構端點,繼而使用您的端點和金鑰建立 QnAMakerClient。 建立 ServiceClientCredentials 物件。

var client = new QnAMakerClient(new ApiKeyServiceClientCredentials(authoringKey))
{ Endpoint = authoringURL };

建立知識庫

知識庫會針對來自三個來源的 CreateKbDTO 物件儲存問題和答案組:

  • 針對編輯內容,請使用 QnADTO 物件。
    • 若要使用中繼資料和後續提示,請使用編輯內容,因為這項資料會在個別的 QnA 配對層級上新增。
  • 針對檔案,請使用 FileDTO 物件。 FileDTO 包含檔案名稱,以及用來觸達檔案的公用 URL。
  • 針對 URL,請使用字串清單來代表公開可用的 URL。

建立步驟也包含知識庫的屬性:

  • defaultAnswerUsedForExtraction - 找不到答案時會傳回的內容
  • enableHierarchicalExtraction - 自動在已擷取的 QnA 配對之間建立提示關聯性
  • language - 會在建立資源的第一個知識庫時,設定要在 Azure 搜尋服務索引中使用的語言。

請呼叫 CreateAsync 方法,然後將傳回的作業識別碼傳遞至 MonitorOperation 方法以輪詢狀態。

下列程式碼的最後一行會傳回來自 MonitorOperation 回應的知識庫識別碼。

private static async Task<string> CreateSampleKb(IQnAMakerClient client)
{
    var qna1 = new QnADTO
    {
        Answer = "Yes, You can use our [REST APIs](https://docs.microsoft.com/rest/api/cognitiveservices/qnamaker/knowledgebase) to manage your knowledge base.",
        Questions = new List<string> { "How do I manage my knowledgebase?" },
        Metadata = new List<MetadataDTO> {
            new MetadataDTO { Name = "Category", Value = "api" },
            new MetadataDTO { Name = "Language", Value = "REST" }
        },

    };

    var qna2 = new QnADTO
    {
        Answer = "Yes, You can use our [.NET SDK](https://www.nuget.org/packages/Microsoft.Azure.CognitiveServices.Knowledge.QnAMaker) with the [.NET Reference Docs](https://docs.microsoft.com/dotnet/api/microsoft.azure.cognitiveservices.knowledge.qnamaker?view=azure-dotnet) to manage your knowledge base.",
        Questions = new List<string> { "Can I program with C#?" },
        Metadata = new List<MetadataDTO> {
            new MetadataDTO { Name = "Category", Value = "api" },
            new MetadataDTO { Name = "Language", Value = ".NET" }
        }
    };

    var file1 = new FileDTO
    {
        FileName = "myfile.tsv",
        FileUri = "https://mydomain/myfile.tsv"

    };

    var createKbDto = new CreateKbDTO
    {
        Name = "QnA Maker .NET SDK Quickstart",
        QnaList = new List<QnADTO> { qna1, qna2 },
        //Files = new List<FileDTO> { file1 }

    };

    var createOp = await client.Knowledgebase.CreateAsync(createKbDto);
    createOp = await MonitorOperation(client, createOp);

    return createOp.ResourceLocation.Replace("/knowledgebases/", string.Empty);
}

務必包含上述程式碼中參考的 MonitorOperation 函式,才能成功建立知識庫。

更新知識庫

若要更新知識庫,請將知識庫識別碼以及包含 addupdatedelete DTO 物件的 UpdatekbOperationDTO 傳遞至 UpdateAsync 方法。 使用 MonitorOperation 方法來判斷更新是否成功。

private static async Task UpdateKB(IQnAMakerClient client, string kbId)
{

    var urls = new List<string> {
        "https://docs.microsoft.com/azure/cognitive-services/QnAMaker/troubleshooting"
    };

    var updateOp = await client.Knowledgebase.UpdateAsync(kbId, new UpdateKbOperationDTO
    {
        // Create JSON of changes
        Add = new UpdateKbOperationDTOAdd
        {
            QnaList = new List<QnADTO> {
                new QnADTO {
                    Questions = new List<string> {
                        "bye",
                        "end",
                        "stop",
                        "quit",
                        "done"
                    },
                    Answer = "goodbye",
                    Metadata = new List<MetadataDTO> {
                        new MetadataDTO { Name = "Category", Value="Chitchat" },
                        new MetadataDTO { Name = "Chitchat", Value = "end" },
                    }
                },
                new QnADTO {
                    Questions = new List<string> {
                        "hello",
                        "hi",
                        "start"
                    },
                    Answer = "Hello, please select from the list of questions or enter a new question to continue.",
                    Metadata = new List<MetadataDTO> {
                        new MetadataDTO { Name = "Category", Value="Chitchat" },
                        new MetadataDTO { Name = "Chitchat", Value = "begin" }
                    },
                    Context = new QnADTOContext
                    {
                        IsContextOnly = false,
                        Prompts = new List<PromptDTO>
                        {
                            new PromptDTO
                            {
                                DisplayOrder =1,
                                DisplayText= "Use REST",
                                QnaId=1

                            },
                            new PromptDTO
                            {
                                DisplayOrder =2,
                                DisplayText= "Use .NET NuGet package",
                                QnaId=2

                            },
                        }
                    }
                },
            },
            Urls = urls
        },
        Update = null,
        Delete = null
    }); ;

    // Loop while operation is success
    updateOp = await MonitorOperation(client, updateOp);
}

務必包含上述程式碼中參考的 MonitorOperation 函數,才能成功更新知識庫。

下載知識庫

使用 DownloadAsync 方法將資料庫下載為 QnADocumentsDTO 的清單。 此做法不等同於 QnA Maker 入口網站從 [設定] 頁面進行的匯出作業,原因是此方法的結果並非檔案。

private static async Task DownloadKb(IQnAMakerClient client, string kbId)
{
    var kbData = await client.Knowledgebase.DownloadAsync(kbId, EnvironmentType.Prod);
    Console.WriteLine("KB Downloaded. It has {0} QnAs.", kbData.QnaDocuments.Count);

    // Do something meaningful with data
}

發佈知識庫

使用 PublishAsync 方法來發佈知識庫。 這會採用目前已儲存且已定型的模型 (可透過知識庫識別碼加以參考),並在端點加以發佈。 若要查詢您的知識庫,這將是必要步驟。

private static async Task PublishKb(IQnAMakerClient client, string kbId)
{
    await client.Knowledgebase.PublishAsync(kbId);
}

取得查詢執行階段金鑰

知識庫發佈後,您必須要有查詢執行階段金鑰才能查詢執行階段。 這不是用來建立原始用戶端物件的相同金鑰。

使用 EndpointKeys 方法取得 EndpointKeysDTO 類別。

使用物件中傳回的其中一個金鑰屬性來查詢知識庫。

private static async Task<String> GetQueryEndpointKey(IQnAMakerClient client)
{
    var endpointKeysObject = await client.EndpointKeys.GetKeysAsync();

    return endpointKeysObject.PrimaryEndpointKey;
}

必須要有執行階段金鑰才能查詢您的知識庫。

驗證執行階段以產生解答

建立 QnAMakerRuntimeClient 來查詢知識庫,以產生解答,或從主動式學習進行訓練。

var runtimeClient = new QnAMakerRuntimeClient(new EndpointKeyServiceClientCredentials(primaryQueryEndpointKey))
{ RuntimeEndpoint = queryingURL };

使用 QnAMakerRuntimeClient 進行下列動作:

  • 從知識庫取得答案
  • 將新的建議問題傳送至主動式學習的知識庫。

從知識庫產生答案

使用 RuntimeClient.GenerateAnswerAsync 方法從已發佈的知識庫產生答案。 此方法會接受知識庫識別碼和 QueryDTO。 存取 QueryDTO 的其他屬性 (例如TopContext),以在聊天機器人中使用。

private static async Task GenerateAnswer(IQnAMakerRuntimeClient runtimeClient, string kbId)
{
    var response = await runtimeClient.Runtime.GenerateAnswerAsync(kbId, new QueryDTO { Question = "How do I manage my knowledgebase?" });
    Console.WriteLine("Endpoint Response: {0}.", response.Answers[0].Answer);

    // Do something meaningful with answer
}

這是查詢知識庫的簡單範例。 若要了解進階查詢案例,請檢閱其他查詢範例

刪除知識庫

使用 DeleteAsync 方法搭配知識庫識別碼的參數來刪除知識庫。

private static async Task DeleteKB(IQnAMakerClient client, string kbId)
{
    await client.Knowledgebase.DeleteAsync(kbId);
}

取得作業的狀態

某些方法 (例如 create 和 update) 的時間很充裕,而不必等候程序完成,並傳回作業。 從要輪詢 (使用重試邏輯) 的作業使用作業識別碼來確定原始方法的狀態。

下列程式碼區塊中的迴圈和 Task.Delay 是用來模擬重試邏輯。 這些項目應該取代為您自己的重試邏輯。

private static async Task<Operation> MonitorOperation(IQnAMakerClient client, Operation operation)
{
    // Loop while operation is success
    for (int i = 0;
        i < 20 && (operation.OperationState == OperationStateType.NotStarted || operation.OperationState == OperationStateType.Running);
        i++)
    {
        Console.WriteLine("Waiting for operation: {0} to complete.", operation.OperationId);
        await Task.Delay(5000);
        operation = await client.Operations.GetDetailsAsync(operation.OperationId);
    }

    if (operation.OperationState != OperationStateType.Succeeded)
    {
        throw new Exception($"Operation {operation.OperationId} failed to completed.");
    }
    return operation;
}

執行應用程式

使用 dotnet run 命令,從您的應用程式目錄執行應用程式。

dotnet run

此範例的原始程式碼可以在 GitHub 上找到。

使用適用於 Node.js 的 QnA Maker 用戶端程式庫來:

  • 建立知識庫
  • 更新知識庫
  • 發佈知識庫
  • 取得預測執行階段端點金鑰
  • 等候長時間執行的工作
  • 下載知識庫
  • 從知識庫取得答案
  • 刪除知識庫

參考文件 | 程式庫原始程式碼 | 套件 (npm) | Node.js 範例

注意

2019 年 7 月 1 日之後建立的新資源會使用自訂的子網域名稱。 如需詳細資訊和完整的區域端點清單,請參閱認知服務的自訂子網域名稱

必要條件

  • Azure 訂用帳戶 - 建立免費帳戶
  • 最新版的 Node.js
  • 擁有 Azure 訂用帳戶之後,請在 Azure 入口網站中建立 QnA Maker 資源,以取得您的撰寫金鑰和資源。 在其部署後,選取 [前往資源]。
    • 您需要來自所建立資源的金鑰和資源名稱,以將應用程式連線至 QnA Maker API。 稍後會在快速入門中將金鑰和資源名稱貼到下列程式碼中。
    • 您可以使用免費定價層 (F0) 來試用服務,之後可升級至付費層以用於實際執行環境。

設定

建立新的 Node.js 應用程式

在主控台視窗 (例如 cmd、PowerShell 或 Bash) 中,為您的應用程式建立新的目錄,並瀏覽至該目錄。

mkdir qnamaker_quickstart && cd qnamaker_quickstart

執行命令 npm init -y,以使用 package.json 檔案建立節點應用程式。

npm init -y

安裝用戶端程式庫

安裝下列 NPM 套件:

npm install @azure/cognitiveservices-qnamaker
npm install @azure/cognitiveservices-qnamaker-runtime
npm install @azure/ms-rest-js

您應用程式的 package.json 檔案會隨著相依性而更新。

建立名為 index.js 的檔案,並匯入下列程式庫:

const msRest = require("@azure/ms-rest-js");
const qnamaker = require("@azure/cognitiveservices-qnamaker");
const qnamaker_runtime = require("@azure/cognitiveservices-qnamaker-runtime");

為資源的 Azure 金鑰和資源名稱建立變數。

  • 我們會交換使用訂用帳戶金鑰和撰寫金鑰。 如需撰寫金鑰的詳細資訊,請遵循 QnA Maker 中的金鑰

  • QNA_MAKER_ENDPOINT 的值具有 https://YOUR-RESOURCE-NAME.cognitiveservices.azure.com 格式。 移至 Azure 入口網站,並尋找您已在必要條件中建立的 QnA Maker 資源。 選取 [資源管理] 下的 [金鑰和端點] 頁面,以找出撰寫 (訂用帳戶) 金鑰和 QnA Maker 端點。

QnA Maker Authoring Endpoint

  • QNA_MAKER_RUNTIME_ENDPOINT 的值具有 https://YOUR-RESOURCE-NAME.azurewebsites.net 格式。 移至 Azure 入口網站,並尋找您已在必要條件中建立的 QnA Maker 資源。 選取 [自動化] 下的 [匯出範本] 頁面,以找出執行階段端點。

QnA Maker Runtime Endpoint

  • 在生產環境中,請考慮使用安全的方式來儲存及存取您的認證。 例如,Azure Key Vault 可提供安全的金鑰儲存。
const subscription_key = "PASTE_YOUR_QNA_MAKER_AUTHORING_SUBSCRIPTION_KEY_HERE";
const endpoint = "PASTE_YOUR_QNA_MAKER_AUTHORING_ENDPOINT_HERE";
const runtime_endpoint = "PASTE_YOUR_QNA_MAKER_RUNTIME_ENDPOINT_HERE";

物件模型

QnA Maker 使用兩種不同的物件模型:

  • QnAMakerClient 是用來建立、管理、發佈和下載知識庫的物件。
  • QnAMakerRuntime 是可讓您透過 GenerateAnswer API 查詢知識庫,並使用定型 API 傳送新的建議問題 (作為主動式學習的一部分) 的物件。

QnAMakerClient 物件模型

製作 QnA Maker 用戶端是一種 QnAMakerClient 物件,會使用含有金鑰的認證向 Azure 進行驗證。

建立用戶端之後,請使用知識庫建立、管理和發佈知識庫。

藉由傳送 JSON 物件來管理知識庫。 針對立即性作業,方法通常會傳回可指出狀態的 JSON 物件。 針對長期作業,回應則是作業識別碼。 使用作業識別碼來呼叫 client.operations.getDetails 方法,以確認要求的狀態

QnAMakerRuntimeClient 物件模型

預測 QnA Maker 用戶端是一種 QnAMakerRuntimeClient 物件,會使用 Microsoft.Rest.ServiceClientCredentials 向 Azure 進行驗證,其中包含您的預測執行階段金鑰,這是在發佈知識庫後由製作用戶端呼叫 client.EndpointKeys.getKeys 傳回的金鑰。

程式碼範例

這些程式碼片段會示範如何使用適用於 .NET 的 QnA Maker 用戶端程式庫來執行下列動作:

驗證用戶端以撰寫知識庫

使用端點和金鑰來具現化用戶端。 使用您的金鑰建立 ServiceClientCredentials 物件,並使用該物件與您的端點搭配來建立 QnAMakerClient 物件。

const creds = new msRest.ApiKeyCredentials({ inHeader: { 'Ocp-Apim-Subscription-Key': subscription_key } });
const qnaMakerClient = new qnamaker.QnAMakerClient(creds, endpoint);
const knowledgeBaseClient = new qnamaker.Knowledgebase(qnaMakerClient);

建立知識庫

知識庫會針對來自三個來源的 CreateKbDTO 物件儲存問題和答案組:

  • 針對編輯內容,請使用 QnADTO 物件。
    • 若要使用中繼資料和後續提示,請使用編輯內容,因為這項資料會在個別的 QnA 配對層級上新增。
  • 針對檔案,請使用 FileDTO 物件。 FileDTO 包含檔案名稱,以及用來觸達檔案的公用 URL。
  • 針對 URL,請使用字串清單來代表公開可用的 URL。

建立步驟也包含知識庫的屬性:

  • defaultAnswerUsedForExtraction - 找不到答案時會傳回的內容
  • enableHierarchicalExtraction - 自動在已擷取的 QnA 配對之間建立提示關聯性
  • language - 會在建立資源的第一個知識庫時,設定要在 Azure 搜尋服務索引中使用的語言。

使用知識庫資訊呼叫 create 方法。 知識庫資訊基本上是 JSON 物件。

create 方法傳回後,將傳回的作業識別碼傳至 wait_for_operation 方法,以輪詢狀態。 當作業完成時,wait_for_operation 方法會傳回。 剖析傳回作業的 resourceLocation 標頭值,以取得新的知識庫識別碼。

const createKnowledgeBase = async (qnaClient, kbclient) => {

    console.log(`Creating knowledge base...`)

    const qna1 = {
        answer: "Yes, You can use our [REST APIs](https://docs.microsoft.com/rest/api/cognitiveservices/qnamaker/knowledgebase) to manage your knowledge base.",
        questions: ["How do I manage my knowledgebase?"],
        metadata: [
            { name: "Category", value: "api" },
            { name: "Language", value: "REST" }
        ]
    };

    const qna2 = {
        answer: "Yes, You can use our JS SDK on NPM for [authoring](https://www.npmjs.com/package/@azure/cognitiveservices-qnamaker), [query runtime](https://www.npmjs.com/package/@azure/cognitiveservices-qnamaker-runtime), and [the reference docs](https://docs.microsoft.com/en-us/javascript/api/@azure/cognitiveservices-qnamaker/?view=azure-node-latest) to manage your knowledge base.",
        questions: ["How do I manage my knowledgebase?"],
        metadata: [
            { name: "Category", value: "api" },
            { name: "Language", value: "JavaScript" }
        ]
    };

    const create_kb_payload = {
        name: 'QnA Maker JavaScript SDK Quickstart',
        qnaList: [
            qna1,
            qna2
        ],
        urls: [],
        files: [
            /*{
                fileName: "myfile.md",
                fileUri: "https://mydomain/myfile.md"
            }*/
        ],
        defaultAnswerUsedForExtraction: "No answer found.",
        enableHierarchicalExtraction: true,
        language: "English"
    };

    const results = await kbclient.create(create_kb_payload)

    if ( ! results._response.status.toString().startsWith("2")) {
        console.log(`Create request failed - HTTP status ${results._response.status}`)
        return
    }

    const operationResult = await wait_for_operation(qnaClient, results.operationId)

    if (!operationResult || !operationResult.operationState || !(operationResult.operationState = "Succeeded") || !operationResult.resourceLocation) {
        console.log(`Create operation state failed - HTTP status ${operationResult._response.status}`)
        return
    }

    // parse resourceLocation for KB ID
    const kbID = operationResult.resourceLocation.replace("/knowledgebases/", "");

    return kbID;
}

務必包含上述程式碼中參考的 wait_for_operation 函式,才能成功建立知識庫。

更新知識庫

若要更新知識庫,請將知識庫識別碼以及包含 addupdatedelete DTO 物件的 UpdateKbOperationDTO 傳至 update 方法。 DTO 基本上也是 JSON 物件。 使用 wait_for_operation 方法來判斷更新是否成功。

const updateKnowledgeBase = async (qnaClient, kbclient, kb_id) => {

    console.log(`Updating knowledge base...`)

    const urls = [
        "https://docs.microsoft.com/azure/cognitive-services/QnAMaker/troubleshooting"
    ]

    const qna3 = {
        answer: "goodbye",
        questions: [
            "bye",
            "end",
            "stop",
            "quit",
            "done"
        ],
        metadata: [
            { name: "Category", value: "Chitchat" },
            { name: "Chitchat", value: "end" }
        ]
    };

    const qna4 = {
        answer: "Hello, please select from the list of questions or enter a new question to continue.",
        questions: [
            "hello",
            "hi",
            "start"
        ],
        metadata: [
            { name: "Category", value: "Chitchat" },
            { name: "Chitchat", value: "begin" }
        ],
        context: {
            isContextOnly: false,
            prompts: [
                {
                    displayOrder: 1,
                    displayText: "Use REST",
                    qna: null,
                    qnaId: 1
                },
                {
                    displayOrder: 2,
                    displayText: "Use JS NPM package",
                    qna: null,
                    qnaId: 2
                },
            ]
        }
    };

    console.log(JSON.stringify(qna4))

    // Add new Q&A lists, URLs, and files to the KB.
    const kb_add_payload = {
        qnaList: [
            qna3,
            qna4
        ],
        urls: urls,
        files: []
    };

    // Bundle the add, update, and delete requests.
    const update_kb_payload = {
        add: kb_add_payload,
        update: null,
        delete: null,
        defaultAnswerUsedForExtraction: "No answer found. Please rephrase your question."
    };

    console.log(JSON.stringify(update_kb_payload))

    const results = await kbclient.update(kb_id, update_kb_payload)

    if ( ! results._response.status.toString().startsWith("2")) {
        console.log(`Update request failed - HTTP status ${results._response.status}`)
        return false
    }

    const operationResult = await wait_for_operation(qnaClient, results.operationId)

    if (operationResult.operationState != "Succeeded") {
        console.log(`Update operation state failed - HTTP status ${operationResult._response.status}`)
        return false
    }

    console.log(`Update operation state ${operationResult._response.status} - HTTP status ${operationResult._response.status}`)
    return true
}

務必包含上述程式碼中參考的 wait_for_operation 函式,才能成功更新知識庫。

下載知識庫

使用 download 方法將資料庫下載為 QnADocumentsDTO 的清單。 此做法不等同於 QnA Maker 入口網站從 [設定] 頁面進行的匯出作業,原因是此方法的結果並非 TSV 檔案。

const downloadKnowledgeBase = async (KBclient, kb_id) => {

    console.log(`Downloading knowledge base...`)

    var kbData = await KBclient.download(kb_id, "Prod");
    console.log(`Knowledge base downloaded. It has ${kbData.qnaDocuments.length} QnAs.`);

    // Do something meaningful with data
}

發佈知識庫

使用 publish 方法來發佈知識庫。 這會採用目前已儲存且已定型的模型 (可透過知識庫識別碼加以參考),並在端點加以發佈。 檢查 HTTP 回應碼以驗證發佈是否成功。

const publishKnowledgeBase = async (kbclient, kb_id) => {

    console.log(`Publishing knowledge base...`)

    const results = await kbclient.publish(kb_id)

    if ( ! results._response.status.toString().startsWith("2")) {
        console.log(`Publish request failed - HTTP status ${results._response.status}`)
        return false
    }

    console.log(`Publish request succeeded - HTTP status ${results._response.status}`)

    return true
}

查詢知識庫

取得查詢執行階段金鑰

知識庫發佈後,您必須要有查詢執行階段金鑰才能查詢執行階段。 這不是用來建立原始用戶端物件的相同金鑰。

使用 EndpointKeys.getKeys 方法取得 EndpointKeysDTO 類別。

使用物件中傳回的其中一個金鑰屬性來查詢知識庫。

const getEndpointKeys = async (qnaClient) => {

    console.log(`Getting runtime endpoint keys...`)

    const runtimeKeysClient = await qnaClient.endpointKeys;
    const results = await runtimeKeysClient.getKeys()

    if ( ! results._response.status.toString().startsWith("2")) {
        console.log(`GetEndpointKeys request failed - HTTP status ${results._response.status}`)
        return null
    }

    console.log(`GetEndpointKeys request succeeded - HTTP status ${results._response.status} - primary key ${results.primaryEndpointKey}`)

    return results.primaryEndpointKey
}

驗證執行階段以產生解答

建立 QnAMakerRuntimeClient 來查詢知識庫,以產生解答,或從主動式學習進行訓練。

const queryRuntimeCredentials = new msRest.ApiKeyCredentials({ inHeader: { 'Authorization': 'EndpointKey ' + primaryQueryRuntimeKey } });
const runtimeClient = new qnamaker_runtime.QnAMakerRuntimeClient(queryRuntimeCredentials, runtime_endpoint);

使用 QnAMakerRuntimeClient 從知識取得解答,或將新的建議問題傳送至主動式學習的知識庫。

從知識庫產生答案

使用 RuntimeClient.runtime.generateAnswer 方法從已發佈的知識庫產生答案。 此方法會接受知識庫識別碼和 QueryDTO。 存取 QueryDTO 的其他屬性 (例如 Top 和 Context),以在聊天機器人中使用。

const generateAnswer = async (runtimeClient, runtimeKey, kb_id) => {

    console.log(`Querying knowledge base...`)

    const requestQuery = await runtimeClient.runtime.generateAnswer(
        kb_id,
        {
            question: "How do I manage my knowledgebase?",
            top: 1,
            strictFilters: [
                { name: "Category", value: "api" }
            ]
        }
    );
    console.log(JSON.stringify(requestQuery));

}

這是查詢知識庫的簡單範例。 若要了解進階查詢案例,請檢閱其他查詢範例

刪除知識庫

使用 delete 方法搭配知識庫識別碼的參數來刪除知識庫。

const deleteKnowledgeBase = async (KBclient, kb_id) => {

    console.log(`Deleting knowledge base...`)

    const results = await KBclient.deleteMethod(kb_id)

    if ( ! results._response.status.toString().startsWith("2")) {
        console.log(`Delete operation state failed - HTTP status ${results._response.status}`)
        return false
    }

    console.log(`Delete operation state succeeded - HTTP status ${results._response.status}`)
    return true
}

取得作業的狀態

某些方法 (例如 create 和 update) 的時間很充裕,而不必等候程序完成,並傳回作業。 從要輪詢 (使用重試邏輯) 的作業使用作業識別碼來確定原始方法的狀態。

下列程式碼區塊中的 delayTimer 呼叫可用來模擬重試邏輯。 請將此項目取代為您自己的重試邏輯。

const wait_for_operation = async (qnaClient, operation_id) => {

    let state = "NotStarted"
    let operationResult = undefined

    while ("Running" === state || "NotStarted" === state) {

        operationResult = await qnaClient.operations.getDetails(operation_id)
        state = operationResult.operationState;

        console.log(`Operation state - ${state}`)

        await delayTimer(1000);
    }

    return operationResult;
}
const delayTimer = async (timeInMs) => {
    return await new Promise((resolve) => {
        setTimeout(resolve, timeInMs);
    });
}

執行應用程式

使用 node index.js 命令從您的應用程式目錄執行應用程式。

node index.js

此範例的原始程式碼可以在 GitHub 上找到。

使用適用于 Python 的 QnA Maker 用戶端程式庫來:

  • 建立知識庫
  • 更新知識庫
  • 發佈知識庫
  • 取得預測執行階段端點金鑰
  • 等候長時間執行的工作
  • 下載知識庫
  • 從知識庫取得答案
  • 刪除知識庫

參考文件 | 程式庫來源程式碼 | 套件 (PyPi) | Python 範例

注意

2019 年 7 月 1 日之後建立的新資源會使用自訂的子網域名稱。 如需詳細資訊和完整的區域端點清單,請參閱認知服務的自訂子網域名稱

必要條件

注意

本文件不適用於最新版本。 若要了解如何搭配使用 Python API 與最新版本,請參閱 Python API 問題解答快速入門

  • Azure 訂用帳戶 - 建立免費帳戶
  • Python 3.x
  • 擁有 Azure 訂用帳戶之後,請在 Azure 入口網站中建立 QnA Maker 資源,以取得您的撰寫金鑰和端點。 在其部署後,選取 [前往資源]。
    • 您需要來自所建立資源的金鑰和端點,以將應用程式連線至 QnA Maker API。 您稍後會在快速入門中將金鑰和端點貼到下列程式碼中。
    • 您可以使用免費定價層 (F0) 來試用服務,之後可升級至付費層以用於實際執行環境。

設定

安裝用戶端程式庫

安裝 Python 之後,您可以透過以下項目安裝用戶端程式庫:

pip install azure-cognitiveservices-knowledge-qnamaker==0.2.0

建立新的 Python 應用程式

建立名為 quickstart-file.py 的新 Python 檔案,並匯入下列程式庫。

import os
import time

from azure.cognitiveservices.knowledge.qnamaker.authoring import QnAMakerClient
from azure.cognitiveservices.knowledge.qnamaker.runtime import QnAMakerRuntimeClient
from azure.cognitiveservices.knowledge.qnamaker.authoring.models import QnADTO, MetadataDTO, CreateKbDTO, OperationStateType, UpdateKbOperationDTO, UpdateKbOperationDTOAdd, EndpointKeysDTO, QnADTOContext, PromptDTO
from azure.cognitiveservices.knowledge.qnamaker.runtime.models import QueryDTO
from msrest.authentication import CognitiveServicesCredentials

為資源的 Azure 端點和金鑰建立變數。

  • 我們會交換使用訂用帳戶金鑰和撰寫金鑰。 如需撰寫金鑰的詳細資訊,請遵循 QnA Maker 中的金鑰

  • QNA_MAKER_ENDPOINT 的值具有 https://YOUR-RESOURCE-NAME.cognitiveservices.azure.com 格式。 移至 Azure 入口網站,並尋找您已在必要條件中建立的 QnA Maker 資源。 選取 [資源管理] 下的 [金鑰和端點] 頁面,以找出撰寫 (訂用帳戶) 金鑰和 QnA Maker 端點。

QnA Maker Authoring Endpoint

  • QNA_MAKER_RUNTIME_ENDPOINT 的值具有 https://YOUR-RESOURCE-NAME.azurewebsites.net 格式。 移至 Azure 入口網站,並尋找您已在必要條件中建立的 QnA Maker 資源。 選取 [自動化] 下的 [匯出範本] 頁面,以找出執行階段端點。

QnA Maker Runtime Endpoint

  • 在生產環境中,請考慮使用安全的方式來儲存及存取您的認證。 例如,Azure Key Vault 可提供安全的金鑰儲存。
subscription_key = 'PASTE_YOUR_QNA_MAKER_AUTHORING_SUBSCRIPTION_KEY_HERE'

authoring_endpoint = 'PASTE_YOUR_QNA_MAKER_AUTHORING_ENDPOINT_HERE'

runtime_endpoint = 'PASTE_YOUR_QNA_MAKER_RUNTIME_ENDPOINT_HERE'

物件模型

QnA Maker 使用兩種不同的物件模型:

  • QnAMakerClient 是用來建立、管理、發佈和下載知識庫的物件。
  • QnAMakerRuntime 是可讓您透過 GenerateAnswer API 查詢知識庫,並使用定型 API 傳送新的建議問題 (作為主動式學習的一部分) 的物件。

使用此範例知識庫

本快速入門中的知識庫起始於 2 個對話式 QnA 配對 (這是為了簡化範例,且在更新方法中有高度可預測的識別碼可供使用),且會將問題的後續提示與新的配對產生關聯。 這是本快速入門中的規劃作業,會依特定順序實作。

如果您日後要依據相依於現有 QnA 配對的後續提示來開發知識庫,您可以選擇:

  • 針對較大的知識庫,在支援自動化的文字編輯器或 TSV 工具中管理知識庫,然後立即將知識庫完全取代為更新。
  • 對於較小的知識庫,則完全在 QnA Maker 入口網站中管理後續提示。

本快速入門中使用的 QnA 配對詳細資料:

  • QnA 配對的類型 - 在更新之後,此知識庫中有 2 種類型的 QnA 配對:Chitchat 和網域專屬資訊。 這在繫結至交談應用程式 (例如聊天機器人) 的知識庫上很常見。
  • 雖然知識庫答案可以透過中繼資料進行篩選,或使用後續追蹤提示,但不在本快速入門的說明範圍中。 您可以在這裡找到不限定語言的 generateAnswer 範例。
  • 解答文字是 Markdown 格式,而且可以包含各式各樣的 Markdown,例如影像 (公開可用的網際網路影像)、連結 (公開可用的 URL) 和項目符號 (本快速入門不會用到此類型)。

QnAMakerClient 物件模型

製作 QnA Maker 用戶端是一種 QnAMakerClient 物件,會使用含有金鑰的 Microsoft.Rest.ServiceClientCredentials 向 Azure 進行驗證。

建立用戶端之後,請使用知識庫屬性來建立、管理和發佈知識庫。

藉由傳送 JSON 物件來管理知識庫。 針對立即性作業,方法通常會傳回可指出狀態的 JSON 物件。 針對長期作業,回應則是作業識別碼。 使用作業識別碼來呼叫 operations.get_details 方法,以確認要求的狀態

QnAMakerRuntimeClient 物件模型

預測 QnA Maker 用戶端是一種 QnAMakerRuntimeClient 物件,會使用 Microsoft.Rest.ServiceClientCredentials 向 Azure 進行驗證,其中包含您的預測執行階段金鑰,這是在發佈知識庫後由製作用戶端呼叫 client.EndpointKeysOperations.get_keys 傳回的金鑰。

使用 generate_answer 方法從查詢執行階段取得答案。

驗證用戶端以撰寫知識庫

使用端點和金鑰來具現化用戶端。 使用金鑰建立 CognitiveServicesCredentials 物件,並使用該物件與您的端點建立 QnAMakerClient 物件。

client = QnAMakerClient(endpoint=authoring_endpoint, credentials=CognitiveServicesCredentials(subscription_key))

建立知識庫

使用用戶端物件取得知識庫作業物件。

知識庫會針對來自三個來源的 CreateKbDTO 物件儲存問題和答案組:

  • 針對編輯內容,請使用 QnADTO 物件。
    • 若要使用中繼資料和後續提示,請使用編輯內容,因為這項資料會在個別的 QnA 配對層級上新增。
  • 針對檔案,請使用 FileDTO 物件。 FileDTO 包含檔案名稱,以及用來觸達檔案的公用 URL。
  • 針對 URL,請使用字串清單來代表公開可用的 URL。

請呼叫 create 方法,然後將傳回的作業識別碼傳至 Operations.getDetails 方法,以輪詢狀態。

下列程式碼的最後一行會傳回來自 MonitorOperation 回應的知識庫識別碼。

def create_kb(client):
    print ("Creating knowledge base...")

    qna1 = QnADTO(
        answer="Yes, You can use our [REST APIs](https://docs.microsoft.com/rest/api/cognitiveservices/qnamaker/knowledgebase) to manage your knowledge base.",
        questions=["How do I manage my knowledgebase?"],
        metadata=[
            MetadataDTO(name="Category", value="api"),
            MetadataDTO(name="Language", value="REST"),
        ]
    )

    qna2 = QnADTO(
        answer="Yes, You can use our [Python SDK](https://pypi.org/project/azure-cognitiveservices-knowledge-qnamaker/) with the [Python Reference Docs](https://docs.microsoft.com/python/api/azure-cognitiveservices-knowledge-qnamaker/azure.cognitiveservices.knowledge.qnamaker?view=azure-python) to manage your knowledge base.",
        questions=["Can I program with Python?"],
        metadata=[
            MetadataDTO(name="Category", value="api"),
            MetadataDTO(name="Language", value="Python"),
        ]
    )

    urls = []
    files = [
        FileDTO(
            file_name = "structured.docx",
            file_uri = "https://github.com/Azure-Samples/cognitive-services-sample-data-files/raw/master/qna-maker/data-source-formats/structured.docx"
        )]

    create_kb_dto = CreateKbDTO(
        name="QnA Maker Python SDK Quickstart",
        qna_list=[
            qna1,
            qna2
        ],
        urls=urls,
        files=[],
        enable_hierarchical_extraction=True,
        default_answer_used_for_extraction="No answer found.",
        language="English"
    )
    create_op = client.knowledgebase.create(create_kb_payload=create_kb_dto)

    create_op_monitor = _monitor_operation(client=client, operation=create_op)

    # Get knowledge base ID from resourceLocation HTTP header
    knowledge_base_ID = create_op_monitor.resource_location.replace("/knowledgebases/", "")
    print("Created KB with ID: {}".format(knowledge_base_ID))

    return knowledge_base_ID

務必包含上述程式碼中參考的 _monitor_operation 函式,才能成功建立知識庫。

更新知識庫

若要更新知識庫,請將知識庫識別碼以及包含 addupdatedelete DTO 物件的 UpdateKbOperationDTO 傳至 update 方法。 使用 Operation.getDetail 方法確認更新是否成功。

def update_kb(client, kb_id):
    print ("Updating knowledge base...")

    qna3 = QnADTO(
        answer="goodbye",
        questions=[
            "bye",
            "end",
            "stop",
            "quit",
            "done"
            ],
        metadata=[
            MetadataDTO(name="Category", value="Chitchat"),
            MetadataDTO(name="Chitchat", value="end"),
        ]
    )

    qna4 = QnADTO(
        answer="Hello, please select from the list of questions or enter a new question to continue.",
        questions=[
            "hello",
            "hi",
            "start"
        ],
        metadata=[
            MetadataDTO(name="Category", value="Chitchat"),
            MetadataDTO(name="Chitchat", value="begin"),
        ],
        context = QnADTOContext(

            is_context_only = False,
            prompts = [

                PromptDTO(
                    display_order =1,
                    display_text= "Use REST",
                    qna_id=1

                ),
                PromptDTO(
                    display_order =2,
                    display_text= "Use .NET NuGet package",
                    qna_id=2
                ),
            ]
        )

    )

    urls = [
        "https://docs.microsoft.com/azure/cognitive-services/QnAMaker/troubleshooting"
    ]



    update_kb_operation_dto = UpdateKbOperationDTO(
        add=UpdateKbOperationDTOAdd(
            qna_list=[
                qna3,
                qna4
            ],
            urls = urls,
            files=[]
        ),
        delete=None,
        update=None
    )
    update_op = client.knowledgebase.update(kb_id=kb_id, update_kb=update_kb_operation_dto)
    _monitor_operation(client=client, operation=update_op)
    print("Updated knowledge base.")

務必包含上述程式碼中參考的 _monitor_operation 函式,才能成功更新知識庫。

下載知識庫

使用 download 方法將資料庫下載為 QnADocumentsDTO 的清單。 此做法不等同於 QnA Maker 入口網站從 [設定] 頁面進行的匯出作業,原因是此方法的結果並非 TSV 檔案。

def download_kb(client, kb_id):
    print("Downloading knowledge base...")
    kb_data = client.knowledgebase.download(kb_id=kb_id, environment="Prod")
    print("Downloaded knowledge base. It has {} QnAs.".format(len(kb_data.qna_documents)))

發佈知識庫

使用 publish 方法來發佈知識庫。 這會採用目前已儲存且已定型的模型 (可透過知識庫識別碼加以參考),並在端點加以發佈。

def publish_kb(client, kb_id):
    print("Publishing knowledge base...")
    client.knowledgebase.publish(kb_id=kb_id)
    print("Published knowledge base.")

查詢知識庫

取得查詢執行階段金鑰

知識庫發佈後,您必須要有查詢執行階段金鑰才能查詢執行階段。 這不是用來建立原始用戶端物件的相同金鑰。

使用 EndpointKeysOperations.get_keys 方法取得 EndpointKeysDTO 類別。

使用物件中傳回的其中一個金鑰屬性來查詢知識庫。

def getEndpointKeys_kb(client):
    print("Getting runtime endpoint keys...")
    keys = client.endpoint_keys.get_keys()
    print("Primary runtime endpoint key: {}.".format(keys.primary_endpoint_key))

    return keys.primary_endpoint_key

驗證執行階段以產生解答

建立 QnAMakerRuntimeClient 來查詢知識庫,以產生解答,或從主動式學習進行訓練。

runtimeClient = QnAMakerRuntimeClient(runtime_endpoint=runtime_endpoint, credentials=CognitiveServicesCredentials(queryRuntimeKey))

使用 QnAMakerRuntimeClient 從知識取得解答,或將新的建議問題傳送至主動式學習的知識庫。

從知識庫產生答案

使用 QnAMakerRuntimeClient.runtime.generate_answer 方法從已發佈的知識庫產生答案。 此方法會接受知識庫識別碼和 QueryDTO。 存取 QueryDTO 的其他屬性 (例如 Top 和 Context),以在聊天機器人中使用。

def generate_answer(client, kb_id, runtimeKey):
    print ("Querying knowledge base...")

    authHeaderValue = "EndpointKey " + runtimeKey

    listSearchResults = client.runtime.generate_answer(kb_id, QueryDTO(question = "How do I manage my knowledgebase?"), dict(Authorization=authHeaderValue))

    for i in listSearchResults.answers:
        print(f"Answer ID: {i.id}.")
        print(f"Answer: {i.answer}.")
        print(f"Answer score: {i.score}.")

這是查詢知識庫的簡單範例。 若要了解進階查詢案例,請檢閱其他查詢範例

刪除知識庫

使用 delete 方法搭配知識庫識別碼的參數來刪除知識庫。

def delete_kb(client, kb_id):
    print("Deleting knowledge base...")
    client.knowledgebase.delete(kb_id=kb_id)
    print("Deleted knowledge base.")

取得作業的狀態

某些方法 (例如 create 和 update) 的時間很充裕,而不必等候程序完成,並傳回作業。 從要輪詢 (使用重試邏輯) 的作業使用作業識別碼來確認原始方法的狀態。

下列程式碼區塊中的 setTimeout 呼叫可用來模擬非同步程式碼。 請將此項目取代為重試邏輯。

def _monitor_operation(client, operation):

    for i in range(20):
        if operation.operation_state in [OperationStateType.not_started, OperationStateType.running]:
            print("Waiting for operation: {} to complete.".format(operation.operation_id))
            time.sleep(5)
            operation = client.operations.get_details(operation_id=operation.operation_id)
        else:
            break
    if operation.operation_state != OperationStateType.succeeded:
        raise Exception("Operation {} failed to complete.".format(operation.operation_id))

    return operation

執行應用程式

在快速入門檔案上使用 Python 命令執行應用程式。

python quickstart-file.py

此範例的原始程式碼可以在 GitHub 上找到。

使用適用於 Java 的 QnA Maker 用戶端程式庫來:

  • 建立知識庫
  • 更新知識庫
  • 發佈知識庫
  • 取得預測執行階段端點金鑰
  • 等候長時間執行的工作
  • 下載知識庫
  • 從知識庫取得答案
  • 刪除知識庫

程式庫原始程式碼 | 套件 | 範例

注意

2019 年 7 月 1 日之後建立的新資源會使用自訂的子網域名稱。 如需詳細資訊和完整的區域端點清單,請參閱認知服務的自訂子網域名稱

必要條件

  • Azure 訂用帳戶 - 建立免費帳戶
  • JDK
  • 擁有 Azure 訂用帳戶之後,請在 Azure 入口網站中建立 QnA Maker 資源,以取得您的撰寫金鑰和端點。 在其部署後,選取 [前往資源]。
    • 您需要來自所建立資源的金鑰和端點,以將應用程式連線至 QnA Maker API。 稍後會在快速入門中將金鑰和端點貼到下列程式碼中。
    • 您可以使用免費定價層 (F0) 來試用服務,之後可升級至付費層以用於實際執行環境。

設定

安裝用戶端程式庫

安裝 Java 之後,您可以使用 MVN 存放庫中的 Maven 來安裝用戶端程式庫。

建立新的 Java 應用程式

建立名為 quickstart.java 的新檔案,並匯入下列程式庫。

/* Download the following files.
 * - https://repo1.maven.org/maven2/com/microsoft/azure/cognitiveservices/azure-cognitiveservices-qnamaker/1.0.0-beta.1/azure-cognitiveservices-qnamaker-1.0.0-beta.1.jar
 * - https://repo1.maven.org/maven2/com/microsoft/azure/cognitiveservices/azure-cognitiveservices-qnamaker/1.0.0-beta.1/azure-cognitiveservices-qnamaker-1.0.0-beta.1.pom
 * Move the downloaded .jar file to a folder named "lib" directly under the current folder.
 * Rename the downloaded file to pom.xml.
 * At the command line, run
 * mvn dependency:copy-dependencies
 * This will download the .jar files depended on by azure-cognitiveservices-qnamaker-1.0.0-beta.1.jar to the folder "target/dependency" under the current folder. Move these .jar files to the "lib" folder as well.
 */
import com.microsoft.azure.cognitiveservices.knowledge.qnamaker.*;
import com.microsoft.azure.cognitiveservices.knowledge.qnamaker.models.*;

import java.io.*;
import java.lang.Object.*;
import java.time.format.DateTimeFormatter;  
import java.time.LocalDateTime; 
import java.util.*;
import java.net.*;

為資源的 Azure 端點和金鑰建立變數。

  • 我們會交換使用訂用帳戶金鑰和撰寫金鑰。 如需撰寫金鑰的詳細資訊,請遵循 QnA Maker 中的金鑰

  • QNA_MAKER_ENDPOINT 的值具有 https://YOUR-RESOURCE-NAME.cognitiveservices.azure.com 格式。 移至 Azure 入口網站,並尋找您已在必要條件中建立的 QnA Maker 資源。 選取 [資源管理] 下的 [金鑰和端點] 頁面,以找出撰寫 (訂用帳戶) 金鑰和 QnA Maker 端點。

QnA Maker Authoring Endpoint

  • QNA_MAKER_RUNTIME_ENDPOINT 的值具有 https://YOUR-RESOURCE-NAME.azurewebsites.net 格式。 移至 Azure 入口網站,並尋找您已在必要條件中建立的 QnA Maker 資源。 選取 [自動化] 下的 [匯出範本] 頁面,以找出執行階段端點。

QnA Maker Runtime Endpoint

  • 在生產環境中,請考慮使用安全的方式來儲存及存取您的認證。 例如,Azure Key Vault 可提供安全的金鑰儲存。
private static String authoring_key = "PASTE_YOUR_QNA_MAKER_AUTHORING_SUBSCRIPTION_KEY_HERE";
private static String authoring_endpoint = "PASTE_YOUR_QNA_MAKER_AUTHORING_ENDPOINT_HERE";
private static String runtime_endpoint = "PASTE_YOUR_QNA_MAKER_RUNTIME_ENDPOINT_HERE";

物件模型

QnA Maker 使用兩種不同的物件模型:

  • QnAMakerClient 是用來建立、管理、發佈和下載知識庫的物件。
  • QnAMakerRuntime 是可讓您透過 GenerateAnswer API 查詢知識庫,並使用定型 API 傳送新的建議問題 (作為主動式學習的一部分) 的物件。

使用此範例知識庫

本快速入門中的知識庫起始於 2 個對話式 QnA 配對 (這是為了簡化範例,且在更新方法中有高度可預測的識別碼可供使用),且會將問題的後續提示與新的配對產生關聯。 這是本快速入門中的規劃作業,會依特定順序實作。

如果您日後要依據相依於現有 QnA 配對的後續提示來開發知識庫,您可以選擇:

  • 針對較大的知識庫,在支援自動化的文字編輯器或 TSV 工具中管理知識庫,然後立即將知識庫完全取代為更新。
  • 對於較小的知識庫,則完全在 QnA Maker 入口網站中管理後續提示。

本快速入門中使用的 QnA 配對詳細資料:

  • QnA 配對的類型 - 在更新之後,此知識庫中有 2 種類型的 QnA 配對:Chitchat 和網域專屬資訊。 這在繫結至交談應用程式 (例如聊天機器人) 的知識庫上很常見。
  • 雖然知識庫答案可以透過中繼資料進行篩選,或使用後續追蹤提示,但不在本快速入門的說明範圍中。 您可以在這裡找到不限定語言的 generateAnswer 範例。
  • 解答文字是 Markdown 格式,而且可以包含各式各樣的 Markdown,例如影像 (公開可用的網際網路影像)、連結 (公開可用的 URL) 和項目符號 (本快速入門不會用到此類型)。

QnAMakerClient 物件模型

撰寫 QnA Maker 用戶端是一種 QnAMakerClient 物件,會使用含有金鑰的 MsRest::ServiceClientCredentials 向 Azure 進行驗證。

用戶端建立後,請使用用戶端知識庫屬性的方法來建立、管理和發佈知識庫。

即時作業的方法通常會傳回結果 (如果有的話)。 長期作業的回應為作業物件。 使用 operation.operationId 值呼叫 getDetails 方法,以確認要求的狀態

QnAMakerRuntimeClient 物件模型

執行階段 QnA Maker 用戶端是 QnAMakerRuntimeClient 物件。

使用撰寫用戶端發佈知識庫之後,請使用執行階段用戶端的 generateAnswer 方法,從知識庫取得答案。

您可以藉由呼叫 QnAMakerRuntimeManager.authenticate 並傳遞執行階段端點金鑰,來建立執行階段用戶端。 若要取得執行階段端點金鑰,請使用撰寫用戶端來呼叫 getKeys

驗證用戶端以撰寫知識庫

使用您的撰寫端點和訂用帳戶金鑰將用戶端具現化。

/* Note QnAMakerManager.authenticate() does not set the baseUrl paramater value
 * as the value for QnAMakerClient.endpoint, so we still need to call withEndpoint().
 */
QnAMakerClient authoring_client = QnAMakerManager.authenticate(authoring_key).withEndpoint(authoring_endpoint);
Knowledgebases kb_client = authoring_client.knowledgebases();
Operations ops_client = authoring_client.operations();
EndpointKeys keys_client = authoring_client.endpointKeys();

建立知識庫

知識庫會針對來自三個來源的 CreateKbDTO 物件儲存問題和答案組:

  • 針對編輯內容,請使用 QnADTO 物件。
    • 若要使用中繼資料和後續提示,請使用編輯內容,因為這項資料會在個別的 QnA 配對層級上新增。
  • 針對檔案,請使用 FileDTO 物件。 FileDTO 包含檔案名稱,以及用來觸達檔案的公用 URL。
  • 針對 URL,請使用字串清單來代表公開可用的 URL。

請呼叫 create 方法,然後將傳回之作業的 operationId 屬性傳遞至 getDetails 方法,以輪詢狀態。

下列程式碼的最後一行會傳回知識庫識別碼。

public String create_kb () throws Exception {
    System.out.println("Creating KB...");

    String name = "QnA Maker FAQ from quickstart";

    var metadata = new MetadataDTO()
        .withName ("Category")
        .withValue ("api");

    List<MetadataDTO> metadata_list = Arrays.asList(new MetadataDTO[]{ metadata });

    var qna = new QnADTO()
        .withAnswer ("You can use our REST APIs to manage your knowledge base.")
        .withQuestions ( Arrays.asList(new String[]{ "How do I manage my knowledgebase?" }))
        .withMetadata (metadata_list);

    List<QnADTO> qna_list = Arrays.asList(new QnADTO[]{ qna });

    var urls = Arrays.asList(new String[]{ "https://docs.microsoft.com/en-in/azure/cognitive-services/qnamaker/faqs" });

    var payload = new CreateKbDTO().withName(name).withQnaList(qna_list).withUrls(urls);

    var result = kb_client.create(payload);
    var kb_id = wait_for_operation(result);

    System.out.println("Created KB with ID: " + kb_id + ".\n");
    return kb_id;
}

更新知識庫

您可以藉由呼叫 update 並傳入知識庫識別碼和 UpdateKbOperationDTO 物件,來更新知識庫。 該物件可包含:

將傳回之作業的 operationId 屬性傳遞至 getDetails 方法,以輪詢狀態。

public void update_kb (String kb_id) throws Exception {
    System.out.println("Updating KB...");

    var update = new UpdateKbOperationDTOUpdate().withName ("New KB name");

    var payload = new UpdateKbOperationDTO().withUpdate((UpdateKbOperationDTOUpdate)update);

    var result = kb_client.update(kb_id, payload);
    wait_for_operation(result);

    System.out.println("Updated KB.");
}

下載知識庫

使用 download 方法將資料庫下載為 QnADocumentsDTO 的清單。 此做法不等同於 QnA Maker 入口網站從 [設定] 頁面進行的匯出作業,原因是此方法的結果並非 TSV 檔案。

public void download_kb(String kb_id) {
    System.out.println("Downloading KB...");

    var kb_data = kb_client.download(kb_id, EnvironmentType.PROD);
    System.out.println("KB Downloaded. It has " + kb_data.qnaDocuments().size() + " question/answer sets.");

    System.out.println("Downloaded KB.\n");
}

發佈知識庫

使用 publish 方法來發佈知識庫。 這會採用目前已儲存且已定型的模型 (可透過知識庫識別碼加以參考),並在端點加以發佈。

public void publish_kb(String kb_id) {
    System.out.println("Publishing KB...");
    kb_client.publish(kb_id);
    System.out.println("KB published.\n");
}

從知識庫產生答案

知識庫發佈後,您必須要有執行階段端點金鑰才能查詢知識庫。 這與用來建立撰寫用戶端的訂用帳戶金鑰不同。

使用 getKeys 方法取得 EndpointKeysDTO 物件。

藉由呼叫 QnAMakerRuntimeManager.authenticate,並從 EndpointKeysDTO 物件傳遞執行階段端點金鑰,來建立執行階段用戶端。

使用 generateAnswer 方法從已發佈的知識庫產生答案。 此方法接受知識庫識別碼和 QueryDTO 物件。

public void query_kb(String kb_id) {
    System.out.println("Sending query to KB...");
    
    var runtime_key = keys_client.getKeys().primaryEndpointKey();
    QnAMakerRuntimeClient runtime_client = QnAMakerRuntimeManager.authenticate(runtime_key).withRuntimeEndpoint(runtime_endpoint);
    var query = (new QueryDTO()).withQuestion("How do I manage my knowledgebase?");
    var result = runtime_client.runtimes().generateAnswer(kb_id, query);
    System.out.println("Answers:");
    for (var answer : result.answers()) {
        System.out.println(answer.answer().toString());
    };
    System.out.println();
}

這是查詢知識庫的簡單範例。 若要了解進階查詢案例,請檢閱其他查詢範例

刪除知識庫

使用 delete 方法搭配知識庫識別碼的參數來刪除知識庫。

public void delete_kb(String kb_id) {
    System.out.println("Deleting KB...");
    kb_client.delete(kb_id);
    System.out.println("KB deleted.\n");
}

取得作業的狀態

某些方法 (例如 create 和 update) 的時間很充裕,而不必等候程序完成,並傳回作業。 從要輪詢 (使用重試邏輯) 的作業使用作業識別碼來確認原始方法的狀態。

public String wait_for_operation(Operation op) throws Exception {
    System.out.println ("Waiting for operation to finish...");
    Boolean waiting = true;
    String result = "";
    while (true == waiting) {
        var op_ = ops_client.getDetails(op.operationId());
        var state = op_.operationState();
        if (OperationStateType.FAILED == state) {
            throw new Exception("Operation failed.");
        }
        if (OperationStateType.SUCCEEDED == state) {
            waiting = false;
            // Remove "/knowledgebases/" from the resource location.
            result = op_.resourceLocation().replace("/knowledgebases/", "");
        }
        if (true == waiting) {
            System.out.println("Waiting 10 seconds for operation to complete...");
            Thread.sleep(10000);
        }
    }
    return result;
}

執行應用程式

以下是應用程式的主要方法。

    public static void main(String[] args) {
        try {
            Quickstart quickstart = new Quickstart();
            String kb_id = quickstart.create_kb();
//			quickstart.list_kbs();
            quickstart.update_kb(kb_id);
            quickstart.publish_kb(kb_id);
            quickstart.download_kb(kb_id);
            quickstart.query_kb(kb_id);
            quickstart.delete_kb(kb_id);
        } catch (Exception e) {
            System.out.println(e.getMessage());
            e.printStackTrace();
        }
    }

以下列方式執行應用程式。 這會假設您的類別名稱是 Quickstart,且您的相依性位於目前資料夾下名為 lib 的子資料夾中。

javac Quickstart.java -cp .;lib\*
java -cp .;lib\* Quickstart

此範例的原始程式碼可以在 GitHub 上找到。

清除資源

如果您想要清除和移除認知服務訂用帳戶,則可以刪除資源或資源群組。 刪除資源群組也會刪除其關聯的任何其他資源。

後續步驟