2017-08-14 109 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