[英]Validate prompt with luis in waterfall dialog (Bot framework V4)
我正在構建一個帶有 Bot Dialogs 擴展的機器人,但我在我的項目中遇到了一個關於瀑布對話框的問題。 如果用戶對機器人說“我想輸入一條新消息”,機器人將回答一系列問題,例如“您希望何時將消息發送給用戶”、“您希望消息說什么” “等。我正在尋找的是,當用戶被要求約會時,如果它響應“明天”,luis 將返回相應的日期,但如果用戶說“foo”,機器人將再次要求約會.
我要做的是這樣的代碼:
public class NewMessageDialog : ComponentDialog
{
private readonly BotStateService _botStateService;
private readonly BotServices _botServices;
public NewMessageDialog(string dialogId, BotStateService botStateService, BotServices botServices) : base(dialogId)
{
_botStateService = botStateService ?? throw new ArgumentNullException(nameof(botStateService));
_botServices = botServices ?? throw new ArgumentNullException(nameof(botServices));
InitializeWaterfalls();
}
private void InitializeWaterfalls()
{
var waterfallSteps = new WaterfallStep[]
{
DateToSendStep,
ExpirationTimeStep,
BodyContentStep,
SummaryStep
};
AddDialog(new WaterfallDialog($"{nameof(NewMessageDialog)}.mainFlow", waterfallSteps));
AddDialog(new DateTimePrompt($"{nameof(NewMessageDialog)}.dateCreation")); //tb
AddDialog(new NumberPrompt<double>($"{nameof(NewMessageDialog)}.expirationTime"));
AddDialog(new TextPrompt($"{nameof(NewMessageDialog)}.body.content"));
InitialDialogId = $"{nameof(NewMessageDialog)}.mainFlow";
}
private async Task<DialogTurnResult> DateCreatedStep(WaterfallStepContext stepContext, CancellationToken cancellationToken)
{
return await stepContext.PromptAsync($"{nameof(NewMessageDialog)}.dateCreation", new PromptOptions
{
Prompt = MessageFactory.Text("What is the date you want to send the message?"),
RetryPrompt = MessageFactory.Text("Please enter a date")
}, cancellationToken);
}
private async Task<DialogTurnResult> ExpirationTimeStep(WaterfallStepContext stepContext, CancellationToken cancellationToken)
{
stepContext.Values["dateToSend"] = Convert.ToDateTime(((List<DateTimeResolution>)stepContext.Result).FirstOrDefault().Value);
return await stepContext.PromptAsync($"{nameof(NewMessageDialog)}.expirationTime", new PromptOptions
{
Prompt = MessageFactory.Text("What is the expiration time?"),
RetryPrompt = MessageFactory.Text("Please enter a decimal number")
}, cancellationToken);
}
private async Task<DialogTurnResult> BodyContentStep(WaterfallStepContext stepContext, CancellationToken cancellationToken)
{
stepContext.Values["expirationTime"] = Convert.ToDateTime(((List<DateTimeResolution>)stepContext.Result).FirstOrDefault().Value);
return await stepContext.PromptAsync($"{nameof(NewMessageDialog)}.body.content", new PromptOptions
{
Prompt = MessageFactory.Text("What is the message body?")
}, cancellationToken);
}
等等...
我還沒有找到正確的方法來做到這一點:我可以問 LUIS 兩次(一次在驗證器中查看意圖是否設置日期,一次在下一步中從實體獲取正確的日期時間),我可以在驗證器中詢問 luis,然后將其保存到類屬性中以最終從那里獲取日期值......有沒有一種有效的方法來做到這一點?
另外我對聊天工具一無所知,我在搜索時在其他網站上看到過...
我建議使用 timex 識別器,就像官方示例存儲庫中Core-Bot中使用的那樣:
// Copyright (c) Microsoft Corporation. All rights reserved.
// Licensed under the MIT License.
using System.Collections.Generic;
using System.Threading;
using System.Threading.Tasks;
using Microsoft.Bot.Builder;
using Microsoft.Bot.Builder.Dialogs;
using Microsoft.Bot.Schema;
using Microsoft.Recognizers.Text.DataTypes.TimexExpression;
namespace Microsoft.BotBuilderSamples.Dialogs
{
public class DateResolverDialog : CancelAndHelpDialog
{
private const string PromptMsgText = "When would you like to travel?";
private const string RepromptMsgText = "I'm sorry, to make your booking please enter a full travel date including Day Month and Year.";
public DateResolverDialog(string id = null)
: base(id ?? nameof(DateResolverDialog))
{
AddDialog(new DateTimePrompt(nameof(DateTimePrompt), DateTimePromptValidator));
AddDialog(new WaterfallDialog(nameof(WaterfallDialog), new WaterfallStep[]
{
InitialStepAsync,
FinalStepAsync,
}));
// The initial child Dialog to run.
InitialDialogId = nameof(WaterfallDialog);
}
private async Task<DialogTurnResult> InitialStepAsync(WaterfallStepContext stepContext, CancellationToken cancellationToken)
{
var timex = (string)stepContext.Options;
var promptMessage = MessageFactory.Text(PromptMsgText, PromptMsgText, InputHints.ExpectingInput);
var repromptMessage = MessageFactory.Text(RepromptMsgText, RepromptMsgText, InputHints.ExpectingInput);
if (timex == null)
{
// We were not given any date at all so prompt the user.
return await stepContext.PromptAsync(nameof(DateTimePrompt),
new PromptOptions
{
Prompt = promptMessage,
RetryPrompt = repromptMessage,
}, cancellationToken);
}
// We have a Date we just need to check it is unambiguous.
var timexProperty = new TimexProperty(timex);
if (!timexProperty.Types.Contains(Constants.TimexTypes.Definite))
{
// This is essentially a "reprompt" of the data we were given up front.
return await stepContext.PromptAsync(nameof(DateTimePrompt),
new PromptOptions
{
Prompt = repromptMessage,
}, cancellationToken);
}
return await stepContext.NextAsync(new List<DateTimeResolution> { new DateTimeResolution { Timex = timex } }, cancellationToken);
}
private async Task<DialogTurnResult> FinalStepAsync(WaterfallStepContext stepContext, CancellationToken cancellationToken)
{
var timex = ((List<DateTimeResolution>)stepContext.Result)[0].Timex;
return await stepContext.EndDialogAsync(timex, cancellationToken);
}
private static Task<bool> DateTimePromptValidator(PromptValidatorContext<IList<DateTimeResolution>> promptContext, CancellationToken cancellationToken)
{
if (promptContext.Recognized.Succeeded)
{
// This value will be a TIMEX. And we are only interested in a Date so grab the first result and drop the Time part.
// TIMEX is a format that represents DateTime expressions that include some ambiguity. e.g. missing a Year.
var timex = promptContext.Recognized.Value[0].Timex.Split('T')[0];
// If this is a definite Date including year, month and day we are good otherwise reprompt.
// A better solution might be to let the user know what part is actually missing.
var isDefinite = new TimexProperty(timex).Types.Contains(Constants.TimexTypes.Definite);
return Task.FromResult(isDefinite);
}
return Task.FromResult(false);
}
}
}
這不是對 LUIS 的調用,它只是檢查您是否輸入了有效的日期時間,並將其設置為自己的小瀑布對話框。 正如您從以下檢查中看到的,它適用於您解釋的測試用例('tomorrow' vs 'foo'):
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.