2017-08-14 36 views
1

我正在使用API​​.AI来实现助手应用程序,但现在我发现很难循环使用相同的意图来收集不同的用户输入(如果我的表达错误,请纠正我的错误)将会详细解释它。)问题是,我有一个元素列表,每次我想为一个人分配一个确切的元素(通过使用输入Assistant.getArgument()收集),但是,我希望它说话给用户每次像'你想分配元素X到谁?' (X是指列表中元素的名称)。我目前的实现是,创建一个单独的函数,让它提出问题,然后在while循环结束时使用while循环在另一个函数中执行collect input/assignment,在body调用ask函数的末尾,但它不起作用API.AI在响应中不可用。任何想法如何做到这一点?让我知道,如果有什么不清楚。api.ai循环使用不同输入的相同意图

这里只是一个简短的代码片段,用于显示问题是什么&我想实现的。我想让它在API.AI中要求4次,获取用户输入,并将它们全部存储到输出字符串中。

var output = ''; 

    function do_sth(assistant){ 
     let get_name_input = assistant.getArgument('name'); 
     output = output + get_name_input + '.'; 
    } 

    function test_repeat(assistant){ 
     for(let i = 0; i < 4; i++){ 
      assistant.ask('What is the name?'); 
      do_sth(assistant); 
     } 
    } 
+0

你可以发布不工作的代码和你的api.ai意图的任何屏幕截图吗? – Prisoner

+0

这听起来像你正试图从用户收集一些不同的值?您可能想查看我们的个人厨师视频,该视频展示了如何从同一意图收集后续问题的信息:https://youtu.be/9SUAuy9OJg4 –

+0

@Prisoner posted。 –

回答

0

的问题是,编程助手是事件驱动的系统(各意图是一个事件),并且结束该服务器上的事件的处理与assistant.ask()assistant.tell()。这会将您的回复发回给用户。然后ask()将等待另一个事件,而tell()指示对话结束。

这意味着你不能把ask()放在一个循环中,你不能把结果存储在一个局部变量中,因为每个答案都会作为一个新事件返回给你(比如 - 每次都有一个新的webhook调用)。

这是一种方法。它由三个部分组成:

  1. 的意图(name.init在我的屏幕截图)用来先调用网络挂接与动作name.entry并触发循环。
  2. name_loop上下文处于活动状态以获取名称并将其以相同动作发送给webhook时,响应的意图(屏幕截图中的name.loop)name.entry
  3. 处理name.entry意图的代码片段。

name.init

name.loop

代码

var loopAction = function(assistant){ 
    const CONTEXT = 'name_loop'; 
    const PARAM = 'name'; 
    const VALUE = 'index'; 
    const NUM_NAMES = 4; 

    // Get the context, which contains the loop counter index, so we know 
    // which name we're getting and how many times we've been through the loop. 
    var index; 
    var context = assistant.getContext(CONTEXT); 

    if(!context){ 
    // If no context was set, then we are just starting the loop, so we 
    // need to initialize it. 
    index = 0; 

    } else { 
    // The context is set, so get the invex value from it 
    index = context.parameters[VALUE]; 

    // Since we are going through the loop, it means we were prompted for 
    // the name, so get the name. 
    var name = assistant.getArgument(PARAM); 

    // Save this all, somehow. 
    // We may want to put it back in a context, or save it in a database, 
    // or something else, but there are things to be aware of: 
    // - We can't save it in a local variable - they will go out of scope 
    // after we send the next reply. 
    // - We can't directly save it in a global variable - other users who 
    // call the Action will end up writing to the same place. 
    loopSave(index, name); 

    // Increment the counter to ask for the next name. 
    index++; 
    } 


    if(index < NUM_NAMES){ 
    // We don't have all the names yet, ask for the next one 

    // Build the outgoing context and store the new index value 
    var contextValues = {}; 
    contextValues[VALUE] = index; 

    // Save the context as part of what we send back to API.AI 
    assistant.setContext(CONTEXT, 5, contextValues); 

    // Ask for the name 
    assistant.ask(`Please give me name ${index}`); 

    } else { 
    // We have reached the end of the loop counter. 

    // Clear the context, making sure we don't continue through the loop 
    // (Not really needed in this case, since we're about to end the 
    // conversation, but useful in other cases, and a good practice.) 
    assistant.setContext(CONTEXT, 0); 

    // End the conversation 
    assistant.tell(`I got all ${index}, thanks!`); 
    } 
}; 
+0

嗨,囚犯,我有点理解你的观点,并尝试过自己,但它并没有很好地工作。我想我需要更多地了解这些:1.除了列出的步骤外,我应该如何设置api.ai中的上下文?具体来说,你指的是什么'name_index',它是一个输入上下文还是输出上下文? 2.当你做setContext时,你如何选择参数空间?对我来说,上下文就是你从getContext得到的,但不应该是一些intent参数吗?我不明白传递这个意思。如果可能,由于示例代码非常简单,您可以将解决方案发布到此吗? –

+0

我已经用屏幕截图和代码更新了我的答案,应该更清楚。 – Prisoner

1

没有进入并发症,让我为您提供一个简单的解决方案,如果我知道你正在努力实现正确的。

用户可以选择3种宠物,狗,猫和兔子。并被要求以不同的方式命名它们。你想用一个意图来实现它,比如说pet_name。操作pet.name的名称。

该解决方案非常简单。在这些意图中创建3个参数(并通过勾选框使其全部为“必需”)。 3个参数是dog_name,cat_name,rabbit_name。

现在启用该意图的履行,并获取您的Web钩子中的所有参数。现在,您可以直接在输出文本中使用它们。像:outputtext = $ dog_name。“是你的小狗的好名字,告诉我更多”; (只有在动作==“pet.name”时才能激活它)。

+0

dipayan谢谢你的答案!它有点不同。在这种情况下,参数没有设置,换句话说,api.ai不知道用户将输入什么名字,所以它是完全动态的。因此,每当我们的结束通过do_sth获得参数名称时,我想让它回到test_repeat意图。 –

+0

这实际上是一个很好的解决方案!但是确实需要您确切地知道您想要询问的预先确定的名称。如果您将参数名称更改为“name_1”,“name_2”,“name_3”等等,则它更接近您正在执行的操作。 – Prisoner

相关问题