适用于:SDK v4
如何处理中断是判断机器人是否可靠的一个重要因素。 用户不总是按照定义的对话流逐步操作。 他们可能会在流程的中途提出问题,或者只是想要取消流程,而不要完成流程。 本文介绍一些在机器人中处理用户中断的常用方法。
先决条件
核心机器人示例使用语言理解 (LUIS) 来辨识用户意图;但是,辨识用户意图不是本文的重点。
有关辨识用户意图的信息,请参阅自然语言理解和向机器人添加自然语言理解。
注意
语言理解 (LUIS) 将于 2025 年 10 月 1 日停用。
从 2023 年 4 月 1 日开始,将无法创建新的 LUIS 资源。
语言理解的较新版本现已作为 Azure AI 语言的一部分提供。
对话语言理解(CLU)是 Azure AI 语言的一项功能,是 LUIS 的更新版本。
有关 Bot Framework SDK 中的语言理解支持的详细信息,请参阅自然语言理解。
关于此示例
本文中使用的示例为某个航班预订机器人建模,该机器人使用对话从用户获取航班信息。 在与机器人聊天过程中的任何时候,用户都可以发出 help 或 cancel 命令来造成中断。 处理的中断有两种类型:
-
轮次级别:绕过轮次级别的处理,但在堆栈中保留包含所提供信息的对话。 下一轮聊天从上次中断聊天的地方继续。
-
对话级别:完全取消处理,使机器人能够从头开始。
定义和实现中断逻辑
首先,定义并实现 help 和 cancel 中断。
若要使用对话,请安装 Microsoft.Bot.Builder.Dialogs NuGet 包。
Dialogs\CancelAndHelpDialog.cs
实现 CancelAndHelpDialog
类来处理用户中断。 可取消的对话 BookingDialog
和 DateResolverDialog
派生自此类。
警告
您正在寻找的示例似乎已经被移动了! 放心,我们正在努力解决此问题。
在 CancelAndHelpDialog
类中,OnContinueDialogAsync
方法调用 InterruptAsync
方法来检查用户是否中断了正常的流。 如果该流已中断,则调用基类方法;否则返回 InterruptAsync
中的返回值。
警告
您正在寻找的示例似乎已经被移动了! 放心,我们正在努力解决此问题。
如果用户键入“help”,InterruptAsync
方法将发送一条消息,然后调用 DialogTurnResult (DialogTurnStatus.Waiting)
来指示最前面的对话正在等待用户的响应。 这样只会中断某个轮次的聊天流,下一轮聊天会从上次中断聊天的地方继续。
如果用户键入“cancel”,该方法将对其内部对话上下文调用 CancelAllDialogsAsync
,这会清除其对话堆栈,导致堆栈退出并返回 cancelled(已取消)状态,但不返回结果值。
MainDialog
(稍后会介绍)将显示预订对话已结束并返回了 null,就如同用户选择不确认其预订一样。
警告
您正在寻找的示例似乎已经被移动了! 放心,我们正在努力解决此问题。
若要使用对话,请安装 botbuilder-dialogs npm 包。
dialogs/cancelAndHelpDialog.js
实现 CancelAndHelpDialog
类来处理用户中断。 可取消的对话 BookingDialog
和 DateResolverDialog
扩展了此类。
警告
您正在寻找的示例似乎已经被移动了! 放心,我们正在努力解决此问题。
在 CancelAndHelpDialog
类中,onContinueDialog
方法调用 interrupt
方法来检查用户是否中断了正常的流。 如果该流已中断,则调用基类方法;否则返回 interrupt
中的返回值。
警告
您正在寻找的示例似乎已经被移动了! 放心,我们正在努力解决此问题。
如果用户键入“help”,interrupt
方法将发送一条消息,然后返回一个 { status: DialogTurnStatus.waiting }
对象来指示最前面的对话正在等待用户的响应。 这样只会中断某个轮次的聊天流,下一轮聊天会从上次中断聊天的地方继续。
如果用户键入“cancel”,该方法将对其内部对话上下文调用 cancelAllDialogs
,这会清除其对话堆栈,导致堆栈退出并返回 cancelled(已取消)状态,但不返回结果值。
MainDialog
(稍后会介绍)将显示预订对话已结束并返回了 null,就如同用户选择不确认其预订一样。
警告
您正在寻找的示例似乎已经被移动了! 放心,我们正在努力解决此问题。
CancelAndHelpDialog.java
实现 CancelAndHelpDialog
类来处理用户中断。 可取消的对话 BookingDialog
和 DateResolverDialog
派生自此类。
警告
您正在寻找的示例似乎已经被移动了! 放心,我们正在努力解决此问题。
在 CancelAndHelpDialog
类中,onContinueDialog
方法调用 interrupt
方法来检查用户是否中断了正常的流。 如果该流已中断,则调用基类方法;否则返回 interrupt
中的返回值。
警告
您正在寻找的示例似乎已经被移动了! 放心,我们正在努力解决此问题。
如果用户键入“help”,interrupt
方法将发送一条消息,然后调用 DialogTurnResult(DialogTurnStatus.WAITING)
来指示最前面的对话正在等待用户的响应。 这样只会中断某个轮次的聊天流,下一轮聊天会从上次中断聊天的地方继续。
如果用户键入“cancel”,该方法将对其内部对话上下文调用 cancelAllDialogs
,这会清除其对话堆栈,导致堆栈退出并返回 cancelled(已取消)状态,但不返回结果值。
MainDialog
(稍后会介绍)将显示预订对话已结束并返回了 null,就如同用户选择不确认其预订一样。
警告
您正在寻找的示例似乎已经被移动了! 放心,我们正在努力解决此问题。
若要使用对话框,请安装 botbuilder-dialogs
包并确保示例 requirements.txt
文件包含正确的引用,如 botbuilder-dialogs>=4.5.0
。
有关安装包的详细信息,请参阅示例存储库 README 文件。
注意
运行 pip install botbuilder-dialogs
也将安装 botbuilder-core
、botbuilder-connector
和 botbuilder-schema
。
dialogs/cancel-and-help-dialog.py
实现 CancelAndHelpDialog
类来处理用户中断。 可取消的对话 BookingDialog
和 DateResolverDialog
派生自此类。
警告
您正在寻找的示例似乎已经被移动了! 放心,我们正在努力解决此问题。
在 CancelAndHelpDialog
类中,on_continue_dialog
方法调用 interrupt
方法来检查用户是否中断了正常的流。 如果该流已中断,则调用基类方法;否则返回 interrupt
中的返回值。
警告
您正在寻找的示例似乎已经被移动了! 放心,我们正在努力解决此问题。
如果用户键入“help”或“?”,interrupt
方法将发送一条消息,然后调用 DialogTurnResult(DialogTurnStatus.Waiting)
来指示堆栈顶部的对话正在等待用户的响应。 这样只会中断某个轮次的聊天流,下一轮聊天会从上次中断聊天的地方继续。
如果用户键入“cancel”或“quit”,该方法将对其内部对话上下文调用 cancel_all_dialogs()
,这会清除其对话堆栈,导致堆栈退出并返回“已取消”状态,但不返回结果值。 稍后会介绍的 MainDialog
将显示预订对话已结束并返回了 null,就如同用户选择不确认其预订一样。
警告
您正在寻找的示例似乎已经被移动了! 放心,我们正在努力解决此问题。
检查每个轮次的中断
实现中断处理类以后,请查看当此机器人收到来自用户的新消息时会发生什么情况。
Dialogs\MainDialog.cs
当新的消息活动抵达时,机器人将运行 MainDialog
。
MainDialog
提示用户需要哪种帮助。 然后,机器人将通过调用 BookingDialog
来启动 MainDialog.ActStepAsync
方法中的 BeginDialogAsync
,如下所示。
警告
您正在寻找的示例似乎已经被移动了! 放心,我们正在努力解决此问题。
接下来,在 FinalStepAsync
类的 MainDialog
方法中,预订对话将会结束,而预订被视为已完成或已取消。
警告
您正在寻找的示例似乎已经被移动了! 放心,我们正在努力解决此问题。
此处不显示 BookingDialog
中的代码,因为其不直接与中断处理相关。 其用于提示用户预订详细信息。 可以在 Dialogs\BookingDialogs.cs 中找到这些代码。
dialogs/mainDialog.js
当新的消息活动抵达时,机器人将运行 MainDialog
。
MainDialog
提示用户需要哪种帮助。 然后,机器人将通过调用 bookingDialog
来启动 MainDialog.actStep
方法中的 beginDialog
,如下所示。
警告
您正在寻找的示例似乎已经被移动了! 放心,我们正在努力解决此问题。
接下来,在 finalStep
类的 MainDialog
方法中,预订对话将会结束,而预订被视为已完成或已取消。
警告
您正在寻找的示例似乎已经被移动了! 放心,我们正在努力解决此问题。
此处不显示 BookingDialog
中的代码,因为其不直接与中断处理相关。 其用于提示用户预订详细信息。 可以在 dialogs/bookingDialogs.js 中找到这些代码。
MainDialog.java
当新的消息活动抵达时,机器人将运行 MainDialog
。
MainDialog
提示用户需要哪种帮助。 然后,机器人将通过调用 BookingDialog
来启动 MainDialog.actStep
方法中的 beginDialog
,如下所示。
警告
您正在寻找的示例似乎已经被移动了! 放心,我们正在努力解决此问题。
接下来,在 finalStep
类的 MainDialog
方法中,预订对话将会结束,而预订被视为已完成或已取消。
警告
您正在寻找的示例似乎已经被移动了! 放心,我们正在努力解决此问题。
此处不显示 BookingDialog
中的代码,因为其不直接与中断处理相关。 其用于提示用户预订详细信息。 可以在“BookingDialogs.java”中找到这些代码。
dialogs/main_dialog.py
当新的消息活动抵达时,机器人将运行 MainDialog
。
MainDialog
提示用户需要哪种帮助。 然后,机器人将通过调用 bookingDialog
来启动 act_step
方法中的 begin_dialog
,如下所示。
警告
您正在寻找的示例似乎已经被移动了! 放心,我们正在努力解决此问题。
接下来,在 final_step
类的 MainDialog
方法中,预订对话将会结束,而预订被视为已完成或已取消。
警告
您正在寻找的示例似乎已经被移动了! 放心,我们正在努力解决此问题。
处理意外错误
适配器的错误处理程序处理机器人中未捕获到的任何异常。
AdapterWithErrorHandler.cs
在本示例中,适配器的 OnTurnError
处理程序接收机器人的轮次逻辑引发的任何异常。 如果引发了异常,该处理程序将删除当前聊天的聊天状态,以防止错误状态导致机器人陷入错误循环。
警告
您正在寻找的示例似乎已经被移动了! 放心,我们正在努力解决此问题。
index.js
在本示例中,适配器的 onTurnError
处理程序接收机器人的轮次逻辑引发的任何异常。 如果引发了异常,该处理程序将删除当前聊天的聊天状态,以防止错误状态导致机器人陷入错误循环。
警告
您正在寻找的示例似乎已经被移动了! 放心,我们正在努力解决此问题。
在此示例中,通过在 AdapterWithErrorHandler
中针对 将 BotFrameworkHttpAdapter
注册到 Spring Framework,适配器的 onTurnError
处理程序接收机器人的轮次逻辑引发的任何异常。 如果引发了异常,该处理程序将删除当前聊天的聊天状态,以防止错误状态导致机器人陷入错误循环。 在 Java SDK 中,AdapterWithErrorHandler
以 SDK 的一部分的形式实现,并包含在 com.microsoft.bot.integration 包中。 有关此适配器的实现的详细信息,请参阅 Java SDK 源代码。
adapter_with_error_handler.py
在本示例中,适配器的 on_error
处理程序接收机器人的轮次逻辑引发的任何异常。 如果引发了异常,该处理程序将删除当前聊天的聊天状态,以防止错误状态导致机器人陷入错误循环。
警告
您正在寻找的示例似乎已经被移动了! 放心,我们正在努力解决此问题。
注册服务
Startup.cs
最后,在 Startup.cs
中创建一个暂时性的机器人,并在每个轮次创建该机器人的新实例。
警告
您正在寻找的示例似乎已经被移动了! 放心,我们正在努力解决此问题。
下面提供了在用于创建上述机器人的调用中使用的类定义供参考。
警告
您正在寻找的示例似乎已经被移动了! 放心,我们正在努力解决此问题。
警告
您正在寻找的示例似乎已经被移动了! 放心,我们正在努力解决此问题。
警告
您正在寻找的示例似乎已经被移动了! 放心,我们正在努力解决此问题。
index.js
最后,在 index.js
中创建机器人。
警告
您正在寻找的示例似乎已经被移动了! 放心,我们正在努力解决此问题。
下面提供了在用于创建上述机器人的调用中使用的类定义供参考。
警告
您正在寻找的示例似乎已经被移动了! 放心,我们正在努力解决此问题。
警告
您正在寻找的示例似乎已经被移动了! 放心,我们正在努力解决此问题。
警告
您正在寻找的示例似乎已经被移动了! 放心,我们正在努力解决此问题。
Application.java
最后,在 Application.java
中创建机器人。
警告
您正在寻找的示例似乎已经被移动了! 放心,我们正在努力解决此问题。
下面提供了在用于创建上述机器人的调用中使用的类定义供参考。
警告
您正在寻找的示例似乎已经被移动了! 放心,我们正在努力解决此问题。
警告
您正在寻找的示例似乎已经被移动了! 放心,我们正在努力解决此问题。
警告
您正在寻找的示例似乎已经被移动了! 放心,我们正在努力解决此问题。
app.py 最后,在 app.py
中创建机器人。
警告
您正在寻找的示例似乎已经被移动了! 放心,我们正在努力解决此问题。
为方便参考,下面提供了在用于创建机器人的调用中使用的类定义。
警告
您正在寻找的示例似乎已经被移动了! 放心,我们正在努力解决此问题。
警告
您正在寻找的示例似乎已经被移动了! 放心,我们正在努力解决此问题。
警告
您正在寻找的示例似乎已经被移动了! 放心,我们正在努力解决此问题。
测试机器人
- 安装 Bot Framework Emulator(如果尚未安装)。
- 在计算机本地运行示例。
- 按如下所示启动模拟器,连接到机器人,然后发送消息。
24.bot-authentication-msgraph 示例(用 C#、JavaScript、Python 或 Java 编写)演示如何处理注销请求。 它使用类似于此处所示的模式来处理中断。
应该发送默认响应,而非不采取任何措施,导致用户对当前情况感到困惑。 默认响应告诉用户机器人理解哪些命令,以便用户可以重新进行对话。
在轮次中的任意时间点,轮次上下文的 responded 属性都会指示机器人在此轮次中是否向用户发送了消息。 在轮次结束之前,机器人应会向用户发送某条消息,即使该消息只是确认收到了用户的输入。