api.ai用不同的input循环相同的意图

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

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

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); } } 

如果我正确地理解你所要达到的目标,那么不要陷入困境,让我为你提供一个简单的解决scheme。

用户可以select3只宠物,狗,猫和兔子。 并被要求以不同的名称。 你想用一个意图来实现它,比如说pet_name。 行动的名称pet.name。

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

现在启用满意的意图,并获得您的networking钩子的所有参数。 现在,您可以直接在输出文本中使用它们。 比如:outputtext = $ dog_name。“对你的小狗来说是个好名字,告诉我更多”。 (只有当action ==“pet.name”时才能激活它)。

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

这意味着你不能把循环中的ask()函数放到一个局部variables中,因为每个答案都会作为一个新的事件返回给你(比如,每次都有一个新的webhook调用)。

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

  1. 一个意图(在我的屏幕截图中的name.init),用于首先调用带有动作name.entry的webhook并触发循环。
  2. 一个意图(我的屏幕截图中的name_loop )在name_loop上下文处于活动状态时响应,以获取名称并使用相同的操作name.entry将其发送到webhook。
  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!` ); } };