重复的 ChoicePrompt 清除 UserState

Repeated ChoicePrompt clears UserState

我使用 Microsoft BotFramework 实现了一个机器人。为了收集用户数据,我使用了 ChoicePrompts。当用户没有选择建议的选项之一时,ChoicePrompt 会重复,直到用户输入有效选项(这是提示方法的默认行为)。

不幸的是,在没有选择一个有效的选项后,用户状态被刷新。这意味着在那之前我会丢失所有收集的用户数据。

这种行为是故意的还是有办法阻止这种行为?

您提供的 link 上的代码存在一些问题。由于我看不到你的完整代码,所以我猜测了一些部分。

  1. 仔细检查 userState 和 userData 是否设置正确。我的构造函数如下所示:
const DIALOG_STATE_PROPERTY = 'dialogState';
const USER_PROFILE_PROPERTY = 'user';

const EDUCATION_PROMPT = 'education_prompt';
const MAJOR_PROMPT = 'major_prompt';

constructor(conversationState, userState) {
    this.conversationState = conversationState;
    this.userState = userState;

    this.dialogState = this.conversationState.createProperty(DIALOG_STATE_PROPERTY);
    this.userData = this.userState.createProperty(USER_PROFILE_PROPERTY);

    this.dialogs = new DialogSet(this.dialogState);

    // Add prompts that will be used by the main dialogs.
    this.dialogs
        .add(new TextPrompt(NAME_PROMPT))
        .add(new TextPrompt(AGE_PROMPT))
        .add(new TextPrompt(GENDER_PROMPT))
        .add(new ChoicePrompt(EDUCATION_PROMPT))
        .add(new ChoicePrompt(MAJOR_PROMPT));

    // Create dialog for prompting user for profile data
    this.dialogs.add(new WaterfallDialog(START_DIALOG, [
        this.promptForName.bind(this),
        this.promptForAge.bind(this),
        this.promptForGender.bind(this),
        this.promptForEducation.bind(this),
        this.promptForMajor.bind(this),
        this.returnUser.bind(this)
    ]));

    this.majors = ['English', 'History', 'Computer Science'];
}
  1. 记住 TextPrompt returns 中的值 step.result。 ChoicePrompt returns 值为 step.result.value

    我假设在您将性别值分配给用户的“promptForEducation”步骤中,该值来自选择提示。否则,您将失去价值。仔细检查您是否指定了正确的来源。

.add(new TextPrompt(GENDER_PROMPT))
.add(new ChoicePrompt(EDUCATION_PROMPT))

...

if (!user.gender) {
    user.gender = step.result;
    // Give user object back to UserState storage
    await this.userData.set(step.context, user);
    console.log(user);
}
  1. 在“promptForMajor”步骤中,step.Prompt 中的第二个参数采用一个字符串并表示选择的对话部分。您的代码应如下所示并将产生以下输出。在本例中,我在构造函数(如上所示)中为“this.majors”赋值。
this.majors = ['English', 'History', 'Computer Science'];

...

if (!user.major) {
    // Copy List of majors and add "Other" entry
    let majorsOther = this.majors.slice(0, this.majors.length);
    majorsOther.push('Einen anderen Studiengang');
    // return await step.prompt(MAJOR_PROMPT, this.userData.major, majorsOther);
    return await step.prompt(MAJOR_PROMPT, 'List of majors:', majorsOther);
}

  1. 检查您是否在“onTurn”结束时保存状态。
// Save changes to the user state.
await this.userState.saveChanges(turnContext);

// End this turn by saving changes to the conversation state.
await this.conversationState.saveChanges(turnContext);

如果你实现了以上,你应该设置好了。我能够 运行 没有任何问题,也没有丢失状态。此外,在最终提供正确响应之前反复不回答 ChoicePrompt 并没有中断状态。

希望得到帮助!