Поддельный ответ LUIS с LuisRecognizer не работает

Я пытаюсь имитировать вызовы LUIS через nock, который использует LuisRecognizer из botbuilder-ai. Вот соответствующая информация.

Сам бот вызывает LUIS и получает результат через const recognizerResult = await this.dispatchRecognizer.recognize(context);. Я получил фактический результат, как показано ниже:

{"text":"I want to look up my order","intents":{"viewOrder":{"score":0.996454835},"srStatus":{"score":0.0172454268},"expediteOrder":{"score":0.0108480565},"escalate":{"score":0.007967358},"qna":{"score":0.00694736559},"Utilities_Cancel":{"score":0.005627355},"manageProfile":{"score":0.004953466},"getPricing":{"score":0.001781322},"Utilities_Help":{"score":0.0007197641},"getAvailability":{"score":0.0005667514},"None":{"score":0.000321137835}},"entities":{"$instance":{}},"sentiment":{"label":"negative","score":0.171873689},"luisResult":{"query":"I want to look up my order","topScoringIntent":{"intent":"viewOrder","score":0.996454835},"intents":[{"intent":"viewOrder","score":0.996454835},{"intent":"srStatus","score":0.0172454268},{"intent":"expediteOrder","score":0.0108480565},{"intent":"escalate","score":0.007967358},{"intent":"qna","score":0.00694736559},{"intent":"Utilities.Cancel","score":0.005627355},{"intent":"manageProfile","score":0.004953466},{"intent":"getPricing","score":0.001781322},{"intent":"Utilities.Help","score":0.0007197641},{"intent":"getAvailability","score":0.0005667514},{"intent":"None","score":0.000321137835}],"entities":[],"sentimentAnalysis":{"label":"negative","score":0.171873689}}}

Для краткости ниже я буду называть это «распознавательResult». Я успешно перехватываю вызов API в моем тестовом файле с помощью nock со следующей конфигурацией:

nock('https://westus.api.cognitive.microsoft.com')
.post(/.*/)
.reply(200,{recognizerResult});

Я пробовал возвращать как объект JSON, так и строку, хотя я почти уверен, что это должен быть объект JSON, как показано (я издеваюсь над вызовом создателя QnA с тем же подходом, который работает). Когда я запускаю этот тест через мокко, я получаю следующую ошибку:

TypeError: Cannot read property 'replace' of undefined
    at LuisRecognizerV2.normalizeName (node_modules\botbuilder-ai\src\luisRecognizerOptionsV2.ts:96:21)
    at luisResult.intents.reduce (node_modules\botbuilder-ai\src\luisRecognizerOptionsV2.ts:104:31)
    at Array.reduce (<anonymous>)
    at LuisRecognizerV2.getIntents (node_modules\botbuilder-ai\src\luisRecognizerOptionsV2.ts:102:32)
    at LuisRecognizerV2.<anonymous> (node_modules\botbuilder-ai\src\luisRecognizerOptionsV2.ts:81:27)
    at Generator.next (<anonymous>)
    at fulfilled (node_modules\botbuilder-ai\lib\luisRecognizerOptionsV2.js:11:58)
    at process._tickCallback (internal/process/next_tick.js:68:7)

Я просмотрел рассматриваемый код в файле luisRecognizerOptionsV2.ts, но не вижу, в чем проблема. Замена является частью нормализации имени намерения, которое предназначено для замены неподдерживаемых символов на "_". Бот работает нормально при развертывании в Azure (и локально), и тесты работают без имитации вызова. Однако я действительно хочу иметь возможность проверить это, не выполняя фактических вызовов LUIS. Есть идеи, почему я получаю эту ошибку и как ее исправить?

Для справки, вот макет QnA Maker, который работает, хотя обратите внимание, что я использую для этого простой вызов REST вместо распознавателя.

nock('https://myqnaservicename.azurewebsites.net')
.post(/.*/)
.reply(200, {"answers": [{"questions": ["I need an unrecognized utterance for testing"], "answer": "I can hear you now!", "score": 28.48, "id": 1234}]});

person billoverton    schedule 22.01.2020    source источник


Ответы (1)


Проблема в том, что ваш {recognizerResult} является тем, что сохраняется в const recognizerResult, но не тем, что возвращается этим вызовом API.

Чтобы найти все это, нужно много копаться, но клиент LUIS V2 получает ответ API, а затем преобразует его в recognizerResult.

У вас есть несколько вариантов "исправить" это:

  1. Установите точку останова в этом node_modules\botbuilder-ai\src\luisRecognizerOptionsV2 файле на этой const result = строке и возьмите luisResult.
  2. Используйте что-то вроде Fiddler, чтобы записать фактический ответ API и использовать его
  3. Напишите это вручную

Для справки вы можете увидеть, как мы это делаем в наших тестах:

Вы можете видеть, что наш nock () возвращает response.v2, что не содержит .topScoringIntent, что является то, что он ищет, поэтому возникает ошибка.

В частности, фиктивный ответ должен состоять только из атрибутов v2 / luisResults. Другими словами, при использовании luisRecognizer ответ, установленный в nock, должен быть

.reply(200,{ "query": "Sample query", "topScoringIntent": { "intent": "desiredIntent", "score":1}, "entities":[]});

Если вы посмотрите на приведенные выше тестовые данные, в фактическом ответе есть и другие атрибуты. Но это минимально необходимый ответ, если вы просто пытаетесь заставить topIntent протестировать маршрутизацию. Если вам нужны другие атрибуты, вы можете добавить их, например вы можете добавить все в v2, как в этот файл или некоторые из более сложных файлов с такими вещами, как множественные намерения.

person mdrichardson    schedule 22.01.2020
comment
Я обновил ответ с атрибутом v2 согласно образцам, но продолжал получать ту же ошибку. По какой-то причине я в настоящее время не могу запустить отладчик (работаю над выяснением этого). Я также просто поместил оператор console.log в файл luisRecognizerOptionsV2, но он тоже ничего не показывает. Я тоже не вижу пакетов в Fiddler. - person billoverton; 23.01.2020
comment
@billoverton Интересно. Не возражаете поделиться своим кодом? Возможно, мне будет проще / быстрее помочь отладить. vDASHmicricATmicrosoftDOTcom (замените заглавные буквы символом). Может потребоваться изменить путь post(), чтобы он совпадал с нашим? Это бы меня немного удивило, но пока на меня ничего не прыгает. - person mdrichardson; 23.01.2020
comment
Я понял. Я не понимал, что мне нужно было предоставить атрибут v2 как ответ, а не как часть ответа. Остальные результаты добавляет модуль. Другими словами, мой ответ в nock должен быть .reply(200,{ "query": "Sample query", "topScoringIntent": { "intent": "viewOrder", "score":0.991234567}, "entities":[]}); Теперь он работает и приму ваш ответ, но может быть полезно уточнить внутри явно, как должен выглядеть ответ nock. - person billoverton; 23.01.2020
comment
@billoverton Я думаю, я понимаю, что вы имеете в виду. Можете ли вы отредактировать мой ответ, чтобы он лучше соответствовал тому, что вам нужно? - person mdrichardson; 23.01.2020
comment
Добавлен. Когда он появится, пожалуйста, посмотрите и убедитесь, что вы согласны с моими выводами. - person billoverton; 23.01.2020
comment
@billoverton LGTM. Я не тестировал это или что-то в этом роде, но это имеет смысл, и я вам доверяю. Хорошая работа! - person mdrichardson; 23.01.2020