调试准则

适用于: SDK v4

机器人是复杂的应用,有大量协同工作的部件。 就像其他复杂应用一样,这可能会导致出现一些需要关注的 Bug,或者会导致机器人的行为异常。

有时候,机器人的调试是一项困难的任务。 每个开发人员都有自己喜欢的方式来完成这项任务。 以下指南是适用于大多数机器人的建议。

在确认机器人能正常工作后,下一步是将其连接到通道。 为此,可以将机器人部署到暂存服务器,并为机器人创建自己的 Direct Line 客户端进行连接。 有关详细信息,请参阅将机器人连接到 Direct Line

通过创建自己的客户端,你可以定义通道的内部工作原理,并测试机器人如何响应某些活动交换。 连接到客户端以后,请运行测试,以便设置机器人状态并验证功能。 如果机器人使用语音之类的功能,则可通过这些通道来验证该功能。

注意

将机器人部署到 Azure 时,默认情况下会预配 Web 聊天通道。

通过 Azure 门户使用 Bot Framework EmulatorWeb 聊天可以进一步了解机器人在与不同通道交互时的性能。

调试机器人与调试其他多线程应用类似,可以设置断点,也可以使用即时窗口之类的功能。

机器人遵循事件驱动型编程范例。如果不熟悉这方面的内容,可能难以理解。 如果想要让机器人在无状态且使用多个线程的情况下处理异步/等待调用,则可能导致意外 Bug。 虽然调试机器人的方式与调试其他多线程应用类似,但我们还是会介绍一些有用的建议、工具和资源。

使用 Emulator 了解机器人活动

除了正常的消息活动以外,机器人还处理不同类型的活动 了解这些活动有助于你提高机器人代码编写效率,并可验证机器人发送和接收的活动是否符合预期。 使用 Emulator 将显示这些活动是什么,何时发生,以及它们包含什么信息。 有关详细信息,请参阅使用模拟器调试

使用脚本保存和检索用户交互

Azure blob 脚本存储提供了一个专门的资源,可以在其中存储和检索脚本(包含用户与机器人之间的交互)。

此外,存储了用户输入交互后,你便可以使用 Azure 的“存储资源管理器”手动查看存储在 Blob 脚本存储中的脚本中包含的数据。 以下示例从"mynewtestblobstorage"的设置中打开“存储资源管理器”。若要打开已保存的用户输入,请选择:Blob 容器 > ChannelId > TranscriptId > ConversationId

存储在 Blob 脚本存储中的脚本条目示例。

这将以 JSON 格式打开存储的用户聊天输入。 用户输入与键"text:"一起保留。有关创建和使用机器人脚本文件的详细信息,请参阅使用脚本文件调试机器人

中间件工作原理

在首次尝试使用中间件时,可能会觉得它不直观,尤其是在涉及到持续执行或短路执行的情况下。 中间件可以在某个轮次的前缘或后缘执行,可以调用 next() 委托来指示何时将执行传递给机器人逻辑。

如果使用多个中间件,并且这是管道的方向,则委托可能会将执行传递给不同的中间件。 若要更清楚地了解该理念,可查看机器人中间件管道的详细信息。

如果未调用 next() 委托,则称为短路路由。 当中间件符合当前活动情况且确定不需传递执行时,则会发生这种情况。

了解中间件短路的时间和原因有助于指示哪个中间件应该首先出现在管道中。 此外,对于 SDK 或其他开发人员提供的内置中间件来说,了解预期内容非常重要。 可以试着先创建你自己的中间件试验一下,然后再使用内置的中间件,这样也许会有用。

有关如何使用检查中间件调试机器人的详细信息,请参阅 使用检查中间件调试机器人。

了解状态

记录状态是机器人必须做的,尤其对于复杂任务来说。 通常情况下,最佳做法是尽快处理活动并让处理操作完成,这样状态就能持久保存。 活动几乎可以同时发送到机器人,由于异步架构,这可能会引入令人困惑的错误。

最重要的,请确保在持久保存状态时,所用方式与预期一致。 可以根据持久保存的状态的存储位置,使用 Cosmos DBAzure 表存储的存储模拟器来验证该状态,然后再使用生产性存储。

重要

Cosmos DB 存储类已弃用。 最初使用 CosmosDbStorage 创建的容器存储没有分区键集,并且被授予默认分区键 _/partitionKey

通过“Cosmos DB 存储”创建的容器可以与“Cosmos DB 分区存储”一起使用。 有关详细信息,请阅读 Azure Cosmos DB 中的分区

另请注意,与旧版 Cosmos DB 存储不同,Cosmos DB 分区存储不会自动在 Cosmos DB 帐户中创建数据库。 你需要手动创建新数据库,但需要跳过手动创建容器步骤,因为 CosmosDbPartitionedStorage 存储会为你创建容器。

如何使用活动处理程序

活动处理程序可能会引入另一层复杂性,尤其是每个活动都在独立线程(或 Web 辅助角色,具体取决于语言)上运行。 根据你的处理程序正在执行的操作,这可能会导致当前状态与你的预期不符的问题。

内置状态在一个轮次结束时写入,但是,由该轮次生成的任何活动在执行时均独立于轮次管道。 通常这不会影响我们,但如果活动处理程序更改状态,则写入的状态必须包含所做的更改。 在这种情况下,轮次管道在完成操作之前,会先等待活动处理完毕,目的是确保记录该轮次的正确状态。

“发送活动”方法及其处理程序带来了一个独特的问题。 单纯地从“在发送活动时”处理程序内调用“发送活动”会导致线程无限地创建分支。 可以通过多种方式解决该问题,例如,可以在传出信息中追加更多消息,或者将内容写出到另一位置(例如控制台或文件),以免机器人崩溃。

调试生产机器人

如果你的机器人在生产环境中,则可以使用开发隧道从任何通道调试机器人。 机器人与多个通道的无缝连接是 Bot Framework 中提供的一项关键功能。 有关详细信息,请参阅使用 devtunnel 从任何通道调试机器人以及调试技能或技能使用者

后续步骤

其他资源