Я создал чатбота v4 с Microsoft Bot Framework, и он работал нормально. У нас есть две среды QA и PROD. Со временем у бота появилось больше функций и диалогов.
Мы обнаружили, что в PROD (который имеет тот же код, что и QA) он не работает нормально, иногда он выходит из текущего диалога и возвращается в init.
Я уже пытался подключите базу QnA QA к PROD, чтобы увидеть, если это проблема с БД, но это не решило проблему.
это часть моего кода
в Bot.cs в OnTurnAsyn c
if (activity.Type == ActivityTypes.Message)
{
// Continue the current dialog
var dialogResult = await dc.ContinueDialogAsync();
// examine results from active dialog
switch (dialogResult.Status)
{
case DialogTurnStatus.Empty:
await NewConversationFlow(turnContext, dc, conversationId, cancellationToken);
break;
case DialogTurnStatus.Waiting:
// The active Dialog is waiting for a response from the user, so do nothing.
break;
case DialogTurnStatus.Complete:
await dc.EndDialogAsync();
// do things
await NewConversationFlow(turnContext, dc, conversationId, cancellationToken);
break;
default:
await dc.CancelAllDialogsAsync();
break;
}
}
в Bot.cs в NewConversationFlow
var response = await _services.QnAServices["QnA"].GetAnswersAsync(turnContext, new QnAMakerOptions() { Top = 5, ScoreThreshold = 0.1F });
QueryResult qnaAnswer = GetQnaAnswer(response, 0.60);
await _flowService.ShortDelayWithTypingActionAsync(turnContext);
await turnContext.SendActivityAsync(response.Answer, cancellationToken: cancellationToken);
var flowValue = response.Metadata?.Where(metadata => metadata.Name == "flow").Select(metadata => metadata.Value).FirstOrDefault();
if (!string.IsNullOrEmpty(flowValue))
{
switch (flowValue)
{
case ONE:
...
default:
await dc.BeginDialogAsync(nameof(OneAnswerDialog));
break;
case TWO:
...
await dc.BeginDialogAsync(nameof(TwoAnswerDialog));
break;
case SEARCH:
await dc.BeginDialogAsync(nameof(SearchDialog));
break;
}
}
в OneAnswerDialog
// Dialog IDs
profileDialog = nameof(OneAnswerDialog);
// Add control flow dialogs
var firstCaseWaterfallSteps = new WaterfallStep[]
{
GetAnswerAsync,
SearchStepAsync,
};
AddDialog(new WaterfallDialog(profileDialog, firstCaseWaterfallSteps));
AddDialog(new TextPrompt(ResponsePrompt, ValidateResponseAsync));
Обычно происходит сбой после того, как пользователь вставляет ответ после первого вопроса (тот, который напечатан в NewConversationFlow). Я не знаю, происходит ли сбой в GetAnswerAsyn c или в ValidateResponseAsyn c, потому что я не могу отладить код в PRD.
в GetAnswerAsyn c
return await stepContext.PromptAsync(ResponsePrompt, new PromptOptions());
in ValidateResponseAsyn c
PositiveResponse = false;
var value = promptContext?.Recognized?.Value?.Trim() ?? string.Empty;
if (value != string.Empty)
{
promptContext.Recognized.Value = value;
bool userSayYes = false;
var response = await _services.QnAServices["QnA"].GetAnswersAsync(promptContext.Context, new QnAMakerOptions() { Top = 5, ScoreThreshold = 0.1F });
if (response != null && response.Length > 0)
{
var responses = response.Where(resp => resp.Metadata?.Any(metadata => metadata.Name == "metadata") ?? false).Select(x => x.Metadata);
PositiveResponse = responses.Any(metadatas => metadatas.Any(metadata => metadata.Value == "more" || metadata.Value == "no"));
if (!PositiveResponse && responses.Any(metadatas => metadatas.Any(metadata => metadata.Value == "yes")))
{
userSayYes = true;
await _flowService.DelayWithTypingActionAsync(promptContext.Context);
await promptContext.Context.SendActivityAsync("Can I help you with anything else?", cancellationToken: cancellationToken);
}
}
if (response == null || response.Length <= 0 || (!PositiveResponse && !userSayYes))
{
await _flowService.AddOrUpdateQuestion(promptContext.Context.Activity.Conversation.Id, value);
}
else if (userSayYes)
{
await _flowService.RemoveFlowTypeAndQuestion(promptContext.Context.Activity.Conversation.Id);
}
}
return true;
(если PositiveResponse имеет значение false, в последующем проходе Диалог завершается и возвращается в Bot.cs)
По какой-то причине в PROD бот «запутывается» и выходит из диалога в GetAnswerAsyn c или ValidateResponseAsyn c и вспомните NewConversationFlow .
Я прочитал в другом посте, что задержка с точечной печатью может вызвать эту проблему, я их убрал, но проблема сохраняется ...
В чем может быть проблема? Что может вызвать преждевременный выход из диалога?
Заранее спасибо.
--------------------- ----- РЕДАКТИРОВАТЬ --------------------------
Я туннелировал PRD с помощью ngrok и отладки это с VS, в данном случае бот работает ...
Что может быть? Есть какая-нибудь конфигурация Azure, которая может вызвать это? Я уже проверил тарифный план, и он не бесплатный.
------------------------- - РЕДАКТИРОВАТЬ 2 --------------------------
Я обновил GetAnswerAsyn c чтобы быть уверенным в том, что бот вводит в диалоге:
protected async Task<DialogTurnResult> GetAnswerAsync(
WaterfallStepContext stepContext,
CancellationToken cancellationToken)
{
await stepContext.Context.SendActivityAsync("What do you think? Does it answer your question?");
await stepContext.PromptAsync(ResponsePrompt, new PromptOptions());
return new DialogTurnResult(DialogTurnStatus.Waiting);
}
Кажется, что он выходит из диалогового окна в этот момент, когда ожидает приглашение пользователя ...
(«Ох, жаль это слышать!» Это болтовня, это не следующий шаг WaterFall)
Иногда бот работает. Кажется, что-то «случайное».
----------------- --------- РЕДАКТИРОВАТЬ 3 -------------------------- У меня все еще есть эта проблема ... У меня есть попытался удалить все настройки из Azure, чтобы приложение прочитало его из файла. Я использовал те же настройки в PRD и QA, но ничего ... Есть идеи?