你当前正在访问 Microsoft Azure Global Edition 技术文档网站。 如果需要访问由世纪互联运营的 Microsoft Azure 中国技术文档网站,请访问 https://docs.azure.cn

向机器人添加自然语言理解

适用于:SDK v4

注意

语言理解 (LUIS) 将于 2025 年 10 月 1 日停用。 从 2023 年 4 月 1 日开始,将无法创建新的 LUIS 资源。 语言理解的较新版本现已作为 Azure AI 语言的一部分提供。

对话语言理解 (CLU) 是 Azure AI 语言的一项功能,是 LUIS 的更新版本。 有关 Bot Framework SDK 中的语言理解支持的详细信息,请参阅自然语言理解

理解用户在会话和上下文中表达的含义是一项艰巨的任务,但可以让机器人更自然地进行聊天。 语言理解 (LUIS) 是一种基于云的 API 服务,能够实现此目标,使机器人能够识别用户消息的意向,接收用户更自然的语言,并更好地指导会话流程。

本主题详细介绍如何将 LUIS 添加到航班预订应用程序,以便识别用户输入中包含的不同意向和实体。

注意

Bot Framework JavaScript、C# 和 Python SDK 将继续受支持,但 Java SDK 即将停用,长期支持最终将结束于 2023 年 11 月。 仅执行此存储库中的关键安全性和缺陷修复。

使用 Java SDK 构建的现有机器人将继续正常运行。

对于新的机器人生成,请考虑使用 Power Virtual Agents 并参阅选择合适的聊天机器人解决方案

有关详细信息,请参阅机器人构建的未来

先决条件

关于此示例

此核心机器人示例演示了飞机航班预订应用程序的示例。 它使用 LUIS 服务来识别用户输入,并返回排名靠前的已识别 LUIS 意向。

语言模型包含三个意向:Book FlightCancelNone。 当用户向机器人发送消息时,LUIS 将使用这些意向来了解其意图。 语言模型还定义 LUIS 可以从用户输入(例如始发或目标机场)中提取的实体。

每次处理用户输入以后,DialogBot 都会保存 UserStateConversationState 的当前状态。 收集所有必需的信息以后,编码示例会创建一个演示版的航班预订。 在本文中,我们将介绍此示例 LUIS 方面的内容。 但是,示例的常规流程为:

  • 连接新用户时,会调用 OnMembersAddedAsync 并显示欢迎卡片。
  • 每次收到用户输入都会调用 OnMessageActivityAsync

Class diagram outlining the structure of the C# sample.

OnMessageActivityAsync 模块通过 Run 对话扩展方法运行相应的对话。 然后,主对话会调用 LUIS 帮助程序 来查找排名靠前的评分用户意向。 如果用户输入的排名靠前的意向返回“BookFlight”,则帮助程序会填充 LUIS 返回的用户的信息。 然后,主对话启动 BookingDialog,后者会根据需要从用户获取其他信息,例如:

  • Origin 始发城市
  • TravelDate 预订航班的日期
  • Destination 目标城市

本文介绍了如何将 LUIS 添加到机器人。 有关使用对话或状态的信息,请分别参阅使用对话提示收集用户输入保存用户和聊天数据

在 LUIS 门户中创建 LUIS 应用

  1. 登录到 LUIS 门户,如果需要,则创建帐户创作资源
  2. LUIS 中的“对话应用”页上,选择“导入”,然后选择“导入为 JSON”
  3. 在“导入新应用”对话框中:
    1. 在示例的“CognitiveModels”文件夹中选择“FlightBooking”文件。
    2. 输入 FlightBooking 作为应用的可选名称,然后选择“完成”。
  4. 该网站可能会显示“如何创建有效的 LUIS 应用”“升级复合实体”对话。 可以关闭这些对话并继续。
  5. 训练应用,然后将其发布到“生产”环境。 若要了解详细信息,请参阅有关如何培训发布应用的 LUIS 文档。

为何使用实体

LUIS 实体使机器人能够了解超出标准意图的事件。 这样,便可以从用户收集其他信息,使机器人可以提出问题并更智能地做出回答。 除了“预订航班”、“取消”和“None”这三个 LUIS 意向的定义,FlightBooking.json 文件还包含一组实体,例如“From.Airport”和“To.Airport”。 LUIS 可以通过这些实体检测用户在发出新的旅行预订请求时其原始输入中包含的其他信息并将其返回。

获取用于连接 LUIS 应用的值

发布 LUIS 应用后,可以在机器人中访问它。 需要记录多个值才能在机器人中访问该 LUIS 应用。 可以使用 LUIS 门户检索该信息。

从 LUIS.ai 门户检索应用程序信息

设置文件(appsettings.json.envconfig.py)充当了位置,用于将所有服务引用一起合并到一个位置。 检索的信息将添加到下一部分的该文件。

  1. luis.ai 中选择已发布的 LUIS 应用。

  2. 打开已发布的 LUIS 应用后,选择“管理”选项卡。

  3. 在左侧选择“设置”选项卡,记录“应用程序 ID”() 的显示值。<>

    Screenshot of the Manage page displaying your application ID.

  4. 选择“Azure 资源”,然后选择“预测资源”。 将“位置”的显示值记录为 <YOUR_REGION>,将“主密钥”的显示值记录为 <YOUR_AUTHORING_KEY>。

    Screenshot of the Manage page displaying your location and primary key.

    或者,可以将区域和主键用于创作资源。

更新设置文件

appsettings.json 文件中添加访问 LUIS 应用所需的信息,包括应用程序 ID、创作密钥和区域。 在上一步中,你已从已发布的 LUIS 应用中检索了这些值。 API 主机名称应采用 <your region>.api.cognitive.microsoft.com 格式。

appsetting.json

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

将机器人配置为使用你的 LUIS 应用

请确保为项目安装 Microsoft.Bot.Builder.AI.Luis NuGet 包。

为了连接到 LUIS 服务,机器人会拉取你添加到 appsetting.json 文件的信息。 FlightBookingRecognizer 类包含的代码有 appsetting.json 文件中的设置,它调用 RecognizeAsync 方法来查询 LUIS 服务。

FlightBookingRecognizer.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"]);
            // Set the recognizer options depending on which endpoint version you want to use.
            // More details can be found in https://docs.microsoft.com/en-gb/azure/cognitive-services/luis/luis-migration-api-v3
            var recognizerOptions = new LuisRecognizerOptionsV3(luisApplication)
            {
                PredictionOptions = new Bot.Builder.AI.LuisV3.LuisPredictionOptions
                {
                    IncludeInstanceData = true,
                }
            };

            _recognizer = new LuisRecognizer(recognizerOptions);
        }
    }

    // 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 结果。

CognitiveModels\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。

测试机器人

下载并安装最新的 Bot Framework Emulator

  1. 在计算机本地运行示例。 如需说明,请参阅 C# 示例JS 示例Python 示例README 文件。

  2. 在模拟器中键入一条消息,例如“前往巴黎”或“从巴黎到柏林”。 使用在 FlightBooking.json 文件中发现的任何话语训练“预订航班”意向。

如果从 LUIS 返回的排名靠前的意向解析为“预订航班”,则机器人会询问更多问题,直至存储了进行旅行预订所需的足够信息。 此时机器人会将下述预订信息返回给用户。

此时代码机器人逻辑会重置,你可以继续进行其他的预订。

其他信息

有关 LUIS 的详细信息,请参阅 LUIS 文档:

提示

SDK 的不同部分定义单独的“实体”类或元素。 有关消息实体,请参阅实体和活动类型