Quickstart: QnA Maker client library

Note

Azure Open AI On Your Data utilizes large language models (LLMs) to produce similar results to QnA Maker. If you wish to migrate your QnA Maker project to Azure Open AI On Your Data, please check out our guide.

Get started with the QnA Maker client library. Follow these steps to install the package and try out the example code for basic tasks.

Note

The QnA Maker service is being retired on the 31st of March, 2025. A newer version of the question and answering capability is now available as part of Azure AI Language. For question answering capabilities within the Language Service, see question answering. Starting 1st October, 2022 you won’t be able to create new QnA Maker resources. For information on migrating existing QnA Maker knowledge bases to question answering, consult the migration guide.

Prerequisites

Note

This documentation does not apply to the latest release. To learn about using the REST API with the latest release consult the question answering REST API quickstart

  • The current version of cURL. Several command-line switches are used in the quickstarts, which are noted in the cURL documentation.

  • You must have a QnA Maker resource, to use the key and resource name. You entered the resource Name during resource creation, then the key was created for you. The resource name is used as the subdomain for your endpoint. To retrieve your key and resource name, select Quickstart for your resource in the Azure portal. The resource name is the first subdomain of the endpoint URL:

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

Caution

The following BASH examples use the \ line continuation character. If you console or terminal uses a different line continuation character, use this character.

Create a knowledge base

To create a knowledge base with the REST APIs and cURL, you need to have the following information:

Information cURL configuration Purpose
QnA Maker resource name URL used to construct URL
QnA Maker resource key -h param for Ocp-Apim-Subscription-Key header Authenticate to QnA Maker service
JSON describing knowledge base -d param Examples of JSON
Size of the JSON in bytes -h param for Content-Size header

The cURL command is executed from a BASH shell. Edit this command with your own resource name, resource key, and JSON values and size of 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://learn.microsoft.com/azure/ai-services/qnamaker/faqs"]}'

The cURL response from QnA Maker includes the operationId , which is required to get status of the operation.

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

Get status of operation

When you create a knowledge base, because the operation is async, the response includes information to determine the status.

Information cURL configuration Purpose
QnA Maker resource name URL used to construct URL
Operation Id URL route /operations/REPLACE-WITH-YOUR-OPERATION-ID
QnA Maker resource key -h param for Ocp-Apim-Subscription-Key header Authenticate to QnA Maker service

The cURL command is executed from a BASH shell. Edit this command with your own resource name, resource key, and operation ID.

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"

The cURL response includes the status. If the operation state is succeeded, then the resourceLocation includes the knowledge base ID.

{
   "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"
}

Publish knowledge base

Before you query the knowledge base, you need to:

  • Publish knowledge base
  • Get the runtime endpoint key

This task publishes the knowledge base. Getting the runtime endpoint key is a separate task.

Information cURL configuration Purpose
QnA Maker resource name URL used to construct URL
QnA Maker resource key -h param for Ocp-Apim-Subscription-Key header Authenticate to QnA Maker service
Knowledge base Id URL route /knowledgebases/REPLACE-WITH-YOUR-KNOWLEDGE-BASE-ID

The cURL command is executed from a BASH shell. Edit this command with your own resource name, resource key, and knowledge base ID.

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 ''

The response status is 204 with no results. Use the -v command-line parameter to see verbose output for the cURL command. This will include the HTTP status.

Get published knowledge base's runtime endpoint key

Before you query the knowledge base, you need to:

  • Publish knowledge base
  • Get the runtime endpoint key

This task getS the runtime endpoint key. Publishing the knowledge base is a separate task.

The runtime endpoint key is the same key for all knowledge bases using the QnA Maker resource.

Information cURL configuration Purpose
QnA Maker resource name URL used to construct URL
QnA Maker resource key -h param for Ocp-Apim-Subscription-Key header Authenticate to QnA Maker service

The cURL command is executed from a BASH shell. Edit this command with your own resource name, resource key.

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"

The cURL response includes the runtime endpoint keys. Use just one of the keys when querying to get an answer from the knowledge base.

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

Query for answer from published knowledge base

Getting an answer from the knowledge is done from a separate runtime than managing the knowledge base. Because it is a separate runtime, you need to authenticate with a runtime key.

Information cURL configuration Purpose
QnA Maker resource name URL used to construct URL
QnA Maker runtime key -h param for Authorization header The key is part of a string that includes the word Endpointkey . Authenticate to QnA Maker service
Knowledge base Id URL route /knowledgebases/REPLACE-WITH-YOUR-KNOWLEDGE-BASE-ID
JSON describing query -d param Request body parameters and examples of JSON
Size of the JSON in bytes -h param for Content-Size header

The cURL command is executed from a BASH shell. Edit this command with your own resource name, resource key, and knowledge base ID.

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="}'

A successful response includes the top answer along with other information a client application, such as a chat bot, needs to display an answer to the user.

Delete knowledge base

When you are done with the knowledge base, delete it.

Information cURL configuration Purpose
QnA Maker resource name URL used to construct URL
QnA Maker resource key -h param for Ocp-Apim-Subscription-Key header Authenticate to QnA Maker service
Knowledge base Id URL route /knowledgebases/REPLACE-WITH-YOUR-KNOWLEDGE-BASE-ID

The cURL command is executed from a BASH shell. Edit this command with your own resource name, resource key, and knowledge base ID.

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"

The response status is 204 with no results. Use the -v command-line parameter to see verbose output for the cURL command. This will include the HTTP status.

Additional resources

Use the QnA Maker client library for .NET to:

  • Create a knowledgebase
  • Update a knowledgebase
  • Publish a knowledgebase
  • Get prediction runtime endpoint key
  • Wait for long-running task
  • Download a knowledgebase
  • Get an answer from a knowledgebase
  • Delete a knowledgebase

Reference documentation | Library source code | Package (NuGet) | C# Samples

Note

New resources created after July 1, 2019, will use custom subdomain names. For more information and a complete list of regional endpoints, see Custom subdomain names for Azure AI services.

Prerequisites

Note

This documentation does not apply to the latest release. To learn about using the C# API with the latest release consult the question answering C# quickstart.

  • Azure subscription - Create one for free
  • The Visual Studio IDE or current version of .NET Core.
  • Once you have your Azure subscription, create a QnA Maker resource in the Azure portal to get your authoring key and resource name. After it deploys, select Go to resource.
    • You will need the key and resource name from the resource you create to connect your application to the QnA Maker API. Paste your key and resource name into the code below later in the quickstart.
    • You can use the free pricing tier (F0) to try the service, and upgrade later to a paid tier for production.

Setting up

CLI

In a console window (such as cmd, PowerShell, or Bash), use the dotnet new command to create a new console app with the name qna-maker-quickstart. This command creates a simple "Hello World" C# project with a single source file: program.cs.

dotnet new console -n qna-maker-quickstart

Change your directory to the newly created app folder. You can build the application with:

dotnet build

The build output should contain no warnings or errors.

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

Within the application directory, install the QnA Maker client library for .NET with the following command:

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

Tip

Want to view the whole quickstart code file at once? You can find it on GitHub, which contains the code examples in this quickstart.

Using directives

From the project directory, open the program.cs file and add the following using directives:

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

Subscription key and resource endpoints

In the application's Main method, add variables and code, shown in the following section, to use the common tasks in this quickstart.

  • We use subscription key and authoring key interchangeably. For more details on authoring key, follow Keys in QnA Maker.

  • The value of QNA_MAKER_ENDPOINT has the format https://YOUR-RESOURCE-NAME.cognitiveservices.azure.com. Go to the Azure portal and find the QnA Maker resource you created in the prerequisites. Select Keys and Endpoint page, under resource management to locate Authoring (Subscription) key and QnA Maker Endpoint.

QnA Maker Authoring Endpoint

  • The value of QNA_MAKER_RUNTIME_ENDPOINT has the format https://YOUR-RESOURCE-NAME.azurewebsites.net. Go to the Azure portal and find the QnA Maker resource you created in the prerequisites. Select Export Template page, under Automation to locate the Runtime Endpoint.

QnA Maker Runtime Endpoint

Important

Remember to remove the key from your code when you're done, and never post it publicly. For production, use a secure way of storing and accessing your credentials like Azure Key Vault. See the Azure AI services security article for more information.

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";

Object models

QnA Maker uses two different object models:

  • QnAMakerClient is the object to create, manage, publish, and download the knowledgebase.
  • QnAMakerRuntime is the object to query the knowledge base with the GenerateAnswer API and send new suggested questions using the Train API (as part of active learning).

Using this example knowledge base

The knowledge base in this quickstart starts with 2 conversational QnA pairs, this is done on purpose to simplify the example and to have highly predictable Ids to use in the Update method, associating follow-up prompts with questions to new pairs. This was planned and implemented in a specific order for this quickstart.

If you plan to develop your knowledge base over time with follow-up prompts that are dependent on existing QnA pairs, you may choose:

  • For larger knowledgebases, manage the knowledge base in a text editor or TSV tool that supports automation, then completely replace the knowledge base at once with an update.
  • For smaller knowledgebases, manage the follow-up prompts entirely in the QnA Maker portal.

Details about the QnA pairs used in this quickstart:

  • Types of QnA pair - there are 2 types of QnA pairs in this knowledge base, after the update: chitchat and domain-specific information. This is typical if your knowledgebase is tied to a conversation application such as a chatbot.
  • While the knowledgebase answers could be filtered by metadata or use followup prompts, this quickstart doesn't show that. Look for those language-agnostic generateAnswer examples here.
  • Answer text is markdown and can contain a wide variety of markdown such as images (publicly available internet-based images), links (to publicly available URLs), and bullet points, this quickstart doesn't use that variety.

QnAMakerClient object model

The authoring QnA Maker client is a QnAMakerClient object that authenticates to Azure using Microsoft.Rest.ServiceClientCredentials, which contains your key.

Once the client is created, use the Knowledge base property to create, manage, and publish your knowledge base.

Manage your knowledge base by sending a JSON object. For immediate operations, a method usually returns a JSON object indicating status. For long-running operations, the response is the operation ID. Call the client.Operations.GetDetailsAsync method with the operation ID to determine the status of the request.

QnAMakerRuntimeClient object model

The prediction QnA Maker client is a QnAMakerRuntimeClient object that authenticates to Azure using Microsoft.Rest.ServiceClientCredentials, which contains your prediction runtime key, returned from the authoring client call, client.EndpointKeys.GetKeys after the knowledgebase is published.

Use the GenerateAnswer method to get an answer from the query runtime.

Code examples

These code snippets show you how to do the following with the QnA Maker client library for .NET:

Authenticate the client for authoring the knowledge base

Instantiate a client object with your key, and use it with your resource to construct the endpoint to create an QnAMakerClient with your endpoint and key. Create a ServiceClientCredentials object.

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

Create a knowledge base

A knowledge base stores question and answer pairs for the CreateKbDTO object from three sources:

  • For editorial content, use the QnADTO object.
    • To use metadata and follow-up prompts, use the editorial context, because this data is added at the individual QnA pair level.
  • For files, use the FileDTO object. The FileDTO includes the filename and the public URL to reach the file.
  • For URLs, use a list of strings to represent publicly available URLs.

The creation step also includes properties for the knowledgebase:

  • defaultAnswerUsedForExtraction - what is returned when no answer is found
  • enableHierarchicalExtraction - automatically create prompt relationships between extracted QnA pairs
  • language - when creating the first knowledgebase of a resource, set the language to use in the Azure Search index.

Call the CreateAsync method then pass the returned operation ID to the MonitorOperation method to poll for status.

The final line of the following code returns the knowledge base ID from the response from 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);
}

Make sure to include the MonitorOperation function, referenced in the above code, in order to successfully create a knowledge base.

Update a knowledge base

You can update a knowledge base by passing in the knowledge base ID and an UpdatekbOperationDTO containing add, update, and delete DTO objects to the UpdateAsync method. Use the MonitorOperation method to determine if the update succeeded.

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);
}

Make sure to include the MonitorOperation function, referenced in the above code, in order to successfully update a knowledge base.

Download a knowledge base

Use the DownloadAsync method to download the database as a list of QnADocumentsDTO. This is not equivalent to the QnA Maker portal's export from the Settings page because the result of this method is not a file.

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
}

Publish a knowledge base

Publish the knowledge base using the PublishAsync method. This takes the current saved and trained model, referenced by the knowledge base ID, and publishes that at your endpoint. This is a necessary step in order to query your knowledgebase.

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

Get query runtime key

Once a knowledgebase is published, you need the query runtime key to query the runtime. This isn't the same key used to create the original client object.

Use the EndpointKeys method to get the EndpointKeysDTO class.

Use either of the key properties returned in the object to query the knowledgebase.

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

    return endpointKeysObject.PrimaryEndpointKey;
}

A runtime key is necessary to query your knowledgebase.

Authenticate the runtime for generating an answer

Create a QnAMakerRuntimeClient to query the knowledge base to generate an answer or train from active learning.

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

Use the QnAMakerRuntimeClient to:

  • get an answer from the knowledgebase
  • to send new suggested questions to the knowledge base for active learning.

Generate an answer from the knowledge base

Generate an answer from a published knowledgebase using the RuntimeClient.GenerateAnswerAsync method. This method accepts the knowledge base ID and the QueryDTO. Access additional properties of the QueryDTO, such a Top and Context to use in your chat bot.

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
}

This is a simple example querying the knowledgebase. To understand advanced querying scenarios, review other query examples.

Delete a knowledge base

Delete the knowledgebase using the DeleteAsync method with a parameter of the knowledge base ID.

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

Get status of an operation

Some methods, such as create and update, can take enough time that instead of waiting for the process to finish, an operation is returned. Use the operation ID from the operation to poll (with retry logic) to determine the status of the original method.

The loop and Task.Delay in the following code block are used to simulate retry logic. These should be replaced with your own retry logic.

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

Run the application

Run the application with the dotnet run command from your application directory.

dotnet run

The source code for this sample can be found on GitHub.

Use the QnA Maker client library for Node.js to:

  • Create a knowledgebase
  • Update a knowledgebase
  • Publish a knowledgebase
  • Get prediction runtime endpoint key
  • Wait for long-running task
  • Download a knowledgebase
  • Get an answer from a knowledgebase
  • Delete knowledge base

Reference documentation | Package (npm) | Node.js Samples

Note

New resources created after July 1, 2019, will use custom subdomain names. For more information and a complete list of regional endpoints, see Custom subdomain names for Azure AI services.

Prerequisites

  • Azure subscription - Create one for free
  • The current version of Node.js.
  • Once you have your Azure subscription, create a QnA Maker resource in the Azure portal to get your authoring key and resource. After it deploys, select Go to resource.
    • You will need the key and resource name from the resource you create to connect your application to the QnA Maker API. Paste your key and resource name into the code below later in the quickstart.
    • You can use the free pricing tier (F0) to try the service, and upgrade later to a paid tier for production.

Setting up

Create a new Node.js application

In a console window (such as cmd, PowerShell, or Bash), create a new directory for your app, and navigate to it.

mkdir qnamaker_quickstart && cd qnamaker_quickstart

Run the npm init -y command to create a node application with a package.json file.

npm init -y

Install the client library

Install the following NPM packages:

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

Your app's package.json file is updated with the dependencies.

Create a file named index.js and import the following libraries:

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

Create a variable for your resource's Azure key and resource name.

  • We use subscription key and authoring key interchangeably. For more details on authoring key, follow Keys in QnA Maker.

  • The value of QNA_MAKER_ENDPOINT has the format https://YOUR-RESOURCE-NAME.cognitiveservices.azure.com. Go to the Azure portal and find the QnA Maker resource you created in the prerequisites. Select Keys and Endpoint page, under resource management to locate Authoring (Subscription) key and QnA Maker Endpoint.

QnA Maker Authoring Endpoint

  • The value of QNA_MAKER_RUNTIME_ENDPOINT has the format https://YOUR-RESOURCE-NAME.azurewebsites.net. Go to the Azure portal and find the QnA Maker resource you created in the prerequisites. Select Export Template page, under Automation to locate the Runtime Endpoint.

QnA Maker Runtime Endpoint

Important

Remember to remove the key from your code when you're done, and never post it publicly. For production, use a secure way of storing and accessing your credentials like Azure Key Vault. See the Azure AI services security article for more information.

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";

Object models

QnA Maker uses two different object models:

  • QnAMakerClient is the object to create, manage, publish, and download the knowledgebase.
  • QnAMakerRuntime is the object to query the knowledge base with the GenerateAnswer API and send new suggested questions using the Train API (as part of active learning).

QnAMakerClient object model

The authoring QnA Maker client is a QnAMakerClient object that authenticates to Azure using your credentials, which contains your key.

Once the client is created, use the knowledgebase to create, manage, and publish your knowledge base.

Manage your knowledge base by sending a JSON object. For immediate operations, a method usually returns a JSON object indicating status. For long-running operations, the response is the operation ID. Call the client.operations.getDetails method with the operation ID to determine the status of the request.

QnAMakerRuntimeClient object model

The prediction QnA Maker client is a QnAMakerRuntimeClient object that authenticates to Azure using Microsoft.Rest.ServiceClientCredentials, which contains your prediction runtime key, returned from the authoring client call, client.EndpointKeys.getKeys after the knowledgebase is published.

Code examples

These code snippets show you how to do the following with the QnA Maker client library for .NET:

Authenticate the client for authoring the knowledge base

Instantiate a client with your endpoint and key. Create a ServiceClientCredentials object with your key, and use it with your endpoint to create an QnAMakerClient object.

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);

Create a knowledge base

A knowledge base stores question and answer pairs for the CreateKbDTO object from three sources:

  • For editorial content, use the QnADTO object.
    • To use metadata and follow-up prompts, use the editorial context, because this data is added at the individual QnA pair level.
  • For files, use the FileDTO object. The FileDTO includes the filename and the public URL to reach the file.
  • For URLs, use a list of strings to represent publicly available URLs.

The creation step also includes properties for the knowledgebase:

  • defaultAnswerUsedForExtraction - what is returned when no answer is found
  • enableHierarchicalExtraction - automatically create prompt relationships between extracted QnA pairs
  • language - when creating the first knowledgebase of a resource, set the language to use in the Azure Search index.

Call the create method with the knowledge base information. The knowledge base information is basically a JSON object.

When the create method returns, pass the returned operation ID to the wait_for_operation method to poll for status. The wait_for_operation method returns when the operation completes. Parse the resourceLocation header value of the returned operation to get the new knowledge base ID.

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

Make sure to include the wait_for_operation function, referenced in the above code, in order to successfully create a knowledge base.

Update a knowledge base

You can update a knowledge base by passing in the knowledge base ID and an UpdateKbOperationDTO containing add, update, and delete DTO objects to the update method. The DTOs are also basically JSON objects. Use the wait_for_operation method to determine if the update succeeded.

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
}

Make sure the include the wait_for_operation function, referenced in the above code, in order to successfully update a knowledge base.

Download a knowledge base

Use the download method to download the database as a list of QnADocumentsDTO. This is not equivalent to the QnA Maker portal's export from the Settings page because the result of this method is not a TSV file.

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 a knowledge base

Publish the knowledge base using the publish method. This takes the current saved and trained model, referenced by the knowledge base ID, and publishes that at an endpoint. Check the HTTP response code to validate that the publish succeeded.

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
}

Query a knowledge base

Get query runtime key

Once a knowledgebase is published, you need the query runtime key to query the runtime. This isn't the same key used to create the original client object.

Use the EndpointKeys.getKeys method to get the EndpointKeysDTO class.

Use either of the key properties returned in the object to query the knowledgebase.

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
}

Authenticate the runtime for generating an answer

Create a QnAMakerRuntimeClient to query the knowledge base to generate an answer or train from active learning.

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

Use the QnAMakerRuntimeClient to get an answer from the knowledge or to send new suggested questions to the knowledge base for active learning.

Generate an answer from the knowledge base

Generate an answer from a published knowledge base using the RuntimeClient.runtime.generateAnswer method. This method accepts the knowledge base ID and the QueryDTO. Access additional properties of the QueryDTO, such a Top and Context to use in your chat bot.

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));

}

This is a simple example querying the knowledge base. To understand advanced querying scenarios, review other query examples.

Delete a knowledge base

Delete the knowledge base using the delete method with a parameter of the knowledge base ID.

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
}

Get status of an operation

Some methods, such as create and update, can take enough time that instead of waiting for the process to finish, an operation is returned. Use the operation ID from the operation to poll (with retry logic) to determine the status of the original method.

The delayTimer call in the following code block is used to simulate the retry logic. Replace this with your own retry logic.

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);
    });
}

Run the application

Run the application with node index.js command from your application directory.

node index.js

The source code for this sample can be found on GitHub.

Use the QnA Maker client library for Python to:

  • Create a knowledgebase
  • Update a knowledgebase
  • Publish a knowledgebase
  • Get prediction runtime endpoint key
  • Wait for long-running task
  • Download a knowledgebase
  • Get an answer from a knowledgebase
  • Delete knowledge base

Reference documentation | Library source code | Package (PyPi) | Python samples

Note

New resources created after July 1, 2019, will use custom subdomain names. For more information and a complete list of regional endpoints, see Custom subdomain names for Azure AI services.

Prerequisites

Note

This documentation does not apply to the latest release. To learn about using the Python API with the latest release consult the question answering Python quickstart.

  • Azure subscription - Create one for free
  • Python 3.x
  • Once you have your Azure subscription, create a QnA Maker resource in the Azure portal to get your authoring key and endpoint. After it deploys, select Go to resource.
    • You will need the key and endpoint from the resource you create to connect your application to the QnA Maker API. You'll paste your key and endpoint into the code below later in the quickstart.
    • You can use the free pricing tier (F0) to try the service, and upgrade later to a paid tier for production.

Setting up

Install the client library

After installing Python, you can install the client library with:

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

Create a new Python application

Create a new Python file named quickstart-file.py and import the following libraries.

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

Create variables for your resource's Azure endpoint and key.

  • We use subscription key and authoring key interchangeably. For more details on authoring key, follow Keys in QnA Maker.

  • The value of QNA_MAKER_ENDPOINT has the format https://YOUR-RESOURCE-NAME.cognitiveservices.azure.com. Go to the Azure portal and find the QnA Maker resource you created in the prerequisites. Select Keys and Endpoint page, under resource management to locate Authoring (Subscription) key and QnA Maker Endpoint.

QnA Maker Authoring Endpoint

  • The value of QNA_MAKER_RUNTIME_ENDPOINT has the format https://YOUR-RESOURCE-NAME.azurewebsites.net. Go to the Azure portal and find the QnA Maker resource you created in the prerequisites. Select Export Template page, under Automation to locate the Runtime Endpoint.

QnA Maker Runtime Endpoint

Important

Remember to remove the key from your code when you're done, and never post it publicly. For production, use a secure way of storing and accessing your credentials like Azure Key Vault. See the Azure AI services security article for more information.

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'

Object models

QnA Maker uses two different object models:

  • QnAMakerClient is the object to create, manage, publish, and download the knowledgebase.
  • QnAMakerRuntime is the object to query the knowledge base with the GenerateAnswer API and send new suggested questions using the Train API (as part of active learning).

Using this example knowledge base

The knowledge base in this quickstart starts with 2 conversational QnA pairs, this is done on purpose to simplify the example and to have highly predictable Ids to use in the Update method, associating follow-up prompts with questions to new pairs. This was planned and implemented in a specific order for this quickstart.

If you plan to develop your knowledge base over time with follow-up prompts that are dependent on existing QnA pairs, you may choose:

  • For larger knowledgebases, manage the knowledge base in a text editor or TSV tool that supports automation, then completely replace the knowledge base at once with an update.
  • For smaller knowledgebases, manage the follow-up prompts entirely in the QnA Maker portal.

Details about the QnA pairs used in this quickstart:

  • Types of QnA pair - there are 2 types of QnA pairs in this knowledge base, after the update: chitchat and domain-specific information. This is typical if your knowledgebase is tied to a conversation application such as a chatbot.
  • While the knowledgebase answers could be filtered by metadata or use followup prompts, this quickstart doesn't show that. Look for those language-agnostic generateAnswer examples here.
  • Answer text is markdown and can contain a wide variety of markdown such as images (publicly available internet-based images), links (to publicly available URLs), and bullet points, this quickstart doesn't use that variety.

QnAMakerClient object model

The authoring QnA Maker client is a QnAMakerClient object that authenticates to Azure using Microsoft.Rest.ServiceClientCredentials, which contains your key.

Once the client is created, use the Knowledge base property to create, manage, and publish your knowledge base.

Manage your knowledge base by sending a JSON object. For immediate operations, a method usually returns a JSON object indicating status. For long-running operations, the response is the operation ID. Call the operations.get_details method with the operation ID to determine the status of the request.

QnAMakerRuntimeClient object model

The prediction QnA Maker client is a QnAMakerRuntimeClient object that authenticates to Azure using Microsoft.Rest.ServiceClientCredentials, which contains your prediction runtime key, returned from the authoring client call, client.EndpointKeysOperations.get_keys after the knowledgebase is published.

Use the generate_answer method to get an answer from the query runtime.

Authenticate the client for authoring the knowledge base

Instantiate a client with your endpoint and key. Create a CognitiveServicesCredentials object with your key, and use it with your endpoint to create an QnAMakerClient object.

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

Create a knowledge base

Use the client object to get a knowledge base operations object.

A knowledge base stores question and answer pairs for the CreateKbDTO object from three sources:

  • For editorial content, use the QnADTO object.
    • To use metadata and follow-up prompts, use the editorial context, because this data is added at the individual QnA pair level.
  • For files, use the FileDTO object. The FileDTO includes the filename and the public URL to reach the file.
  • For URLs, use a list of strings to represent publicly available URLs.

Call the create method then pass the returned operation ID to the Operations.getDetails method to poll for status.

The final line of the following code returns the knowledge base ID from the response from 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

Make sure the include the _monitor_operation function, referenced in the above code, in order to successfully create a knowledge base.

Update a knowledge base

You can update a knowledge base by passing in the knowledge base ID and an UpdateKbOperationDTO containing add, update, and delete DTO objects to the update method. Use the Operation.getDetail method to determine if the update succeeded.

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.")

Make sure the include the _monitor_operation function, referenced in the above code, in order to successfully update a knowledge base.

Download a knowledge base

Use the download method to download the database as a list of QnADocumentsDTO. This is not equivalent to the QnA Maker portal's export from the Settings page because the result of this method is not a TSV file.

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 a knowledge base

Publish the knowledge base using the publish method. This takes the current saved and trained model, referenced by the knowledge base ID, and publishes that at an endpoint.

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

Query a knowledge base

Get query runtime key

Once a knowledgebase is published, you need the query runtime key to query the runtime. This isn't the same key used to create the original client object.

Use the EndpointKeysOperations.get_keys method to get the EndpointKeysDTO class.

Use either of the key properties returned in the object to query the knowledgebase.

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

Authenticate the runtime for generating an answer

Create a QnAMakerRuntimeClient to query the knowledge base to generate an answer or train from active learning.

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

Use the QnAMakerRuntimeClient to get an answer from the knowledge or to send new suggested questions to the knowledge base for active learning.

Generate an answer from the knowledge base

Generate an answer from a published knowledge base using the QnAMakerRuntimeClient.runtime.generate_answer method. This method accepts the knowledge base ID and the QueryDTO. Access additional properties of the QueryDTO, such a Top and Context to use in your chat bot.

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}.")

This is a simple example of querying the knowledge base. To understand advanced querying scenarios, review other query examples.

Delete a knowledge base

Delete the knowledge base using the delete method with a parameter of the knowledge base ID.

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

Get status of an operation

Some methods, such as create and update, can take enough time that instead of waiting for the process to finish, an operation is returned. Use the operation ID from the operation to poll (with retry logic) to determine the status of the original method.

The setTimeout call in the following code block is used to simulate asynchronous code. Replace this with retry logic.

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

Run the application

Run the application with the Python command on your quickstart file.

python quickstart-file.py

The source code for this sample can be found on GitHub.

Use the QnA Maker client library for Java to:

  • Create a knowledgebase
  • Update a knowledgebase
  • Publish a knowledgebase
  • Get prediction runtime endpoint key
  • Wait for long-running task
  • Download a knowledgebase
  • Get an answer from a knowledgebase
  • Delete knowledge base

Library source code | Package | Samples

Note

New resources created after July 1, 2019, will use custom subdomain names. For more information and a complete list of regional endpoints, see Custom subdomain names for Azure AI services.

Prerequisites

  • Azure subscription - Create one for free
  • JDK
  • Once you have your Azure subscription, create a QnA Maker resource in the Azure portal to get your authoring key and endpoint. After it deploys, select Go to resource.
    • You will need the key and endpoint from the resource you create to connect your application to the QnA Maker API. Paste your key and endpoint into the code below later in the quickstart.
    • You can use the free pricing tier (F0) to try the service, and upgrade later to a paid tier for production.

Setting up

Install the client libraries

After installing Java, you can install the client libraries using Maven from MVN Repository.

Create a new Java application

Create a new file named quickstart.java and import the following libraries.

/* 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.*;

Create variables for your resource's Azure endpoint and key.

  • We use subscription key and authoring key interchangeably. For more details on authoring key, follow Keys in QnA Maker.

  • The value of QNA_MAKER_ENDPOINT has the format https://YOUR-RESOURCE-NAME.cognitiveservices.azure.com. Go to the Azure portal and find the QnA Maker resource you created in the prerequisites. Select Keys and Endpoint page, under resource management to locate Authoring (Subscription) key and QnA Maker Endpoint.

QnA Maker Authoring Endpoint

  • The value of QNA_MAKER_RUNTIME_ENDPOINT has the format https://YOUR-RESOURCE-NAME.azurewebsites.net. Go to the Azure portal and find the QnA Maker resource you created in the prerequisites. Select Export Template page, under Automation to locate the Runtime Endpoint.

QnA Maker Runtime Endpoint

Important

Remember to remove the key from your code when you're done, and never post it publicly. For production, use a secure way of storing and accessing your credentials like Azure Key Vault. See the Azure AI services security article for more information.

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";

Object models

QnA Maker uses two different object models:

  • QnAMakerClient is the object to create, manage, publish, and download the knowledgebase.
  • QnAMakerRuntime is the object to query the knowledge base with the GenerateAnswer API and send new suggested questions using the Train API (as part of active learning).

Using this example knowledge base

The knowledge base in this quickstart starts with 2 conversational QnA pairs, this is done on purpose to simplify the example and to have highly predictable Ids to use in the Update method, associating follow-up prompts with questions to new pairs. This was planned and implemented in a specific order for this quickstart.

If you plan to develop your knowledge base over time with follow-up prompts that are dependent on existing QnA pairs, you may choose:

  • For larger knowledgebases, manage the knowledge base in a text editor or TSV tool that supports automation, then completely replace the knowledge base at once with an update.
  • For smaller knowledgebases, manage the follow-up prompts entirely in the QnA Maker portal.

Details about the QnA pairs used in this quickstart:

  • Types of QnA pair - there are 2 types of QnA pairs in this knowledge base, after the update: chitchat and domain-specific information. This is typical if your knowledgebase is tied to a conversation application such as a chatbot.
  • While the knowledgebase answers could be filtered by metadata or use followup prompts, this quickstart doesn't show that. Look for those language-agnostic generateAnswer examples here.
  • Answer text is markdown and can contain a wide variety of markdown such as images (publicly available internet-based images), links (to publicly available URLs), and bullet points, this quickstart doesn't use that variety.

QnAMakerClient object model

The authoring QnA Maker client is a QnAMakerClient object that authenticates to Azure using MsRest::ServiceClientCredentials, which contains your key.

Once the client is created, use the methods of the client's Knowledgebases property to create, manage, and publish your knowledge base.

For immediate operations, a method usually returns the result, if any. For long-running operations, the response is an Operation object. Call the getDetails method with the operation.operationId value to determine the status of the request.

QnAMakerRuntimeClient object model

The runtime QnA Maker client is a QnAMakerRuntimeClient object.

After you publish your knowledge base using the authoring client, use the runtime client's generateAnswer method to get an answer from the knowledge base.

You create a runtime client by calling QnAMakerRuntimeManager.authenticate and passing a runtime endpoint key. To obtain the runtime endpoint key, use the authoring client to call getKeys.

Authenticate the client for authoring the knowledge base

Instantiate a client with your authoring endpoint and subscription key.

/* 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();

Create a knowledge base

A knowledge base stores question and answer pairs for the CreateKbDTO object from three sources:

  • For editorial content, use the QnADTO object.
    • To use metadata and follow-up prompts, use the editorial context, because this data is added at the individual QnA pair level.
  • For files, use the FileDTO object. The FileDTO includes the filename and the public URL to reach the file.
  • For URLs, use a list of strings to represent publicly available URLs.

Call the create method then pass the operationId property of the returned operation to the getDetails method to poll for status.

The final line of the following code returns the knowledge base ID.

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 a knowledge base

You can update a knowledge base by calling update and passing in the knowledge base ID and an UpdateKbOperationDTO object. That object in turn can contain:

Pass the operationId property of the returned operation to the getDetails method to poll for status.

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 a knowledge base

Use the download method to download the database as a list of QnADocumentsDTO. This is not equivalent to the QnA Maker portal's export from the Settings page because the result of this method is not a TSV file.

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 a knowledge base

Publish the knowledge base using the publish method. This takes the current saved and trained model, referenced by the knowledge base ID, and publishes that at an endpoint.

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

Generate an answer from the knowledge base

Once a knowledge base is published, you need the runtime endpoint key to query the knowledge base. This is not the same as the subscription key used to create the authoring client.

Use the getKeys method to get an EndpointKeysDTO object.

Create a runtime client by calling QnAMakerRuntimeManager.authenticate and passing a runtime endpoint key from the EndpointKeysDTO object.

Generate an answer from a published knowledge base using the generateAnswer method. This method accepts the knowledge base ID and a QueryDTO object.

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();
}

This is a simple example of querying a knowledge base. To understand advanced querying scenarios, review other query examples.

Delete a knowledge base

Delete the knowledge base using the delete method with a parameter of the knowledge base ID.

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

Get status of an operation

Some methods, such as create and update, can take enough time that instead of waiting for the process to finish, an operation is returned. Use the operation ID from the operation to poll (with retry logic) to determine the status of the original method.

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

Run the application

Here is the main method for the application.

    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();
        }
    }

Run the application as follows. This presumes your class name is Quickstart and your dependencies are in a subfolder named lib below the current folder.

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

The source code for this sample can be found on GitHub.

Clean up resources

If you want to clean up and remove an Azure AI services subscription, you can delete the resource or resource group. Deleting the resource group also deletes any other resources associated with it.

Next steps