gpt4 book ai didi

c# - Bot Framework v4.2 - 优雅地从 OnTurnError 异常中恢复

转载 作者:行者123 更新时间:2023-11-30 16:38:41 25 4
gpt4 key购买 nike

我一直在阅读文档并查看代码示例以获取提示和灵感,但到目前为止我什么也没找到。

如果我们捕获到我们的机器人中发生的全局异常,我们将进入 OnTurnError 处理程序:

// Catches any errors that occur during a conversation turn and logs them.
options.OnTurnError = async (context, exception) =>
{
logger.LogError($"Exception caught : {exception}");
await context.SendActivityAsync("Sorry, it looks like something went wrong.");
};

我没有在文档或任何讨论中发现任何人随后从错误中恢复并重新开始对话的内容。我有一个有效的解决方案,但我想知道我是否缺少更“最佳实践”的方法。我现在正在这样做:

options.OnTurnError = async (context, exception) =>
{
logger.LogError($"Exception caught : {exception}");
await context.SendActivityAsync("Sorry, it looks like something went wrong.");

await _conversationState.DeleteAsync(context);

await MyBot.SendIntroCardAsync(context, CancellationToken.None);
};

如果没有像这样的某种恢复,我们就会让用户陷入僵局。是否有我没有找到的更好的解决方案?

最佳答案

“删除”对话状态并重新开始当然是处理它的一种方法,尽管有点笨拙。打电话DeleteAsync是这样做的正确方法。也许考虑到您不想删除所有 对话状态,也许只是删除 DialogState反而?你可以通过调用 IStatePropertyAccessor<DialogState>::DeleteAsync 来做到这一点反而。一切都取决于您在状态中维护的内容以及维护的位置。

现在,我发现问题在于尝试从 OnTurnError 触发您的机器人处理程序在发生这种情况时立即重新开始对话。看起来您正在调用一个静态方法 ( SendIntroCardAsync),我认为它可以工作,但它创建了一些非常紧密的耦合,这让我感到不舒服。

我的一部分想建议,如果你的 MyBot真的很想参与这种级别的异常处理,然后可能会放一个实际的 try/catch进入OnTurnAsync基本上将事件广场的处理保持在其责任范围内并且能够干净地包含和触发 SendIntroCardAsync 的机器人本身。 .然后,在这种情况下,OnTurnError除非机器人未能正确处理异常,否则可能永远不会被击中。除了对 SendIntroCardAsync 的调用外,我仍会保留该处理程序逻辑中的所有内容 ,但现在您知道只有在机器人未能正确处理异常(这应该是极其罕见的)或某个上游中间件抛出异常的情况下才会触发。不过,我也不太喜欢这个,因为它给机器人带来了责任,否则它可能是不可知的。

我认为,鉴于此,我可能会采用的 final方法是构建一个特定的中间件,我将其安装在执行顶级异常处理的管道的“顶部”,而不是知道什么一旦完成处理,它实际上只是重新执行整个管道一些可配置的次数。这样你的下游中间件和机器人从顶级异常处理的角度来看仍然是“愚蠢的”,但是你仍然可以通过在注册时使用这个中间件配置回调来选择要做什么(在你的情况下删除一些状态),并且,最终,一旦将异常作为新请求处理,您的机器人将看到该回合的重播。这个中间件甚至可以向 ITurnContext::TurnState 添加一些东西让下游逻辑检测到它处于重放状态并且行为略有不同的包。例如,假设您的机器人能够执行此操作:

public async Task OnTurnAsync(ITurnContext turnContext, CancellationToken cancellationToken = default(CancellationToken))
{
if(turnContext.IsReplayingTurnBecauseOfException())
{
... send sorry msg and restart dialogs from wherever you want ...
}
}

哪里IsReplayingTurnBecauseOfException (供辩论)是 ITurnContext 的扩展方法这将与这个新的中间件一起提供,以从阅读中抽象代码 TurnState直接详解。像这样的东西:

public static bool IsReplayingTurnBecauseOfException(this ITurnContext turnContext) =>
turnContext.TurnState.ContainsKey("MySuperAwesomeExceptionHandlingMiddleware.IsReplayingBecauseOfException");

关于c# - Bot Framework v4.2 - 优雅地从 OnTurnError 异常中恢复,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/54636919/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com