botframework - 如何维护调度机器人和技能机器人之间的状态?
问题描述
我正在使用通过 Microsoft 的botframework-solutions
Github 存储库提供的虚拟助手模板,并且在维护我们的主要入口点之间的活动对话时遇到了麻烦——开发的机器人实现了调度模型以确定发送用户话语以进行进一步处理的技能—— - 个人技能处理用户的输入。
我让我们的调度模型机器人收听localhost:3979/api/messages
使用route
方法 inmainDialog.ts
确定将用户话语传递给的相关技能的 POST,该技能采用该话语并确定应该使用技能中的哪个对话来处理用户的话语。当我们开始一个实现多步骤瀑布对话的对话时,调度模型机器人不会跟踪技能机器人中活动的对话,因此技能机器人不知道如何将用户的话语路由到已经激活的对话框。当我们直接发布到技能机器人并在调度模型机器人之前,技能机器人能够跟踪活动对话,这让我相信我们没有正确管理调度机器人和技能机器人之间的状态.
我注意到我们从模板中使用的 bot 虚拟助手和技能模板botframework-solutions
实例化了AutoSaveStateMiddleWare
它们的新实例defaultAdapter.ts
,因此看来对话和用户状态的读取和写入应该已经被自动管理。
调度机器人中的 mainDialog.ts,它将话语路由到适当的技能
protected async route(dc: DialogContext): Promise<void> {
// Get cognitive models for locale
const locale: string = i18next.language.substring(0, 2);
const cognitiveModels: ICognitiveModelSet | undefined = this.services.cognitiveModelSets.get(locale);
if (cognitiveModels === undefined) {
throw new Error('There is no value in cognitiveModels');
}
// Check dispatch result
const dispatchResult: RecognizerResult = await cognitiveModels.dispatchService.recognize(dc.context);
const intent: string = LuisRecognizer.topIntent(dispatchResult);
if (this.settings.skills === undefined) {
throw new Error('There is no skills in settings value');
}
// Identify if the dispatch intent matches any Action within a Skill if so, we pass to the appropriate SkillDialog to hand-off
const identifiedSkill: ISkillManifest | undefined = SkillRouter.isSkill(this.settings.skills, intent);
if (identifiedSkill !== undefined) {
// We have identified a skill so initialize the skill connection with the target skill
await dc.beginDialog(identifiedSkill.id);
// Pass the activity we have
const result: DialogTurnResult = await dc.continueDialog();
if (result.status === DialogTurnStatus.complete) {
await this.complete(dc);
}
} else if (intent === 'l_NOVA_general') {
// If dispatch result is general luis model
const luisService: LuisRecognizerTelemetryClient | undefined = cognitiveModels.luisServices.get(this.luisServiceGeneral);
if (luisService === undefined) {
throw new Error('The specified LUIS Model could not be found in your Bot Services configuration.');
} else {
const result: RecognizerResult = await luisService.recognize(dc.context);
if (result !== undefined) {
const generalIntent: string = LuisRecognizer.topIntent(result);
// switch on general intents
switch (generalIntent) {
case 'Escalate': {
// start escalate dialog
await dc.beginDialog(EscalateDialog.name);
break;
}
case 'None':
default: {
// No intent was identified, send confused message
await this.responder.replyWith(dc.context, MainResponses.responseIds.confused);
}
}
}
}
} else {
// If dispatch intent does not map to configured models, send 'confused' response.
await this.responder.replyWith(dc.context, MainResponses.responseIds.confused);
}
}
以下来自技能机器人的代码,dialogBot.ts
它监听所有turn
事件
public async turn(turnContext: TurnContext, next: () => Promise<void>): Promise<any> {
// Client notifying this bot took to long to respond (timed out)
if (turnContext.activity.code === EndOfConversationCodes.BotTimedOut) {
this.telemetryClient.trackTrace({
message: `Timeout in ${ turnContext.activity.channelId } channel: Bot took too long to respond`,
severityLevel: Severity.Information
});
return;
}
const dc: DialogContext = await this.dialogs.createContext(turnContext);
if (dc.activeDialog !== undefined) {
const result: DialogTurnResult = await dc.continueDialog();
} else {
await dc.beginDialog(this.rootDialogId);
}
await next();
}
mainDialog.ts
路由到claims_claimsStatus
瀑布对话框的技能机器人内
protected async route(dc: DialogContext): Promise<void> {
// get current activity locale
const locale: string = i18next.language.substring(0, 2);
const localeConfig: Partial<ICognitiveModelSet> | undefined = this.services.cognitiveModelSets.get(locale);
// Populate state from SkillContext slots as required
await this.populateStateFromSkillContext(dc.context);
if (localeConfig === undefined) {
throw new Error('There is no cognitiveModels for the locale');
}
// Get skill LUIS model from configuration
if (localeConfig.luisServices !== undefined) {
const luisService: LuisRecognizerTelemetryClient | undefined = localeConfig.luisServices.get(this.solutionName);
if (luisService === undefined) {
throw new Error('The specified LUIS Model could not be found in your Bot Services configuration.');
} else {
let turnResult: DialogTurnResult = Dialog.EndOfTurn;
const result: RecognizerResult = await luisService.recognize(dc.context);
const intent: string = LuisRecognizer.topIntent(result);
switch (intent) {
case 'claims_claimStatus': {
turnResult = await dc.beginDialog(StatusDialog.name);
break;
}
.
.
.
预期结果:当使用调度机器人路由到技能机器人时,在对话中开始瀑布对话后claims_claimStatus
,dialogContext.activeDialog
应该是statusDialog
瀑布对话的进一步步骤
实际结果:当使用调度机器人路由到技能机器人时,在对话中开始瀑布对话后claims_claimStatus
,dialogContext.activeDialog
应该是undefined
瀑布对话的进一步步骤
解决方案
推荐阅读
- huggingface-transformers - 如何更改拥抱脸转换器的默认缓存目录
- docker - Docker 桌面 - kubernetes 无法启动
- javascript - 如何通过单键启动和停止计数器
- excel - 更改引用库的位置
- flutter - Flutter Android 更改隐藏状态栏颜色
- c# - Asp.Net Core + GraphQL -> Schema 没有出现
- c# - 将 IMongoCollection 转换为 ObservableCollection
- r - \parskip 和 tikzDevice 之间的交互影响 .Rnw 中的绘图边距
- flutter - 全新 Flutter 和 Dart 安装时的构建错误(导入错误)
- python - uasyncio 并行(多)线程似乎不起作用