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

时间:2017-08-14 18:28:27

标签: node.js dialogflow actions-on-google google-assist-api

我正在使用API​​.AI来实现助手应用程序,但现在我发现很难循环收集不同用户输入的相同意图(如果我的表达错误,请纠正我,将详细说明) 。)问题是,我有一个元素列表,每次我想将一个元素分配给一个人(通过使用输入Assistant.getArgument()收集),但是,我希望它每次都像用户说话一样'您想将元素X分配给谁?' (X指的是列表中元素的名称)。我当前的实现是,创建一个单独的函数,让它提出问题然后使用while循环在另一个函数中进行收集输入/赋值,在while调用ask函数的末尾,但它没有作为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);
        }
    }

2 个答案:

答案 0 :(得分:2)

问题是,Assistant的编程是一个事件驱动的系统(每个Intent都是一个事件),您可以使用assistant.ask()assistant.tell()结束服务器上事件的处理。这会将您的回复发送回用户。然后,ask()将等待另一个事件,而tell()表示对话已结束。

这意味着您无法将ask()放入循环中,并且无法将结果存储在本地变量中,因为每个答案都将作为新事件返回给您(即 - 每次都对您的webhook进行新的调用。)

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

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

答案 1 :(得分:1)

如果我没有弄清楚并发症,如果我正确理解你想要实现的目标,请让我为你提供一个简单的解决方案。

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

解决方案非常简单。在那些意图中创建3个参数(并通过选中框,使所有这些参数和#34;必需&#34;)。 3个参数是dog_name,cat_name,rabbit_name。

现在启用该意图的实现,并获取Web挂钩中的所有参数。现在您可以直接在输出文本中使用它们。喜欢:outputtext = $ dog_name。&#34;是你的小狗的一个伟大的名字。告诉我更多&#34 ;; (只有当action ==&#34; pet.name&#34;)时才能激活它。