Microsoft botframework V4, Custom Skill.
Машинопись
Навык не может получить информацию, переданную от виртуального помощника через SkillContext.
Шаг 1. Создайте виртуальное устройство с помощью https://botbuilder.myget.org/feed/aitemplates/package/npm/botbuilder-solutions.
Шаг 2. Создайте навык с помощью команды генератора навыков.
" https://botbuilder.myget.org/feed/aitemplates/package/npm/botbuilder-skills "
Шаг 3. Добавлен файл манифеста навыка с параметром слота.
Шаг 4: Установите SkillContext со значением параметра слота.
Шаг 5: попробуйте получить доступ к значению SkillContext в Skill.
Объект, установленный в SkillContext, должен быть доступен для навыка, если совпал атрибут «слот».
Но навык не может получить SkillContext.
"SkillMiddleware" должен поддерживать skillContextAccessor и заполнять SkillContext параметрами слота.
После некоторой работы выяснилось, что CustomSkillAdapter заполняется значением «skillContextAccessor».
Текущий код:
класс экспорта CustomSkillAdapter расширяет SkillHttpBotAdapter {
конструктор(
telemetryClient: TelemetryClient,
talkState: ConversationState,
skillContextAccessor: StatePropertyAccessor
dialogStateAccessor: StatePropertyAccessor
...
) {
супер (телеметрияКлиент);
[...]
this.use (новый SkillMiddleware (talkState, dialogStateAccessor));
[...]
}
}
Ожидаемый код в соответствии с этим " https://microsoft.github.io/botframework-solutions/howto/skills/skillenablesav4bot/ "
класс экспорта CustomSkillAdapter расширяет SkillHttpBotAdapter {
конструктор(
telemetryClient: TelemetryClient,
talkState: ConversationState,
skillContextAccessor: StatePropertyAccessor
dialogStateAccessor: StatePropertyAccessor
...
) {
супер (телеметрияКлиент);
[...]
this.use (новый SkillMiddleware (talkState, skillContextAccessor, dialogStateAccessor));
[...]
}
}
Спасибо,
Эдвард
Привет @ Edwardfelix08 , извиняюсь за задержку с ответом.
Мы рассмотрели документацию по включению бота V4 в качестве навыка (структура документа изменилась, предыдущая ссылка вернула 404) и поняли, что она не обновлялась правильно после некоторых изменений в коде, поэтому мы обновим эту документацию.
Следуя инструкциям по воспроизведению, мы понимаем, что у вас есть некоторая информация о вашем виртуальном помощнике, и вы сохраняете эту информацию в SkillContext
виртуального помощника, и когда навык получит сообщение, вы хотите получить эту информацию из SkillContext
. Это верно?
Привет @dfavretto.
Да, это правильно.
Привет, @ Edwardfelix08 , мы тестировали этот сценарий и создали руководство о том, как заставить его работать. Примите во внимание , что образец-помощник не готов вне коробки для использования в этом сценарии, поэтому мы даем три шага в некоторых незначительных изменений , необходимых для достижения этой цели :
Прежде всего, вы должны сохранить желаемую информацию в контексте навыков , чтобы получить ее позже. Это необходимо сделать до того,
Внутри mainDialog вы должны использовать skillContextAccessor для получения SkillContext, соответствующего вашему контексту. Это можно сделать с помощью следующих строк:
const sc: SkillContext = await this.skillContextAccessor.get(dc.context, new SkillContext());
const skillContext: SkillContext = Object.assign(new SkillContext(), sc);
Теперь, когда ваш SkillContext сохранен в переменной, вы можете получить или установить любое значение. Не забывайте, что значения внутри SkillContext представляют собой пару «ключ-значение», поэтому убедитесь, что ваши ключи уникальны, если вы не хотите перезаписывать свои значения. Теперь вы можете сохранить что угодно, например значение местоположения:
skillContext.setObj('location', locationObj);
Наконец, установите свой SkillContext с помощью skillContextAccessor, чтобы эта информация сохранялась в вашем userState :
await this.skillContextAccessor.set(dc.context, skillContext);
После сохранения информации в SkillContext можно перенаправить сообщение в Skill, но до того, как сообщение достигнет Skill, SkillDialog внутри botbuilder-skills
обработает SkillContext во время метода onBeginDialog , который выполняется только один раз, когда Навык вызывается впервые.
Этот метод автоматически выполнит следующие шаги:
Третий и последний шаг - заполнить SkillState информацией, отправленной из виртуального помощника, с помощью следующих шагов:
typescript
if (semanticAction !== undefined && Object.keys(semanticAction.entities)
.find((key: string) => key === "location"))
Надеюсь, эти шаги будут полезны 😊
Привет, @ lauren-mills, не могли бы вы проверить, верен ли этот подход? 😁
Спасибо, @dfavretto попробует посмотреть, работает ли это.
Привет @dfavretto. Я пробовал вышеуказанное решение, но оно не сработало. Я все еще вижу, что в классе CustomSkillAdapter нет обновлений или изменений кода.
@ Edwardfelix08 Не могли бы вы рассказать нам , в чем
SkillContext
вашего виртуального помощника ?SkillManifest
необходимыми слотами ?SkillContext
?populateStateFromSemanticAction
в вашей Skill раскомментирована?Кроме того, что касается CustomSkillAdapter
, не было необходимости изменять этот класс для этого сценария.
Привет @dfavretto!
Ниже приведен используемый код
Удалось ли вам сохранить информацию в SkillContext в вашем виртуальном помощнике?
В.А. MainDialog.
const sk: SkillContext = await this.skillContextAccessor.get (dc.context, new SkillContext ());
const skillContext: SkillContext = Object.assign (новый SkillContext (), sk);
skillContext.setObj ('userState', userProfile);
ждать this.skillContextAccessor.set (dc.context, skillContext);
Обновлен ли ваш SkillManifest необходимыми слотами?
skill.json в VA
"слоты": [{
"name": "userState",
"тип": ["IUserState"]
}],
SkillManifest
"слоты": [{
"name": "userState",
"тип": ["IUserState"]
}],
Соответствует ли ключ слота ключу, используемому для сохранения информации в SkillContext?
код внутри populateStateFromSemanticAction
if (skillContext.ContainsKey ('userState')) {
......
......
}
Раскомментирован ли метод populateStateFromSemanticAction в вашем навыке?
да, я раскомментировал код метода populateStateFromSemanticAction внутри botSkill.
Какую версию фрейма бота мы должны использовать?
Мы используем следующие пакеты.
"botbuilder": "^4.5.3",
"botbuilder-ai": "^4.5.3",
"botbuilder-applicationinsights": "^4.5.3",
"botbuilder-azure": "^4.5.3",
"botbuilder-core": "^4.5.3",
"botbuilder-dialogs": "^4.5.3",
"botbuilder-skills": "^4.4.6",
"botbuilder-solutions": "^4.4.6",
"botframework-config": "^4.5.3",
"botframework-connector": "^4.5.3",
"botframework-schema": "^4.5.3",
@ Edwardfelix08 , я вижу, вы пытаетесь получить значение userState
из skillContext
в методе populateStateFromSemanticAction
. Я хотел бы отметить, что skillContext
вы заполнили в виртуальном помощнике , больше не те, что у вас есть в вашем навыке .
Для использования этой ситуации данные из skillContext
виртуального помощника копируются в semanticAction
. Действие - единственный элемент, отправленный виртуальным помощником навыку , и затем его можно оценить для получения этой информации.
Вот пример populateStateFromSemanticAction
, который получит ваше значение userState
из semanticAction
действия Activity:
protected async populateStateFromSemanticAction(context: TurnContext): Promise<void> {
// Example of populating local state with data passed through semanticAction out of Activity
const activity: Activity = context.activity;
const semanticAction: SemanticAction | undefined = activity.semanticAction;
if (semanticAction !== undefined && Object.keys(semanticAction.entities).find((key: string) => key === "userState")) {
const userState: any = semanticAction.entities["userState"];
const userStateObj = userState.properties["userState"];
const state: SkillState = await this.stateAccessor.get(context, new SkillState());
state.userState = userStateObj !== undefined ? userStateObj : userState;
await this.stateAccessor.set(context, state);
}
}
@dfavretto извините за поздний ответ.
Я пробовал то же самое, но до сих пор не могу понять значение.
Значение для activity.semanticAction
не определено.
Привет, @ Edwardfelix08 , мы провели несколько SemanticAction
всегда имеет какое-то значение по умолчанию, поэтому оно не должно быть неопределенным.
Просто чтобы подтвердить, в вашем виртуальном помощнике вы вызываете свой навык следующим образом?
@darrenj - стоит ли добавить команду поддержки, чтобы они могли подойти к этой проблеме с другой точки зрения? Поскольку похоже, что это не имеет ничего общего с самой реализацией TypeScript, а с конкретным сценарием, который здесь реализуется.
Привет @dfavretto!
Извините за поздний ответ. Нам удалось заставить это работать, благодаря вам. Мы имели в виду старую версию фреймворка после обновления и перекрестной проверки с вашим кодом, и было различие в "populateStateFromSemanticAction", обновили код до предложенного, и он начал работать как шарм.
Спасибо, что помогли нам в этом.
Приятно это слышать! Рад, что смог помочь тебе с этим 😊
Самый полезный комментарий
Приятно это слышать! Рад, что смог помочь тебе с этим 😊