#c# #botframework #chatbot
#c# #botframework #чат-бот
Вопрос:
Я меняю код, который был реализован в Framework 3, на Framework v4.
Вариант использования выглядит следующим образом: пользователь вводит что-то вроде «Я ищу XY». Мы определяем намерение, если это MyIntent, мы ищем входные данные в базе данных, и если мы его находим, мы показываем пользователю текст типа «Я нашел ваш элемент поиска в базе данных». Затем мы показываем другой текст (последующий вопрос), в котором говорится что-то вроде «Как называется отдел?».
Пользователь может ввести что-то, и это будет обработано. НО дело в том, что на этом этапе пользователь может снова сказать «Я ищу ABC». То есть пользователь может игнорировать то, что чат-бот задал дополнительный вопрос, и ввести обычный ввод. И ожидается, что чат-бот также обработает его как обычный.
В то же время, если в начале введенный элемент не найден в базе данных, мы хотим вернуть что-то вроде «извините, я не смог найти его в базе данных. Есть ли что-нибудь еще, чем я могу вам помочь?»
Я имею в виду, у меня есть условие внутри этого намерения.
Ранее эта часть текстовой подсказки была реализована просто:
PromptDialog.Text(context, answerMe, "What is the name of the department?", $"Sorry I don't understand.", 3);
В котором context
имеет тип IDialogContext
и answerMe
является методом, подобным следующему:
private async Task answerMe(IDialogContext context, IAwaitable<string> res1)
{
string text = await res1;
if (Functions.IsCancelList(text, CancelOptionsEqual, CancelOptionsContain))
{
await CancelDialog(context, "Empty");
}
else
{
string s = text;
bool str=Functions.isText(s);
...
await CallMethod(context, text);
}
}
Теперь мой класс выглядит следующим образом:
using Microsoft.Bot.Builder;
using Microsoft.Bot.Builder.Dialogs;
using Microsoft.Extensions.Configuration;
using Microsoft.Extensions.Logging;
using Newtonsoft.Json;
using RestSharp;
using System;
using System.Threading;
using System.Threading.Tasks;
using XYT.Models;
using XYT.Services;
namespace XYZ.Dialogs
{
public class MyMainDialog: MainDialogBase
{
private readonly ICommonBotServices _commonBotServices;
public MyMainDialog(IConfiguration configuration, ILogger<MainDialogBase> logger, ICommonBotServices commonBotServices, IServiceProvider serviceProvider, UserState userState)
: base(configuration, logger, serviceProvider, userState)
{
_commonBotServices = commonBotServices;
}
protected override async Task<DialogTurnResult> ProcessInput(WaterfallStepContext wtrflCntxt, CancellationToken cancellationToken)
{
var result = await _commonBotServices.Luis.RecognizeAsync<MyRecognizer>(wtrflCntxt.Context, cancellationToken);
var intent = result.TopIntent();
switch (intent.intent)
{
case MyRecognizer.Intent.MyIntent:
await wtrflCntxt.Context.SendActivityAsync($"Let me search");
String answer = $"I found it in the database,...";
await wtrflCntxt.Context.SendActivityAsync(answer);
//??? to be implemented
return await wtrflCntxt.EndDialogAsync();
}
}
}
Я не знаю, как мне следует реализовать вариант использования. Я не думаю, что диалог водопада является правильным для меня.
Будем признательны за любую помощь.
Ответ №1:
Во-первых, я бы взглянул на документы по переходу с V3 на V4, если вы еще этого не сделали.
Есть много разных способов добиться того, чего вы хотите, поэтому мне сложно дать точный ответ. В целом, я бы сказал, что диалоговые окна водопада — это правильный путь.
Если вы используете диалоговые окна водопада, похоже, вам нужно будет обрабатывать прерывания, чтобы, если:
- Пользователь спрашивает «Я ищу XY»
- Бот запускает диалоговое окно водопада и запрашивает: «Как называется отдел?»
- Пользователь игнорирует приглашение и спрашивает: «Я ищу ABC»
… он должен иметь возможность прерывать диалог. Для этого я бы посмотрел на образец основного бота. Он обрабатывает прерывания через диалоговое окно отмены и справки. По сути, весь пользовательский ввод сначала отправляется в это диалоговое окно. Если пользователь говорит «отмена» или «справка», он прерывает текущее диалоговое окно и обрабатывает эти намерения. Вы, вероятно, сделали бы что-то похожее с MyIntent
, вместо отмены и справки. Однако обратите внимание, что в этом примере для этого не используется LUIS. Вам нужно, чтобы LUIS искал намерения, а затем прерывал их на основе
Если вы ищете что-то более гибкое, вы, вероятно, захотите рассмотреть адаптивные диалоги. Диалоги водопада очень программны; if user says "X" in this circumstance, do "Y"
. Адаптивные диалоги намного более гибкие, поскольку на самом деле не имеет значения, что пользователь делает в данный момент — если они говорят что-то с соответствующим намерением, запускается соответствующий диалог. Я думаю, это больше то, что вы ищете, но у нас нет документации по миграции для этого. Вот несколько примеров адаптивного диалога
Composer, конструктор ботов на основе графического интерфейса, основан на адаптивных диалоговых окнах, и вы можете даже предпочесть это.