BotFramework从提示验证程序传递结果

问题描述 投票:0回答:1

我正在将botframework的python sdk用于我的机器人设计。我在对话设计中使用的是瀑布式对话框。

我的机器人首先通过询问用户对话框:"I can show documents for topic A, B, C. Of what topic you would like to see documents?"要验证用户是否提交了正确的主题,我使用自定义验证程序,并使用luis验证用户是否输入了正确的主题。

在对话框的瀑布步骤中,我使用用户输入的主题向他显示相应的主题。但是在这里,我还必须再次点击luis服务,以从用户消息中提取主题,然后从主题列表中使用该实体过滤器。

我的问题是:是否可以将值从hintValidatorContext传递到当前步骤上下文或瀑布对话框集中的下一个对话框。

您可以通过以下示例代码看到,我正在用相同的用户消息两次访问luis应用程序,如果可以在hintValidatorContext和dialogContext之间共享值,这将有助于我避免两次访问luis服务并且可以执行相同操作一次击中工作。

示例代码:

class MainDialog(ComponentDialog):
    def __init__(self, dialog_id, luis_app):
        self.dialog_id = dialog_id
        self.luis_app = luis_app
        self.add_dialog(TextPrompt('topic', self.TopicValidator))
        self.add_dialog(WaterFallDialog('wf_dialog', [self.Welcome, self.Topic, self.FinalStep])

    async def Welcome(self, step_context):
        return await step_context.prompt(
        'topic', 
        options = PromptOptions(
            prompt = MessageFactory.text('Welcome to the bot, I can show you documents of topic Math, English, Science'), 
            retry_prompt = MessageFactory.text("I am sorry I didn't understand please try again with different wording")
            )
        )

    async def TopicValidator(self, prompt_context: PromptValidatorContext):
        for_luis = prompt_context.recognized.value

        #hit the luis app to get the topic name
        topic_name = self.luis_app(for_luis)

        if topic_name in ['Math', 'Science', 'English']:
            return True
        else:
            return False

    async def Topic(self, step_context):
        topic_name = self.luis_app(step_context.context.activity.text) #using the same user message as used in Validator function 

        #filter documents based on topics with custom function filter_doc
        docs = filter_doc(topic_name) 

        return await step_context.prompt('docs', options = PromptOptions(prompt = docs))

    async def FinalStep(self, step_context):
        #code for final step
python botframework luis
1个回答
0
投票

我真的很想重申,我认为您应该使用选择提示。选择提示比您想象的要灵活得多。选择识别确实非常先进,它能够识别短语中间的选择,甚至可以像在LUIS列表实体中一样提供同义词。对话框库中有一个entire folder,专门用于选择识别。您以为使用LUIS给用户带来了更好的体验,但实际上却给他们带来了更糟糕的体验,因为他们不能输入像1或2这样的序数作为选择。根据您告诉我的内容,我确定选择提示是您的最佳选择。

话虽如此,这是您要求的信息。

通常,每回合仅调用任何给定的LUIS端点一次。如果您的机器人的LUIS模型是全局的,那么在该对话框之外调用它会更有意义,因此,我假定此LUIS模型特定于此对话框。

最明显的解决方案是将LUIS结果存储在转弯状态。您可以这样存储它:

prompt_context.context.turn_state[MY_KEY] = self.luis_app(for_luis);

您可以像这样检索值:

topic_name = step_context.context.turn_state[MY_KEY];

另一个想法是将luis_app设为memoized function(一个缓存其自身结果的函数)。由于其缓存的最佳位置是转弯状态,因此与第一个想法没有太大不同。主要区别在于您将更改luis_app代码,并保持对话框代码不变。

另一个想法是将您的LUIS结果放入提示结果中。您可以根据需要在验证器中自由修改识别的值。

prompt_context.recognized.value = self.luis_app(prompt_context.recognized.value);

在瀑布的下一步中使用step_context.result访问该值。我应该提到,您还可以修改传入活动的text属性,但是这可能被认为是不好的做法。

最后,您可以创建自己的提示类,该提示类自动使用LUIS实体作为其识别值。也许您可以称它为EntityPrompt之类的东西。

© www.soinside.com 2019 - 2024. All rights reserved.