您现在访问的是微软AZURE全球版技术文档网站,若需要访问由世纪互联运营的MICROSOFT AZURE中国区技术文档网站,请访问 https://docs.azure.cn.

向机器人添加自然语言理解Add natural language understanding to your bot

适用于: 是SDK v4 否SDK v3 APPLIES TO: yesSDK v4 no SDK v3

理解用户在会话和上下文中表达的含义是一项艰巨的任务,但可以让机器人更自然地进行聊天。The ability to understand what your user means conversationally and contextually can be a difficult task, but can provide your bot a more natural conversation feel. 使用语言理解(称为 LUIS)能够实现此目标,使机器人能够识别用户消息的意向,接收用户更自然的语言,并更好地指导会话流程。Language Understanding, called LUIS, enables you to do just that so that your bot can recognize the intent of user messages, allow for more natural language from your user, and better direct the conversation flow. 本主题详细介绍如何将 LUIS 添加到航班预订应用程序,以便识别用户输入中包含的不同意向和实体。This topic walks you through adding LUIS to a flight booking application to recognize different intents and entities contained within user input.

先决条件Prerequisites

关于此示例About this sample

此核心机器人编码示例演示了飞机航班预订应用程序的示例。This core bot coding sample shows an example of an airport flight booking application. 它使用 LUIS 服务来识别用户输入,并返回排名靠前的已识别 LUIS 意向。It uses a LUIS service to recognize the user input and return the top recognized LUIS intent.

每次处理用户输入以后,DialogBot 都会保存 UserStateConversationState 的当前状态。After each processing of user input, DialogBot saves the current state of both UserState and ConversationState. 收集所有必需的信息以后,编码示例会创建一个演示版的航班预订。Once all the required information has been gathered the coding sample creates a demo flight booking reservation. 在本文中,我们将介绍此示例 LUIS 方面的内容。In this article we'll be covering the LUIS aspects of this sample. 但是,示例的常规流程如下所示:However, the general flow of the sample is shown below:

  • 连接新用户时,会调用 OnMembersAddedAsync 并显示欢迎卡片。OnMembersAddedAsync is called when a new user is connected and displays a welcome card.
  • 每次收到用户输入都会调用 OnMessageActivityAsyncOnMessageActivityAsync is called for each user input received.

LUIS 示例逻辑流

OnMessageActivityAsync 模块通过 Run 对话扩展方法运行相应的对话。The OnMessageActivityAsync module runs the appropriate dialog through the Run dialog extension method. 然后,主对话会调用 LUIS 帮助程序来查找排名靠前的评分用户意向。Then the main dialog calls the LUIS helper to find the the top scoring user intent. 如果用户输入的排名靠前的意向返回“BookFlight”,则帮助程序会填充 LUIS 返回的用户的信息。If the top intent for the user input returns "BookFlight", the helper fills out information from the user that LUIS returned. 然后,主对话启动 BookingDialog,后者会根据需要从用户获取其他信息,例如:After that, the nain dialog starts the BookingDialog, which acquires additional information as needed from the user such as:

  • Origin 始发城市Origin the originating city
  • TravelDate 预订航班的日期TravelDate the date to book the flight
  • Destination 目标城市Destination the destination city

若要详细了解示例的其他方面,例如对话或状态,请参阅使用对话提示收集用户输入保存用户和聊天数据For details on the other aspects of the sample like dialogs or state, see Gather user input using a dialog prompt or Save user and conversation data.

在 LUIS 门户中创建 LUIS 应用Create a LUIS app in the LUIS portal

登录到 LUIS 门户,以创建自己的示例 LUIS 应用版本。Sign in to the LUIS portal to create your own version of the sample LUIS app. 可在“我的应用”中创建和管理应用程序 。You can create and manage your applications on My Apps.

  1. 选择“导入新应用”。 Select Import new app.
  2. 单击“选择应用文件(JSON 格式)...” Click Choose App file (JSON format)...
  3. 选择示例的 CognitiveModels 文件夹中的 FlightBooking.json 文件。Select FlightBooking.json file located in the CognitiveModels folder of the sample. 在“可选名称”中,输入 FlightBookingIn the Optional Name, enter FlightBooking. 此文件包含三个意向:“预订航班”、“取消”和“None”。This file contains three intents: 'Book Flight', 'Cancel', and 'None'. 当用户向机器人发送消息时,我们将使用这些意向来了解其意图。We'll use these intents to understand what the user meant when they send a message to the bot.
  4. 训练应用。Train the app.
  5. 将应用发布到生产环境。 Publish the app to production environment.

为何使用实体Why use entities

LUIS 实体可让机器人智能理解不同于标准意向的某些事物或事件。LUIS entities allow your bot to intelligently understand certain things or events that are different than the standard intents. 这样,你便可以从用户收集额外的信息,让机器人以更高的智能做出响应,或者在某些情况下跳过它向用户提出的有关该信息的问题。This enables you to gather extra information from the user, which lets your bot respond more intelligently or possibly skip certain questions where it asks the user for that information. 除了“预订航班”、“取消”和“None”这三个 LUIS 意向的定义,FlightBooking.json 文件还包含一组实体,例如“From.Airport”和“To.Airport”。Along with definitions for the three LUIS intents 'Book Flight', 'Cancel', and 'None' the FlightBooking.json file also contains a set of entities such as 'From.Airport' and 'To.Airport'. LUIS 可以通过这些实体检测用户在发出新的旅行预订请求时其原始输入中包含的其他信息并将其返回。These entities allow LUIS to detect and return additional information contained within the user's original input when they request a new travel booking.

若要了解实体信息如何在 LUIS 结果中显示,请参阅从包含意图和实体的话语文本中提取数据For information on how entity information appears in a LUIS result, see Extract data from utterance text with intents and entities.

获取用于连接 LUIS 应用的值Obtain values to connect to your LUIS app

发布 LUIS 应用后,可以在机器人中访问它。Once your LUIS app is published, you can access it from your bot. 需要记录多个值才能在机器人中访问该 LUIS 应用。You will need to record several values to access your LUIS app from within your bot. 可以使用 LUIS 门户检索该信息。You can retrieve that information using the LUIS portal.

从 LUIS.ai 门户检索应用程序信息Retrieve application information from the LUIS.ai portal

设置文件(appsettings.json.env)将所有服务引用合并到一个位置。The settings file (appsettings.json or .env) acts as the place to bring all service references together in one place. 检索的信息将添加到下一部分的该文件。The information you retrieve will be added to this file in the next section.

  1. luis.ai 中选择已发布的 LUIS 应用。Select your published LUIS app from luis.ai.
  2. 打开已发布的 LUIS 应用后,选择“管理”选项卡。 管理 LUIS 应用With your published LUIS app open, select the MANAGE tab. Manage LUIS app
  3. 在左侧选择“应用程序信息”选项卡,记录“应用程序 ID”(<YOUR_APP_ID>) 的显示值。 Select the Application Information tab on the left side, record the value shown for Application ID as <YOUR_APP_ID>.
  4. 在左侧选择“密钥和终结点”选项卡,记录“创作密钥”(<YOUR_AUTHORING_KEY>) 的显示值。 Select the Keys and Endpoints tab on the left side, record the value shown for Authoring Key as <YOUR_AUTHORING_KEY>.
  5. 向下滚动到页尾,记录“区域”(<YOUR_REGION>) 的显示值。 Scroll down to the end of the page, record the value shown for Region as <YOUR_REGION>.

更新设置文件Update the settings file

appsettings.json 文件中添加访问 LUIS 应用所需的信息,包括应用程序 ID、创作密钥和区域。Add the information required to access your LUIS app including application id, authoring key, and region into the appsettings.json file. 前面已在发布的 LUIS 应用中保存了这些值。These are the values you saved previously from your published LUIS app. 请注意,API 主机名称应采用 <your region>.api.cognitive.microsoft.com 格式。Note that the API host name should be in the format <your region>.api.cognitive.microsoft.com.

appsetting.jsonappsetting.json

{
  "MicrosoftAppId": "",
  "MicrosoftAppPassword": "",
  "LuisAppId": "",
  "LuisAPIKey": "",
  "LuisAPIHostName": ""
}

将机器人配置为使用你的 LUIS 应用Configure your bot to use your LUIS app

请确保为项目安装 Microsoft.Bot.Builder.AI.Luis NuGet 包。Be sure that the Microsoft.Bot.Builder.AI.Luis NuGet package is installed for your project.

为了连接到 LUIS 服务,机器人会从 appsetting.json 文件拉取你此前添加的信息。To connect to the LUIS service, the bot pulls the information you added above from the appsetting.json file. FlightBookingRecognizer 类包含的代码有 appsetting.json 文件中的设置,它调用 RecognizeAsync 方法来查询 LUIS 服务。The FlightBookingRecognizer class contains code with your settings from the appsetting.json file and queries the LUIS service by calling RecognizeAsync method.

FlightBookingRecognizer.csFlightBookingRecognizer.cs

public class FlightBookingRecognizer : IRecognizer
{
    private readonly LuisRecognizer _recognizer;

    public FlightBookingRecognizer(IConfiguration configuration)
    {
        var luisIsConfigured = !string.IsNullOrEmpty(configuration["LuisAppId"]) && !string.IsNullOrEmpty(configuration["LuisAPIKey"]) && !string.IsNullOrEmpty(configuration["LuisAPIHostName"]);
        if (luisIsConfigured)
        {
            var luisApplication = new LuisApplication(
                configuration["LuisAppId"],
                configuration["LuisAPIKey"],
                "https://" + configuration["LuisAPIHostName"]);

            _recognizer = new LuisRecognizer(luisApplication);
        }
    }

    // Returns true if luis is configured in the appsettings.json and initialized.
    public virtual bool IsConfigured => _recognizer != null;

    public virtual async Task<RecognizerResult> RecognizeAsync(ITurnContext turnContext, CancellationToken cancellationToken)
        => await _recognizer.RecognizeAsync(turnContext, cancellationToken);

    public virtual async Task<T> RecognizeAsync<T>(ITurnContext turnContext, CancellationToken cancellationToken)
        where T : IRecognizerConvert, new()
        => await _recognizer.RecognizeAsync<T>(turnContext, cancellationToken);
}

FlightBookingEx.cs 包含的逻辑可以使用 FromToTravelDate 来提取内容;它扩展的分部类 FlightBooking.cs 在从 MainDialog.cs 调用 FlightBookingRecognizer.RecognizeAsync<FlightBooking> 时可以用来存储 LUIS 结果。The FlightBookingEx.cs contains the logic to extract From, To and TravelDate; it extends the partial class FlightBooking.cs used to store LUIS results when calling FlightBookingRecognizer.RecognizeAsync<FlightBooking> from the MainDialog.cs.

CognitiveModels\FlightBookingEx.csCognitiveModels\FlightBookingEx.cs

// Extends the partial FlightBooking class with methods and properties that simplify accessing entities in the luis results
public partial class FlightBooking
{
    public (string From, string Airport) FromEntities
    {
        get
        {
            var fromValue = Entities?._instance?.From?.FirstOrDefault()?.Text;
            var fromAirportValue = Entities?.From?.FirstOrDefault()?.Airport?.FirstOrDefault()?.FirstOrDefault();
            return (fromValue, fromAirportValue);
        }
    }

    public (string To, string Airport) ToEntities
    {
        get
        {
            var toValue = Entities?._instance?.To?.FirstOrDefault()?.Text;
            var toAirportValue = Entities?.To?.FirstOrDefault()?.Airport?.FirstOrDefault()?.FirstOrDefault();
            return (toValue, toAirportValue);
        }
    }

    // This value will be a TIMEX. And we are only interested in a Date so grab the first result and drop the Time part.
    // TIMEX is a format that represents DateTime expressions that include some ambiguity. e.g. missing a Year.
    public string TravelDate
        => Entities.datetime?.FirstOrDefault()?.Expressions.FirstOrDefault()?.Split('T')[0];
}

现在,你已为机器人配置并连接了 LUIS。LUIS is now configured and connected for your bot.

测试机器人Test the bot

下载并安装最新的 Bot Framework EmulatorDownload and install the latest Bot Framework Emulator

  1. 在计算机本地运行示例。Run the sample locally on your machine. 如需说明,请参阅 C# 示例JS 示例的自述文件。If you need instructions, refer to the readme file for either the C# Sample or JS Sample.

  2. 在模拟器中键入一条消息,例如“旅行到巴黎”或“从巴黎到柏林”。In the emulator, type a message such as "travel to paris" or "going from paris to berlin". 使用在 FlightBooking.json 文件中发现的任何话语训练“预订航班”意向。Use any utterance found in the file FlightBooking.json for training the intent "Book flight".

LUIS 预订输入

如果从 LUIS 返回的排名靠前的意向解析为“预订航班”,则机器人会询问其他问题,直至存储了进行旅行预订所需的足够信息。If the top intent returned from LUIS resolves to "Book flight" your bot will ask additional questions until it has enough information stored to create a travel booking. 此时机器人会将下述预订信息返回给用户。At that point it will return this booking information back to your user.

LUIS 预订结果

此时代码机器人逻辑会重置,你可以继续进行其他的预订。At this point the code bot logic will reset and you can continue to create additional bookings.

后续步骤Next steps