Tutorial: Use QnA Maker in your bot to answer questions
Artikel
11 minit untuk dibaca
APPLIES TO: SDK v4
You can use the QnA Maker service to create a knowledge base to add question-and-answer support to your bot. When you create your knowledge base, you seed it with questions and answers.
In this tutorial, you learn how to:
Create a QnA Maker service and knowledge base
Add knowledge base information to your configuration file
Update your bot to query the knowledge base
Republish your bot
If you don't have an Azure subscription, create a free account before you begin.
Prerequisites
The bot created in the previous tutorial. You'll add a question-and-answer feature to the bot.
Some familiarity with QnA Maker is helpful. You'll use the QnA Maker portal to create, train, and publish the knowledge base to use with the bot.
Connect your QnA Maker service to your knowledge base.
Name your knowledge base.
To populate your knowledge base, use the smartLightFAQ.tsv file from the samples repo. If you've downloaded the samples, upload the file smartLightFAQ.tsv from your computer.
Select Create your kb to create the knowledge base.
Select Save and train.
Select PUBLISH to publish your knowledge base.
Once your QnA Maker app is published, select SETTINGS, and scroll down to Deployment details. Copy the following values from the Postman HTTP example request.
POST /knowledgebases/<knowledge-base-id>/generateAnswer
Host: <your-hostname> // NOTE - this is a URL ending in /qnamaker.
Authorization: EndpointKey <qna-maker-resource-key>
The full URL string for your hostname will look like "https://<knowledge-base-name>.azure.net/qnamaker".
These values will be used within your bot configuration file in the next step.
The knowledge base is now ready for your bot to use.
Add knowledge base information to your bot
Use the following instructions connect your C#, JavaScript, Java, or Python bot to your knowledge base.
Add the following values to your appsetting.json file:
{
"MicrosoftAppId": "",
"MicrosoftAppPassword": "",
"ScmType": "None",
"QnAKnowledgebaseId": "knowledge-base-id",
"QnAAuthKey": "qna-maker-resource-key",
"QnAEndpointHostName": "your-hostname" // This is a URL ending in /qnamaker
}
Add the following values to your .env file:
MicrosoftAppId=""
MicrosoftAppPassword=""
ScmType=None
QnAKnowledgebaseId="knowledge-base-id"
QnAAuthKey="qna-maker-resource-key"
QnAEndpointHostName="your-hostname" // This is a URL ending in /qnamaker
Add the following values to your application.properties file:
MicrosoftAppId=
MicrosoftAppPassword=
QnAKnowledgebaseId="knowledge-base-id"
QnAEndpointKey="qna-maker-resource-key"
QnAEndpointHostName="your-hostname" // This is a URL ending in /qnamaker
server.port=3978
Field
Value
QnAKnowledgebaseId
The knowledge base ID that the QnA Maker portal generated for you.
QnAAuthKey (QnAEndpointKey in Python)
The endpoint key that the QnA Maker portal generated for you.
QnAEndpointHostName
The host URL that the QnA Maker portal generated. Use the complete URL, starting with https:// and ending with /qnamaker. The full URL string will look like "https://<knowledge-base-name>.azure.net/qnamaker".
Now save your edits.
Update your bot to query the knowledge base
Update your initialization code to load the service information for your knowledge base.
In your Startup.cs file, add the following namespace reference.
Startup.cs
using Microsoft.Bot.Builder.AI.QnA;
Modify the ConfigureServices method in Startup.cs to create a QnAMakerEndpoint object that connects to the knowledge base defined in the appsettings.json file.
In your EchoBot.cs file, add the following namespace references.
Bots\EchoBot.cs
using System.Linq;
using Microsoft.Bot.Builder.AI.QnA;
Add an EchoBotQnA property and add a constructor to initialize it.
EchoBot.cs
public QnAMaker EchoBotQnA { get; private set; }
public EchoBot(QnAMakerEndpoint endpoint)
{
// connects to QnA Maker endpoint for each turn
EchoBotQnA = new QnAMaker(endpoint);
}
Add an AccessQnAMaker method:
EchoBot.cs
private async Task AccessQnAMaker(ITurnContext<IMessageActivity> turnContext, CancellationToken cancellationToken)
{
var results = await EchoBotQnA.GetAnswersAsync(turnContext);
if (results.Any())
{
await turnContext.SendActivityAsync(MessageFactory.Text("QnA Maker Returned: " + results.First().Answer), cancellationToken);
}
else
{
await turnContext.SendActivityAsync(MessageFactory.Text("Sorry, could not find an answer in the knowledge base."), cancellationToken);
}
}
Update the OnMessageActivityAsync method to call the new AccessQnAMaker method.
Open a terminal or command prompt to the root directory for your project.
Add the botbuilder-ai npm package to your project.
npm i botbuilder-ai
In index.js, following the call to create the BotFrameworkAdapter, add the following code to read your .env file configuration information needed to generate the QnA Maker services.
index.js
// Map knowledge base endpoint values from .env file into the required format for `QnAMaker`.
const configuration = {
knowledgeBaseId: process.env.QnAKnowledgebaseId,
endpointKey: process.env.QnAAuthKey,
host: process.env.QnAEndpointHostName
};
Modify the call to create the bot to pass in the QnA services configuration information.
index.js
// Create the main dialog.
const myBot = new EchoBot(configuration, {});
In your bot.js file, import `QnAMaker from botbuilder-ai.
bot.js
const { QnAMaker } = require('botbuilder-ai');
Modify the constructor to take the configuration parameters required to create a QnA Maker connector and throw an error if these parameters aren't provided.
bot.js
class EchoBot extends ActivityHandler {
constructor(configuration, qnaOptions) {
super();
if (!configuration) throw new Error('[QnaMakerBot]: Missing parameter. configuration is required');
// now create a QnAMaker connector.
this.qnaMaker = new QnAMaker(configuration, qnaOptions);
Finally in bot.js, update your onMessage function to query your knowledge bases for an answer. Pass each user input to your QnA Maker knowledge base, and return the first QnA Maker response back to the user.
this.onMessage(async (context, next) => {
const replyText = `Echo: ${ context.activity.text }`;
await context.sendActivity(MessageFactory.text(replyText, replyText));
// send user input to QnA Maker.
const qnaResults = await this.qnaMaker.getAnswers(context);
// If an answer was received from QnA Maker, send the answer back to the user.
if (qnaResults[0]) {
await context.sendActivity(`QnA Maker Returned: ' ${ qnaResults[0].answer}`);
}
else {
// If no answers were returned from QnA Maker, reply with help.
await context.sendActivity('No QnA Maker response was returned.'
+ 'This example uses a QnA Maker Knowledge Base that focuses on smart light bulbs. '
+ `Ask the bot questions like "Why won't it turn on?" or "I need help."`);
}
await next();
});
Add the com.microsoft.bot.bot-ai-qna package to your project.
To do this, add the package to your Maven pom.xml file:
Make sure you've installed the packages as described in the samples repository README file.
Add the botbuilder-ai reference to the requirements.txt file, as shown below.
requirements.txt
botbuilder-core
botbuilder-ai
flask
Notice that the versions may vary.
In the app.py file, modify the bot instance creation as shown below.
# Create the bot
BOT = EchoBot(CONFIG)
In the bot.py file import QnAMaker and QnAMakerEndpoint from botbuilder.ai.qna, then Config from flask, as shown below.
bot.py
from flask import Config
from botbuilder.ai.qna import QnAMaker, QnAMakerEndpoint
from botbuilder.core import ActivityHandler, MessageFactory, TurnContext
from botbuilder.schema import ChannelAccount
Next, in bot.py_ add an __init__ function to instantiate a qna-maker object. Using the configuration parameters provided in the config.py file.
Next, in bot.py, update on_message_activity to query your knowledge base for an answer. Pass each user input to your QnA Maker knowledge base, and return the first QnA Maker response to the user.
bot.py
async def on_message_activity(self, turn_context: TurnContext):
# The actual call to the QnA Maker service.
response = await self.qna_maker.get_answers(turn_context)
if response and len(response) > 0:
await turn_context.send_activity(MessageFactory.text(response[0].answer))
else:
await turn_context.send_activity("No QnA Maker answers were found.")
Optionally, update the welcome message in on_members_added_activity for example:
bot.py
await turn_context.send_activity("Hello and welcome to QnA!")
Test your bot locally
At this point, your bot should be able to answer some questions. Run the bot locally and open it in the Bot Framework Emulator.
Republish your bot
Now you can republish your bot back to Azure. Zip your project folder and then run the command to redeploy your bot.
Prepare your project files
Prepare your project files before you deploy your bot.
Switch to your project's root folder. For C#, the root is the folder that contains the .csproj file.
Do a clean rebuild in release mode.
If you haven't done so before, run az bot prepare-deploy to add required files to the root of your local source code directory.
This command generates a .deployment file in your bot project folder.
az bot prepare-deploy --lang Csharp --code-dir "." --proj-file-path "<my-cs-proj>"
Option
Description
lang
The language or runtime of the bot. Use Csharp.
code-dir
The directory to place the generated deployment files in. Use your project's root folder. Default is the current directory.
proj-file-path
The path to the .csproj file for your bot, relative to the code-dir option.
Within your project's root folder, create a zip file that contains all files and subfolders.
Switch to your project's root folder.
For JavaScript, the root is the folder that contains the app.js or index.js file.
For TypeScript, the root is the folder that contains the src folder (where the bot.ts and index.ts files are).
Run npm install.
If you haven't done so before, run az bot prepare-deploy to add required files to the root of your local source code directory.
This command generates a web.config file in your project folder.
Azure App Services requires each Node.js bot to include a web.config file in its project root folder.
az bot prepare-deploy --lang <language> --code-dir "."
Option
Description
lang
The language or runtime of the bot. Use Javascript or Typescript.
code-dir
The directory to place the generated deployment files in. Use your project's root folder. Default is the current directory.
Within your project's root folder, create a zip file that contains all files and subfolders.
Switch to your project's root folder.
In the project directory, run the following command from the command line:
mvn clean package
Tip
For Python bots, dependency installation is performed on the server.
The ARM templates require your dependencies to be listed in a requirements.txt file.
If you're using a dependency and package manager:
Convert your dependencies list to a requirements.txt file
Add requirements.txt to the folder that contains app.py.
Within your project's root folder, create a zip file that contains all files and subfolders.
Republish your bot
Tip
If your session token expired, run az login again. If you aren't using your default subscription, also reset your subscription.
At this point, we are ready to deploy the code to the Azure Web App.
The name of the Azure resource group that contains your bot.
Dbotname
Name of the Web App you used earlier.
Note
This step can take a few minutes to complete.
Also it can take a few more minutes between when the deployment finishes and when your bot is available to test.
Clean up resources
If you aren't going to use this application again, delete the associated resources with the following steps:
In the Azure portal, open the resource group for your bot.
Select Delete resource group to delete the group and all the resources it contains.
Enter the resource group name in the confirmation pane, then select Delete.
If you created a single-tenant or multi-tenant app:
Go to the Azure Active Directory blade.
Locate the app registration you used for your bot, and delete it.
Next steps
For information on how to add features to your bot, see the Send and receive text message article and the other articles in the how-to develop section.