Это похоже на дилемму дизайна.Я рекомендую изменить приоритеты вашего бота так, чтобы LUIS вызывался only , если ваш диалог не был должным образом отреагирован.Это может быть достигнуто путем перемещения IsTurnInterruptedAsync
из OnTurnAsync
в метод проверки.Метод validator может быть передан в качестве аргумента в конструктор вашей подсказки:
_dialogs.Add(new ConfirmPrompt(CONFIRMPROMPT, ValidateAsync));
Вы захотите убедиться, что к вашему главному намерению можно получить доступ из любого места, если ваша подсказка находится в другом классе.Вы можете сделать это, добавив верхнее намерение к своему состоянию хода, то есть состоянию, которое длится только в пределах одного хода.Включите этот код в OnTurnAsync
:
var topScoringIntent = luisResults?.GetTopScoringIntent();
var topIntent = topScoringIntent.Value.intent;
// Include this:
turnContext.TurnState.Add("topIntent", topIntent);
Ваш метод ValidateAsync
может выглядеть следующим образом:
private async Task<bool> ValidateAsync(PromptValidatorContext<bool> promptContext, CancellationToken cancellationToken)
{
if (promptContext.Recognized.Succeeded)
{
return true;
}
await IsTurnInterruptedAsync(promptContext.Context);
return false;
}
Поскольку IsTurnInterruptedAsync
теперь может быть в другом классе, он будетнеобходимо получить доступ к верхнему намерению через ваше состояние хода.Если _dialogs
находится вне области видимости, вы можете добавить это к состоянию своего хода или просто сделать его публичным / статическим свойством.
private async Task<bool> IsTurnInterruptedAsync(ITurnContext turnContext)
{
var dc = await _dialogs.CreateContextAsync(turnContext);
var topIntent = turnContext.TurnState.Get<string>("topIntent");
// See if there are any conversation interrupts we need to handle.
if (topIntent.Equals(CancelIntent))
{
// . . .
Таким образом, прерывание произойдет только в том случае, если произнесенонедопустимо для диалога.
Возможно, вы захотите разрешить прерывания, даже если высказывание допустимо для диалога.Конечно, для текстового приглашения все допустимо, но вы все равно не можете позволить пользователю вводить «Что мне делать?»как их зовут.Если вы хотите сначала отправить высказывание в LUIS для определенных типов диалогов и сначала отправить высказывание в диалоговое окно для других типов диалогов, вы можете проверить тип диалога, находящегося в верхней части стека, следующим образом:
var activeDialog = _dialogs.Find(dc.ActiveDialog.Id);
if (activeDialog is ConfirmPrompt || activeDialog is ChoicePrompt)