【问题标题】:Sending an IForm from a LUIS intent从 LUIS 意图发送 IForm
【发布时间】:2026-02-12 01:45:02
【问题描述】:

我目前有一个在 Visual Studio 中运行的聊天机器人,它使用 Microsoft 的 C# 机器人框架。 我将 LUIS 集成到机器人中,我想知道如何才能使类似于 this 示例的 FormFlow 出现在特定意图上。

到目前为止,这是我的表单的代码:

internal static IDialog<InfoGroup> MakeRootDialog()
    {
        return Chain.From(() => FormDialog.FromForm(InfoGroup.BuildForm));
    }
public enum GroupOptions
{
    A, B, C, D, E, F, G, H
};
[Serializable]
public class InfoGroup
{
    public GroupOptions? groupId;

    public static IForm<InfoGroup> BuildForm()
    {
        return new FormBuilder<InfoGroup>()
                .Message("Please select an option")
                .Build();
    }
};

我正在尝试通过我的 LUIS 意图方法发送它,如下所示:

[LuisIntent("SpecificGroup")]
    public async Task SpecificGroupIntent(IDialogContext context, IAwaitable<IMessageActivity> activity, LuisResult result)
    {
        await context.PostAsync(FormDialog.FromForm(InfoGroup.BuildForm));
        context.Wait(MessageReceived);
        return;
    }

这显然不是调用表单的正确方法,我怎样才能使表单显示为直接从我的 SpecificGroupIntent() 方法调用的响应? 任何帮助将不胜感激。 填写表格后,我想使用用户选择的选项来相应地显示文本。

【问题讨论】:

    标签: botframework azure-language-understanding formflow


    【解决方案1】:

    您可以从 luis 意图方法调用表单流构建器,例如使用 context.Call() 方法从父对话框调用对话框。您还需要指定填写表单后将执行的方法。

    例如: 通过创建 InfoGroup(Your form) 类型的 FormDialog 并指定要在它之后执行的方法来调用 formbuilder。

    InfoGroup form = new InfoGroup();    
    FormDialog<InfoGroup> InfoGroupform = new FormDialog<InfoGroup>(form, InfoGroup.BuildForm, FormOptions.PromptInStart);
    context.Call(InfoGroupform, InfoGroupFormSubmitted);
    

    InfoGroupFormSubmitted 是填写表单后将调用的方法。你需要这个,因为如果你使用 context.Call() 方法,你需要为它指定一个 resumeAfter 方法。在这个 InfoGroupFormSubmitted 方法中,您可以确认表单是否正确填写或用户退出,您可以捕获异常并显示用户退出的位置。

    public static async Task InfoGroupFormSubmitted(IDialogContext context, IAwaitable<InfoGroup> result)
    {
            try
            {
                 var query = await result;
                 context.PostAsync("Your choice has been recorded.");
            } 
            catch (FormCanceledException<InfoGroup> e)
            {
                  string reply;
                  if (e.InnerException == null)
                  {
                        reply = $"You quit on {e.Last}--maybe you can finish next time!";
                  }
                  else
                  {
                        reply = $"Sorry, I've had a short circuit.  Please try again.";
                  }
                  context.Done(true);
                  await context.PostAsync(reply);
            }
    }
    

    【讨论】:

    • 非常感谢,这是非常完整的答案,唯一的问题是在尝试此操作后,我在输入 LUIS 意图时收到此错误,有什么建议吗?
    • 抛出异常:Microsoft.Bot.Builder.dll 中的“Microsoft.Bot.Builder.Internals.Fibers.InvalidNeedException”抛出异常:mscorlib 中的“Microsoft.Bot.Builder.Internals.Fibers.InvalidNeedException” .dll 抛出异常:mscorlib.dll 中的“Microsoft.Bot.Builder.Internals.Fibers.InvalidNeedException”
    • 糟糕,我有一个上下文。Wait(MessageReceived);在我的表单调用是多余的并且导致错误之后,感谢您的回答它完美地工作!!!
    • 乐于助人:D