Каков наилучший способ предоставить LuisRecognizer предопределенный текстовый контекст, отличный от ITurnContext RecognizeAsync, полученный из пользовательского ввода? - PullRequest
0 голосов
/ 23 июня 2019

Моя первая идея завершить вызов luis - установить turnContext, но большинство его свойств доступно только для чтения.Также я знал бы, как создать точный контекст, который будет создан из пользовательского ввода, в основном из текста, который они вводят, предоставляя контекст, необходимый для прохождения через LuisRecognizer.

Моя вторая идея, связанная с водопадом, который вызывает LuisHelper (stepContext.Context), также установить это вручную.Вы не можете, потому что это тоже только для чтения, как и stepContext.Result ...

Так что мой вопрос заключается в том, есть ли способ передать luisRecognizer текстовую фразу, которая может быть добавлена ​​к ответу пользователя.

Пример ... Если я спрошу пользователя, какой цвет машины вы ищете.Я знаю, что мое намерение - CarColor, поэтому, если пользователи говорят ... Синий, я хочу добавить к этому утверждению. Клиенту нужен автомобиль синего цвета ... чтобы я мог абстрагироваться от объекта, который был бы синим, и знать, что я являюсьссылаясь на намерение CarColor.Просто поймите, почему я хочу это сделать.

Каким образом я могу взять ответ пользователя и добавить к нему текст, а затем отправить его как фразу в вызов LuisRecognizer.

вот код для справки:

     private async Task<DialogTurnResult> ActStepAsync(WaterfallStepContext stepContext, CancellationToken cancellationToken)
            {
                stepContext.Values["tester"] = "Travel to Chicago";

                stepContext.Result = "christian";

                // Call LUIS and gather any potential booking details. (Note the TurnContext has the response to the prompt.)
                var bookingDetails = stepContext.Result != null
                        ?
                    await LuisHelper.ExecuteLuisQuery(Configuration, Logger, stepContext.Context, cancellationToken)
                        :
                    new BookingDetails();

                // In this sample we only have a single Intent we are concerned with. However, typically a scenario
                // will have multiple different Intents each corresponding to starting a different child Dialog.

                // Run the BookingDialog giving it whatever details we have from the LUIS call, it will fill out the remainder.
                return await stepContext.BeginDialogAsync(nameof(BookingDialog), bookingDetails, cancellationToken);
            }

1 Ответ

1 голос
/ 24 июня 2019

Как

Этого можно достичь, установив свойство Text для Activity, которое находится под свойством Context, следующим образом:

stepContext.Context.Activity.Text = "The phrase that you want to pass through here";

Выполните это назначение ДО , по которому вы звоните LuisHelper.ExecuteLuisQuery, в противном случае ваше обновленное значение Text не будет отправлено.


Почему это должноработа

Поскольку LuisHelper.ExecuteLuisQuery(Configuration, Logger, stepContext.Context, cancellationToken) проходит через stepContext.Context и под сценами здесь этот контекст передается в вызов RecognizeAsync внутри метода ExecuteLuisQuery.Кроме того, переменная recognizer имеет тип LuisRecognizer, исходный код для этого класса доступен здесь .Строка, которая вас интересует, это эта , которая показывает Text свойство turnContext, используемого в качестве высказывания, которое передается через.


Объяснение исходного кода / Дополнительная информация

Для дальнейшего использования (в случае изменения кода или ссылок) упрощенная версия исходного кода:

public virtual async Task<RecognizerResult> RecognizeAsync(ITurnContext turnContext, CancellationToken cancellationToken)
            => await RecognizeInternalAsync(turnContext, null, null, null, cancellationToken).ConfigureAwait(false);

, где RecognizeInteralAsync выглядит следующим образом:

private async Task<RecognizerResult> RecognizeInternalAsync(ITurnContext turnContext, LuisPredictionOptions predictionOptions, Dictionary<string, string> telemetryProperties, Dictionary<string, double> telemetryMetrics, CancellationToken cancellationToken)
{
    var luisPredictionOptions = predictionOptions == null ? _options : MergeDefaultOptionsWithProvidedOptions(_options, predictionOptions);

    BotAssert.ContextNotNull(turnContext);

    if (turnContext.Activity.Type != ActivityTypes.Message)
    {
        return null;
    }

    // !! THIS IS THE IMPORTANT LINE !!
    var utterance = turnContext.Activity?.AsMessageActivity()?.Text;
    RecognizerResult recognizerResult;
    LuisResult luisResult = null;

    if (string.IsNullOrWhiteSpace(utterance))
    {
        recognizerResult = new RecognizerResult
        {
            Text = utterance,
            Intents = new Dictionary<string, IntentScore>() { { string.Empty, new IntentScore() { Score = 1.0 } } },
            Entities = new JObject(),
        };
    }
    else
    {
        luisResult = await _runtime.Prediction.ResolveAsync(
            _application.ApplicationId,
            utterance,
            timezoneOffset: luisPredictionOptions.TimezoneOffset,
            verbose: luisPredictionOptions.IncludeAllIntents,
            staging: luisPredictionOptions.Staging,
            spellCheck: luisPredictionOptions.SpellCheck,
            bingSpellCheckSubscriptionKey: luisPredictionOptions.BingSpellCheckSubscriptionKey,
            log: luisPredictionOptions.Log ?? true,
            cancellationToken: cancellationToken).ConfigureAwait(false);

        recognizerResult = new RecognizerResult
        {
            Text = utterance,
            AlteredText = luisResult.AlteredQuery,
            Intents = LuisUtil.GetIntents(luisResult),
            Entities = LuisUtil.ExtractEntitiesAndMetadata(luisResult.Entities, luisResult.CompositeEntities, luisPredictionOptions.IncludeInstanceData ?? true),
        };
        LuisUtil.AddProperties(luisResult, recognizerResult);
        if (_includeApiResults)
        {
            recognizerResult.Properties.Add("luisResult", luisResult);
        }
    }

    // Log telemetry code
    await OnRecognizerResultAsync(recognizerResult, turnContext, telemetryProperties, telemetryMetrics, cancellationToken).ConfigureAwait(false);

    var traceInfo = JObject.FromObject(
        new
        {
            recognizerResult,
            luisModel = new
            {
                ModelID = _application.ApplicationId,
            },
            luisOptions = luisPredictionOptions,
            luisResult,
        });

    await turnContext.TraceActivityAsync("LuisRecognizer", traceInfo, LuisTraceType, LuisTraceLabel, cancellationToken).ConfigureAwait(false);
    return recognizerResult;
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...