Quickstart: QnA Maker client library for .NET

Get started with the QnA Maker client library for .NET. Follow these steps to install the package and try out the example code for basic tasks. QnA Maker enables you to power a question-and-answer service from your semi-structured content like FAQ documents, URLs, and product manuals.

Use the QnA Maker client library for .NET to:

  • Create a knowledge base
  • Manage a knowledge base
  • Publish a knowledge base
  • Generate an answer from the knowledge base

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 Cognitive Services.

Prerequisites

Setting up

Create a QnA Maker Azure resource

Azure Cognitive Services are represented by Azure resources that you subscribe to. Create a resource for QnA Maker using the Azure portal or Azure CLI on your local machine.

After getting a key and endpoint for your resource, create environment variables for the key, named QNAMAKER_SUBSCRIPTION_KEY. The resource name is used as part of the endpoint URL.

Create a new C# application

Create a new .NET Core application in your preferred editor or IDE.

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

Install the SDK

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 1.0.0

If you're using the Visual Studio IDE, the client library is available as a downloadable NuGet package.

Object model

The 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.

Code examples

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

Add the dependencies

From the project directory, open the Program.cs file in your preferred editor or IDE. Replace the existing using code with 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.Linq;
using System.Threading.Tasks;

Authenticate the client for authoring the knowledge base

In the main method, create a variable for your resource's Azure key pulled from an environment variable named QNAMAKER_SUBSCRIPTION_KEY. If you created the environment variable after the application is launched, the editor, IDE, or shell running it will need to be closed and reloaded to access the variable. The methods will be created later.

Next, create an ApiKeyServiceClientCredentials object with your key, and use it with your endpoint to create an QnAMakerClient object.

Change the Endpoint variable, <your-custom-domain>, to the name of your custom domain. This location is found on the Overview page for your QnA Maker resource in the Azure portal.

var subscriptionKey = Environment.GetEnvironmentVariable("QNAMAKER_SUBSCRIPTION_KEY");
var client = new QnAMakerClient(new ApiKeyServiceClientCredentials(subscriptionKey)) { Endpoint = "https://<your-custom-domain>.api.cognitive.microsoft.com" };

Authenticate the runtime for generating an answer

In the main method, create a variable for your resource's authentication pulled from an environment variables named QNAMAKER_ENDPOINT_HOSTNAME and QNAMAKER_ENDPOINT_KEY. When you publish your knowledge base, these values are returned. After you publish, you can find these settings on the Settings page of the QnA Maker portal.

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

var endpointhostName = Environment.GetEnvironmentVariable("QNAMAKER_ENDPOINT_HOSTNAME");
var endpointKey = Environment.GetEnvironmentVariable("QNAMAKER_ENDPOINT_KEY");
var runtimeClient = new QnAMakerRuntimeClient(new EndpointKeyServiceClientCredentials(endpointKey)) { RuntimeEndpoint = $"https://{endpointhostName}.azurewebsites.net" };

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.
  • For files, use the FileDTO object.
  • For URLs, use a list of strings.

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 MonitorOoperation.

private static async Task<string> CreateSampleKb(IQnAMakerClient client)
{
    var qna1 = new QnADTO
    {
        Answer = "You can use our REST APIs 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" } }    
    };
    
    var file1 = new FileDTO
    {
        FileName="myFileName",
        FileUri="https://mydomain/myfile.md"

    };

    var urls = new List<string> {
        "https://docs.microsoft.com/en-in/azure/cognitive-services/qnamaker/faqs"
    };

    var createKbDto = new CreateKbDTO
    {
        Name = "QnA Maker FAQ from c# quickstart",
        QnaList = new List<QnADTO> { qna1 },
        //Files = new List<FileDTO> { file1 },
        Urls = urls

    };

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

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

Make sure the 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)
{
    // Update kb
    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" }, Answer = "goodbye" } } }, 
        Update = null,
        Delete = null
    });

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

Make sure the 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 TSV file.

Console.Write("Downloading KB...");
var kbData = client.Knowledgebase.DownloadAsync(kbId, EnvironmentType.Prod).Result;
Console.WriteLine("KB Downloaded. It has {0} QnAs.", kbData.QnaDocuments.Count);

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 an endpoint.

Console.Write("Publishing KB...");
client.Knowledgebase.PublishAsync(kbId).Wait();
Console.WriteLine("KB Published.");

Generate an answer from the knowledge base

Generate an answer from a published knowledge base 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.

Console.Write("Querying Endpoint...");
var response = runtimeClient.Runtime.GenerateAnswerAsync(kbId, new QueryDTO { Question = "How do I manage my knowledgebase?" }).Result;
Console.WriteLine("Endpoint Response: {0}.", response.Answers[0].Answer);

Delete a knowledge base

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

Console.Write("Deleting KB...");
client.Knowledgebase.DeleteAsync(kbId).Wait();
Console.WriteLine("KB Deleted.");            

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.

All of the code snippets in this article are available and can be run as a single file.

dotnet run

The source code for this quickstart is available in the QnA Maker C# samples GitHub repository.

Clean up resources

If you want to clean up and remove a Cognitive Services subscription, you can delete the resource or resource group. Deleting the resource group also deletes any other resources associated with it.

Next steps