Core-Bot示例(https://github.com/microsoft/BotBuilder-Samples/tree/master/samples/csharp_dotnetcore/13.core-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();
}
}
}
}
我想使用LUIS来确定用户是否试图通过检查帮助意图来中断当前对话框。
问题是我不想对LUIS进行两次调用(即首先要检查它是否被打断,其次要在对话框继续时获取意图),并且我无法传递识别器结果通过OnContinueDialogAsync()方法转到对话框。
var result = await InterruptAsync(innerDc, cancellationToken);
if (result != null)
{
return result;
}
return await base.OnContinueDialogAsync(innerDc, cancellationToken);
我认为可以只进行一次呼叫,然后使用状态访问器将识别结果存储在用户状态中,但这对我来说似乎是一种解决方法。
在中断和对话框中使用LUIS的推荐方法是什么?
答案 0 :(得分:0)
这是我使用Redis Cache的方法。
我将创建一个“中断对话框”,我需要启用中断的任何对话框都可以继承该对话框。在此对话框中,我将调用LUIS识别器,而不是进行文本比较,这将返回意图。
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;
}
然后,在识别器类中,我可以为每种发音缓存LUIS Result。您必须确保每次重新发布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;
}