執行要求會定義動作的對話介面,以取得使用者輸入內容和處理輸入內容的邏輯,藉此完成動作。
定義對話
現在您已定義動作,可以為這些動作建構對應的對話。要達到這個目的,您可以建立 Dialogflow 意圖來定義文法或使用者需要說的內容,藉此觸發意圖,並在觸發意圖時處理相應的執行要求。
您可以建立任意數量的意圖,用來定義整個對話的文法。
建立意圖
在 Dialogflow 左側導覽面板中,按一下「Intents」(意圖)+ 選單項目旁的「+」+符號。畫面上會顯示意圖編輯器,您可以在其中輸入下列資訊:
- 「意圖名稱」是意圖在 IDE 中顯示的名稱。
- 「情境」可讓您將意圖觸發範圍的範圍縮小至特定情況。詳情請參閱有關背景資訊的 Dialogflow 說明文件。
- 「事件」會觸發意圖,而使用者無需採取任何動作。其中一個範例事件是
GOOGLE_ASSISTANT_WELCOME
事件,可讓 Google 助理叫用您的動作。這個事件會用於動作的預設動作。如要進一步瞭解內建輔助意圖,請參閱說明文件。 - 訓練詞組會定義使用者需要說的內容 (文法) 才能觸發意圖。請在這裡輸入幾個詞組 (5 至 10),說明使用者可說哪些內容來觸發意圖。Dialogflow 會自動處理您提供的範例詞組的自然變化形式。
如果這個意圖啟用了執行要求,「動作和參數」會定義要傳送至執行要求的資料。包括剖析使用者輸入內容中的資料,以及在執行要求中使用的名稱,以偵測觸發的意圖。您稍後會使用這個名稱,將意圖對應到對應的執行要求邏輯。如要進一步瞭解如何定義動作,請參閱 Dialogflow 說明文件中的動作和參數。
回應是 Dialogflow 回應建構工具,您可以在 Dialogflow 中直接定義這個意圖的回應,而不必呼叫執行要求。此功能對於不需要執行要求的靜態回應非常實用。這可以提供簡單的歡迎訊息或道別訊息。然而,您可能會使用執行要求來回應使用者大多數的意圖。
「Fulfillment」(執行要求) 可讓您指定是否在觸發此意圖時呼叫執行要求。您很可能會針對 Dialogflow 代理程式中的大多數意圖啟用這項功能。如要在意圖中查看這個項目,您必須先在「Fulfillment」選單中為代理程式啟用執行要求。
在 Dialogflow 中建構回覆
在某些意圖中,您可能不需要讓執行要求傳回回應。在這種情況下,您可以在 Dialogflow 中使用回應建構工具來建立回應。
在「Responses」區域中,提供您要傳回給使用者的文字回應。預設文字回應是簡單的 TTS 文字回應,可用於多項 Dialogflow 整合。請參閱「回應」頁面,瞭解 Google 助理的回應。
建築物執行要求回應
您的執行要求程式碼會託管於該動作的 Webhook 執行要求邏輯。例如,在 Silly Name Maker 範例中,您可以在 Cloud Function for Firebase 的 index.js
中找到這個邏輯。
使用執行要求觸發的意圖時,您會收到來自 Dialogflow 的要求,當中包含意圖相關資訊。接著,您可以處理意圖並傳回回應,藉此回應要求。這項要求和回應是由 Dialogflow Webhook 定義,
強烈建議您使用 Node.js 用戶端程式庫來處理要求及傳回回應。以下為使用用戶端程式庫的一般程序:
- 初始化 Dialogflow 物件。這個物件會自動處理並剖析要求,方便您在執行要求中處理。
- 建立函式來處理要求。 這些函式會處理使用者輸入內容和其他意圖元件,並建立回應以傳回 Dialogflow。
初始化 Dialogflow
物件
以下程式碼會執行個體化 Dialogflow
,並對 Google Cloud Functions 執行部分樣板 Node.js 設定:
'use strict'; const {dialogflow} = require('actions-on-google'); const functions = require('firebase-functions'); const app = dialogflow({debug: true}); app.intent('Default Welcome Intent', (conv) => { // Do things }); exports.yourAction = functions.https.onRequest(app);
public class DfFulfillment extends DialogflowApp { private static final Logger LOGGER = LoggerFactory.getLogger(DfFulfillment.class); @ForIntent("Default Welcome Intent") public ActionResponse welcome(ActionRequest request) { // Do things // ... }
建立函式來處理要求
當使用者說出會觸發意圖的詞組時,您就會收到 Dialogflow 發出的要求,這類要求會使用執行要求中的函式處理。在這個函式中,您通常會執行以下操作:
- 執行任何處理使用者輸入內容所需的邏輯。
- 建構回應來回應觸發的意圖。請將使用者用來建構適當回應的介面納入考量。如要進一步瞭解如何為不同介面提供回應,請參閱「介面功能」。
- 使用回應呼叫
ask()
函式。
以下程式碼示範如何建構兩個用於處理叫用意圖 (input.welcome
) 的 TTS 回應,以及歡迎使用者執行動作的對話方塊意圖 (input.number
),並回響使用者對 Dialogflow 意圖說出的一個數字:
const app = dialogflow(); app.intent('Default Welcome Intent', (conv) => { conv.ask('Welcome to number echo! Say a number.'); }); app.intent('Input Number', (conv, {num}) => { // extract the num parameter as a local string variable conv.close(`You said ${num}`); });
@ForIntent("Default Welcome Intent") public ActionResponse defaultWelcome(ActionRequest request) { ResponseBuilder rb = getResponseBuilder(request); rb.add("Welcome to number echo! Say a number."); return rb.build(); } @ForIntent("Input Number") public ActionResponse inputNumber(ActionRequest request) { ResponseBuilder rb = getResponseBuilder(request); Integer number = (Integer) request.getParameter("num"); rb.add("You said " + number.toString()); return rb.endConversation().build(); }
與上述程式碼一同的自訂意圖 Input Number 會使用 @sys.number
實體,從使用者話語中擷取數字。接著,意圖會將 num
參數 (內含使用者提供的數字) 傳送至執行要求中的函式。
您也可以新增備用函式,而非為每個意圖設定個別處理常式。在備用函式中,檢查哪個意圖觸發了此函式,並據此採取適當行動。
const WELCOME_INTENT = 'Default Welcome Intent'; const NUMBER_INTENT = 'Input Number'; const NUMBER_PARAMETER = 'num'; // you can add a fallback function instead of a function for individual intents app.fallback((conv) => { // intent contains the name of the intent // you defined in the Intents area of Dialogflow const intent = conv.intent; switch (intent) { case WELCOME_INTENT: conv.ask('Welcome! Say a number.'); break; case NUMBER_INTENT: const num = conv.parameters[NUMBER_PARAMETER]; conv.close(`You said ${num}`); break; } });
// you can add a fallback function instead of a function for individual intents @ForIntent("Default Fallback Intent") public ActionResponse fallback(ActionRequest request) { final String WELCOME_INTENT = "Default Welcome Intent"; final String NUMBER_INTENT = "Input Number"; final String NUMBER_ARGUMENT = "num"; // intent contains the name of the intent // you defined in the Intents area of Dialogflow ResponseBuilder rb = getResponseBuilder(request); String intent = request.getIntent(); switch (intent) { case WELCOME_INTENT: rb.add("Welcome! Say a number."); break; case NUMBER_INTENT: Integer num = (Integer) request.getParameter(NUMBER_ARGUMENT); rb.add("You said " + num).endConversation(); break; } return rb.build(); }
未比對重複的提示
如果 Dialogflow 無法比對意圖訓練詞組中定義的任何輸入文法,就會觸發備用意圖。備用意圖通常會再次提示使用者為動作提供必要的輸入內容。如要提供自動提示詞組,請在備用意圖的「Response」區域中指定這些詞組,也可以使用 Webhook 提供回應。
如果使用者的回應與動作的訓練詞組不符,Google 助理會嘗試處理輸入內容。這個行為可協助使用者在對話中變更動作。例如,有位使用者詢問「本週上映哪些電影?」,然後在對話期間變更情境:「明天天氣如何?」在這個例子中,由於「明天天氣如何?」對於初始提示觸發的對話並非有效的回應,因此 Google 助理會自動嘗試處理相符項目,並將使用者移至適當的對話。
如果 Google 助理找不到與使用者輸入內容相符的適當動作,使用者就會返回動作的情境。
由於 Google 助理可能會中斷您的動作以回應有效的不相符情境,因此請勿使用備用意圖來完成使用者查詢。您應只使用備用意圖,重新提示使用者輸入有效的輸入內容。
如要建立備用意圖,請按照下列指示操作:
- 在 Dialogflow 的導覽選單中按一下「Intents」。
- 按一下「Create Intent」(建立意圖) 旁的 ⋮,然後選取「Create Fallback Intent」(建立備用意圖)。(您也可以按一下 [Default Fallback Intent] (預設備用意圖) 來編輯)。
指定要提示的詞組,回覆使用者。這些詞組應為對話式,並盡可能對使用者目前背景資訊有用。
如要在沒有執行要求的情況下執行這項操作:請在意圖的「Response」區域中指定詞組。Dialogflow 會隨機從這份清單中選擇詞組來向使用者說話,直到觸發更具體的意圖為止。
如何透過執行要求執行這項操作:
- 在意圖的「Fulfillment」區段,切換「Enable Webhookcall for this intent」(針對這個意圖啟用 Webhook 呼叫)。
- 請在執行要求邏輯中,按照「建立處理要求的函式」一節所述的方式處理備用意圖。
舉例來說,下列函式會使用 Node.js 用戶端程式庫的
conv.data
物件 (可用來維護狀態的任意資料酬載),儲存計數器,追蹤備用意圖的觸發次數。如果動作多次觸發,動作就會退出。儘管程式碼並未顯示,但應在觸發非備用意圖時,讓其他意圖將此計數器重設為 0。(如要進一步瞭解如何實作此範例,請參閱「數字 Genie 範例」)。Node.js app.intent('Default Fallback Intent', (conv) => { conv.data.fallbackCount++; // Provide two prompts before ending game if (conv.data.fallbackCount === 1) { conv.contexts.set(DONE_YES_NO_CONTEXT, 5); conv.ask('Are you done playing Number Genie?'); } else { conv.close(`Since I'm still having trouble, so I'll stop here. ` + `Let's play again soon.`); } });
Java @ForIntent("Default Fallback Intent") public ActionResponse defaultFallback(ActionRequest request) { final String DONE_YES_NO_CONTEXT = "done_yes_no_context"; ResponseBuilder rb = getResponseBuilder(request); int fallbackCount = request.getConversationData().get("fallbackCount") == null ? 0 : (Integer) request.getConversationData().get("fallbackCount"); fallbackCount++; request.getConversationData().put("fallbackCount", fallbackCount); if (fallbackCount == 1) { rb.add(new ActionContext(DONE_YES_NO_CONTEXT, 5)); rb.add("Are you done playing Number Genie?"); } else { rb.add("Since I'm still having trouble, so I'll stop here. Let's play again soon") .endConversation(); } return rb.build(); }
使用背景資訊
如果您想讓 Dialogflow 只在特定情況下觸發備用意圖,請使用結構定義。如果您想為不同的不相符情境設定不同的備用意圖,這個方法就十分實用。
- 如果您未針對備用意圖設定背景資訊,系統會將此動作視為全域備用意圖,在沒有相符的其他意圖時觸發。如果你選擇使用其中一個變數,只能擇一使用。
如果您為備用意圖設定輸入背景資訊,Dialogflow 會在以下情況觸發這個備用意圖:
- 使用者的目前背景資訊是意圖中定義的背景資訊超集。
- 沒有其他相符的意圖。
如此一來,您就能使用不同輸入情境的多個備用意圖,自訂要與特定情境不相符的重新比對。
如果您對備用意圖設定輸出背景資訊,系統在觸發及處理備用意圖後,就能將使用者留在相同的情境中。
詳情請參閱「Dialogflow 情境」一文。
無輸入重新提示
如要進一步瞭解當使用者未在 Google Home 等需要持續互動的語音裝置上提供進一步輸入內容時,應如何處理。請參閱拒絕提示頁面。