调试准则

适用于: SDK v4

机器人是复杂的应用,有大量协同工作的部件。 就像其他复杂应用一样,这种情况可能会引发一些奇怪的 Bug,或者导致你的机器人表现得与预期不符。

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

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

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

注意

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

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

调试机器人的方式与调试其他多线程应用类似,可以设置断点,也可以使用“立即”窗口等功能。

机器人遵循事件驱动型编程范例。如果不熟悉这方面的内容,可能难以理解。 将你的机器人设计为无状态、支持多线程并处理 async/await 调用,这种思路可能会导致意想不到的 bug。 虽然调试机器人的方式与调试其他多线程应用类似,但我们还是会介绍一些有用的建议、工具和资源。

使用 Emulator 了解机器人活动

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

保存和检索用户与转录文本的交互

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

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

存储在 Blob 转录存储中的转录条目示例。

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

中间件工作原理

在首次尝试使用中间件时,可能会觉得它不直观,尤其是在涉及到持续执行或短路执行的情况下。 中间件可以在轮次开始时或结束时执行,而对 next() 委托的调用则决定何时将执行流程交给机器人逻辑。

如果你使用了多个中间件,并且你的管道就是这样组织的,那么该委托可能会将执行传递给另一个中间件。 若要更清楚地了解该理念,可查看机器人中间件管道的详细信息。

如果未调用 next() 委托,这称为短路路由。 当中间件满足当前活动的要求,并确定没有必要将执行传递下去时,就会发生这种情况。

了解中间件短路的时间和原因有助于指示哪个中间件应该首先出现在管道中。 此外,对于 SDK 或其他开发人员提供的内置中间件来说,了解预期内容非常重要。 有些人觉得,先尝试自己创建中间件做一些实验,再深入了解内置中间件,会更有帮助。

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

了解状态

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

最重要的是,请确保状态的持久化方式符合你的预期。 取决于持久化状态存储在何处,Cosmos DB 和 Azure 表存储的存储模拟器可以帮助你在使用生产存储之前先验证该状态。

重要

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

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

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

如何使用活动处理程序

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

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

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

调试生产机器人

当你的机器人处于生产环境时,你可以通过任何通道使用 Dev Tunnels 调试你的机器人。 机器人与多个通道的无缝连接是 Bot Framework 中提供的一项关键功能。 有关详细信息,请参阅使用 devtunnel 从任何通道调试机器人以及调试技能或技能使用者。

后续步骤

其他资源