C# 使用LUIS中断对话的最佳实践是什么 核心BOT示例()显示了一种处理中断的方法,例如当用户在对话框中间键入“帮助”或“取消”时。它使用文本比较: private async Task<DialogTurnResult> InterruptAsync(DialogContext innerDc, CancellationToken cancellationToken) { if (innerDc.Context.Activity.Type == ActivityTypes.Message) { var text = innerDc.Context.Activity.Text.ToLowerInvariant(); switch (text) { case "help": case "?": await innerDc.Context.SendActivityAsync($"Show Help...", cancellationToken: cancellationToken); return new DialogTurnResult(DialogTurnStatus.Waiting); case "cancel": case "quit": await innerDc.Context.SendActivityAsync($"Cancelling", cancellationToken: cancellationToken); return await innerDc.CancelAllDialogsAsync(); } } } }
我认为只打一次电话,然后使用状态访问器将识别结果存储在用户状态中是可能的,但这对我来说就像是一项工作C# 使用LUIS中断对话的最佳实践是什么 核心BOT示例()显示了一种处理中断的方法,例如当用户在对话框中间键入“帮助”或“取消”时。它使用文本比较: private async Task<DialogTurnResult> InterruptAsync(DialogContext innerDc, CancellationToken cancellationToken) { if (innerDc.Context.Activity.Type == ActivityTypes.Message) { var text = innerDc.Context.Activity.Text.ToLowerInvariant(); switch (text) { case "help": case "?": await innerDc.Context.SendActivityAsync($"Show Help...", cancellationToken: cancellationToken); return new DialogTurnResult(DialogTurnStatus.Waiting); case "cancel": case "quit": await innerDc.Context.SendActivityAsync($"Cancelling", cancellationToken: cancellationToken); return await innerDc.CancelAllDialogsAsync(); } } } },c#,botframework,C#,Botframework,我认为只打一次电话,然后使用状态访问器将识别结果存储在用户状态中是可能的,但这对我来说就像是一项工作 在中断和对话框中使用LUIS的推荐方法是什么?以下是我如何使用Redis Cache实现这一点 我将创建一个中断对话框,它可以被我需要的任何对话框继承以启用中断。在这个对话框中,我将调用LUIS recognizer,它将返回意图,而不是进行文本比较 protected override async Task<DialogTurnResult> OnContinueDialogAsy
在中断和对话框中使用LUIS的推荐方法是什么?以下是我如何使用Redis Cache实现这一点 我将创建一个中断对话框,它可以被我需要的任何对话框继承以启用中断。在这个对话框中,我将调用LUIS recognizer,它将返回意图,而不是进行文本比较
protected override async Task<DialogTurnResult> OnContinueDialogAsync(DialogContext innerDc, CancellationToken cancellationToken = default)
{
var result = await InterruptAsync(innerDc, cancellationToken);
if (result != null)
{
return result;
}
return await base.OnContinueDialogAsync(innerDc, cancellationToken);
}
private async Task<DialogTurnResult> InterruptAsync(DialogContext innerDc, CancellationToken cancellationToken)
{
if (innerDc.Context.Activity.Type == ActivityTypes.Message)
{
var luisResult = await _recognizer.RecognizeAsync<MyLuisModel>(innerDc.Context, cancellationToken);
switch (luisResult.TopIntent().intent)
{
case MyLuisModel.Intent.Cancel:
return await CancelAllDialogsAsync(innerDc, cancellationToken);
case MyLuisModel.Intent.SignOut:
return await SignOutAsync(innerDc, cancellationToken);
}
}
return null;
}
受保护的覆盖异步任务OnContinueDialogAsync(DialogContext innerDc,CancellationToken CancellationToken=default)
{
var结果=等待中断异步(innerDc,cancellationToken);
如果(结果!=null)
{
返回结果;
}
返回wait base.OnContinueDialogAsync(innerDc,cancellationToken);
}
专用异步任务中断异步(DialogContext innerDc,CancellationToken CancellationToken)
{
if(innerDc.Context.Activity.Type==ActivityTypes.Message)
{
var luisResult=await _recognizer.RecognizeAsync(innerDc.Context,cancellationToken);
开关(luisResult.TopIntent().intent)
{
案例MyLuisModel.Intent.Cancel:
返回Wait Wait CancelAllDialogsAsync(innerDc,cancellationToken);
案例MyLuisModel.Intent.SignOut:
返回等待SignOutAsync(innerDc,cancellationToken);
}
}
返回null;
}
然后,在识别器类中,我可以缓存每个话语的LUIS结果。您必须确保在每次重新发布LUIS模型时清除缓存,或者缓存过期时间更短
public virtual async Task<T> RecognizeAsync<T>(ITurnContext turnContext, CancellationToken cancellationToken) where T : IRecognizerConvert, new()
{
var utterance = turnContext.Activity?.AsMessageActivity()?.Text;
if (string.IsNullOrWhiteSpace(utterance)) return default;
var cacheKey = Regex.Replace(utterance, @"[^A-Za-z0-9]+", "_");
var matches = Regex.Match(cacheKey, @"[A-Za-z0-9]+");
if (!matches.Success) return default;
cacheKey = "MyBot_" + cacheKey + "_" + nameof(T);
var recognizerResult = await _cacheClient.Db15.GetAsync<T>(cacheKey);
if (recognizerResult != null) return recognizerResult;
recognizerResult = await _recognizer.RecognizeAsync<T>(turnContext, cancellationToken);
await _cacheClient.Db15.AddAsync(cacheKey, recognizerResult, TimeSpan.FromDays(1));
return recognizerResult;
}
public virtual async Task RecognizeAsync(ITurnContext turnContext,CancellationToken CancellationToken),其中T:IRecognizerConvert,new()
{
var话语=turnContext.Activity?.AsMessageActivity()?.Text;
if(string.IsNullOrWhiteSpace(话语))返回默认值;
var cacheKey=Regex.Replace(话语,@“[^A-Za-z0-9]+”,“”);
var matches=Regex.Match(cacheKey,@“[A-Za-z0-9]+”;
如果(!matches.Success)返回默认值;
cacheKey=“MyBot”+cacheKey+“+nameof(T);
var recognizerResult=await_cacheClient.Db15.GetAsync(cacheKey);
if(recognizerResult!=null)返回recognizerResult;
recognizerResult=wait _recognizer.RecognizeAsync(turnContext,cancellationToken);
wait_cacheClient.Db15.AddAsync(cacheKey,recognizerResult,TimeSpan.FromDays(1));
返回识别结果;
}
以下是我将如何使用Redis缓存实现这一点
我将创建一个中断对话框,它可以被我需要的任何对话框继承以启用中断。在这个对话框中,我将调用LUIS recognizer,它将返回意图,而不是进行文本比较
protected override async Task<DialogTurnResult> OnContinueDialogAsync(DialogContext innerDc, CancellationToken cancellationToken = default)
{
var result = await InterruptAsync(innerDc, cancellationToken);
if (result != null)
{
return result;
}
return await base.OnContinueDialogAsync(innerDc, cancellationToken);
}
private async Task<DialogTurnResult> InterruptAsync(DialogContext innerDc, CancellationToken cancellationToken)
{
if (innerDc.Context.Activity.Type == ActivityTypes.Message)
{
var luisResult = await _recognizer.RecognizeAsync<MyLuisModel>(innerDc.Context, cancellationToken);
switch (luisResult.TopIntent().intent)
{
case MyLuisModel.Intent.Cancel:
return await CancelAllDialogsAsync(innerDc, cancellationToken);
case MyLuisModel.Intent.SignOut:
return await SignOutAsync(innerDc, cancellationToken);
}
}
return null;
}
受保护的覆盖异步任务OnContinueDialogAsync(DialogContext innerDc,CancellationToken CancellationToken=default)
{
var结果=等待中断异步(innerDc,cancellationToken);
如果(结果!=null)
{
返回结果;
}
返回wait base.OnContinueDialogAsync(innerDc,cancellationToken);
}
专用异步任务中断异步(DialogContext innerDc,CancellationToken CancellationToken)
{
if(innerDc.Context.Activity.Type==ActivityTypes.Message)
{
var luisResult=await _recognizer.RecognizeAsync(innerDc.Context,cancellationToken);
开关(luisResult.TopIntent().intent)
{
案例MyLuisModel.Intent.Cancel:
返回Wait Wait CancelAllDialogsAsync(innerDc,cancellationToken);
案例MyLuisModel.Intent.SignOut:
返回等待SignOutAsync(innerDc,cancellationToken);
}
}
返回null;
}
然后,在识别器类中,我可以缓存每个话语的LUIS结果。您必须确保在每次重新发布LUIS模型时清除缓存,或者缓存过期时间更短
public virtual async Task<T> RecognizeAsync<T>(ITurnContext turnContext, CancellationToken cancellationToken) where T : IRecognizerConvert, new()
{
var utterance = turnContext.Activity?.AsMessageActivity()?.Text;
if (string.IsNullOrWhiteSpace(utterance)) return default;
var cacheKey = Regex.Replace(utterance, @"[^A-Za-z0-9]+", "_");
var matches = Regex.Match(cacheKey, @"[A-Za-z0-9]+");
if (!matches.Success) return default;
cacheKey = "MyBot_" + cacheKey + "_" + nameof(T);
var recognizerResult = await _cacheClient.Db15.GetAsync<T>(cacheKey);
if (recognizerResult != null) return recognizerResult;
recognizerResult = await _recognizer.RecognizeAsync<T>(turnContext, cancellationToken);
await _cacheClient.Db15.AddAsync(cacheKey, recognizerResult, TimeSpan.FromDays(1));
return recognizerResult;
}
public virtual async Task RecognizeAsync(ITurnContext turnContext,CancellationToken CancellationToken),其中T:IRecognizerConvert,new()
{
var话语=turnContext.Activity?.AsMessageActivity()?.Text;
if(string.IsNullOrWhiteSpace(话语))返回默认值;
var cacheKey=Regex.Replace(话语,@“[^A-Za-z0-9]+”,“”);
var matches=Regex.Match(cacheKey,@“[A-Za-z0-9]+”;
如果(!matches.Success)返回默认值;
cacheKey=“MyBot”+cacheKey+“+nameof(T);
var recognizerResult=await_cacheClient.Db15.GetAsync(cacheKey);
if(recognizerResult!=null)返回recognizerResult;
recognizerResult=wait _recognizer.RecognizeAsync(turnContext,cancellationToken);
wait_cacheClient.Db15.AddAsync(cacheKey,recognizerResult,TimeSpan.FromDays(1));
返回识别结果;
}
您可以通过更新luiselper
中的ExecuteLuisQuery
方法来处理“帮助”意图,从而实现所需的结果。这样你就可以不用打断别人了。我不知道您为什么要避免这两个LUIS调用,因为开销非常小。也许您可以提供有关您的场景的更多信息,其中概述了您希望减少呼叫数量的原因?我敢打赌,您将遇到更多问题,并最终通过尝试缓存LUIS结果来避免进行额外的API调用,从而为您的应用程序增加不必要的复杂性。您是对的,有两个LUIS调用可能不会明显变慢。然而,这是一项付费服务,通过这种结构,您拨打的电话数量几乎是所需电话数量的两倍。此外,每一句话,除了被打断者抓住的那句,都会被路易斯接受两次。因为它背后有人工智能,我担心这会