設計故事
在設計故事時,需要考慮兩組對話互動:快樂路徑和不快樂路徑。快樂路徑描述使用者何時按照您的預期遵循對話流程,並在出現提示時始終提供必要的資訊。然而,使用者經常會因為問題、閒聊或其他問題而偏離愉快的道路。我們稱這些為不幸的道路。
對你的機器人來說,優雅地處理不愉快的路徑很重要,但也無法預測給定使用者可能採取的路徑。通常,開發人員在設計不愉快的路徑時會嘗試考慮所有可能的分歧路徑。為狀態機中的每個可能狀態(其中許多永遠不會達到)進行規劃需要大量額外工作並顯著增加訓練時間。
相反,我們建議 在設計不愉快的路徑時採用對話驅動的開發方法。對話驅動開發促進儘早與測試使用者共享您的機器人,並收集真實的對話資料,這些資料可以準確地告訴您使用者如何偏離快樂路徑。從這些資料中,您可以建立故事來完成使用者的請求,並開始思考如何引導他們回到快樂的道路上。
對於多回合互動,您應該定義一個故事,例如:
1 stories: 2 - story: Greeting and ask user how they're doing 3 steps: 4 - intent: greet 5 - action: utter_greet 6 - action: utter_ask_how_doing 7 - intent: doing_great 8 - action: utter_happy
管理對話流程
以下是管理故事中對話流程的一些技巧:
何時使用插槽來影響對話
插槽充當機器人的記憶體。定義槽時,您可以定義槽是否 應影響對話。屬性influence_conversation
設定為 的插槽false
只能儲存資訊。屬性influence_conversation
設定為 的插槽true
可以根據其中儲存的資訊影響對話流程。
需要將影響對話的插槽新增到您的故事或規則中。這也適用於插槽是由自定義操作設定的情況。例如,您可以使用由自定義操作設定的布林槽來根據其值使用以下故事控制對話流:
1 stories: 2 - story: Welcome message, premium user 3 steps: 4 - intent: greet 5 - action: action_check_profile 6 - slot_was_set: 7 - premium_account: true 8 - action: utter_welcome_premium 9 10 - story: Welcome message, basic user 11 steps: 12 - intent: greet 13 - action: action_check_profile 14 - slot_was_set: 15 - premium_account: false 16 - action: utter_welcome_basic 17 - action: utter_ask_upgrade
如果您不希望槽影響對話流,則應將槽的屬性設定influence_conversation
為false
。您不需要slot_was_set
在故事中包含不影響對話的插槽事件。
實現分支邏輯
在編寫故事時,有時下一個操作將取決於您的自定義操作之一中返回的值。在這些情況下,重要的是在返回插槽和直接使用自定義操作程式碼來影響機器人接下來的操作之間找到正確的平衡。
如果某個值僅用於確定機器人的響應,請考慮將決策邏輯嵌入自定義操作中,而不是在您的故事中使用特徵化槽。這有助於降低整體複雜性並使您的故事更易於管理。
例如,您可以轉換這些故事:
1 stories: 2 - story: It's raining now 3 steps: 4 - intent: check_for_rain 5 - action: action_check_for_rain 6 - slot_was_set: 7 - raining: true 8 - action: utter_is_raining 9 - action: utter_bring_umbrella 10 11 - story: It isn't raining now 12 steps: 13 - intent: check_for_rain 14 - action: action_check_for_rain 15 - slot_was_set: 16 - raining: false 17 - action: utter_not_raining 18 - action: utter_no_umbrella_needed
合成一個故事是:
1 stories: 2 - story: check for rain 3 steps: 4 - intent: check_for_rain 5 - action: action_check_for_rain
在actions檔案裡定義:
1 def run(self, dispatcher, tracker, domain): 2 is_raining = check_rain() 3 if is_raining: 4 dispatcher.utter_message(template="utter_is_raining") 5 dispatcher.utter_message(template="utter_bring_umbrella") 6 else: 7 dispatcher.utter_message(template="utter_not_raining") 8 dispatcher.utter_message(template="utter_no_umbrella_needed") 9 return []
如果該值用於影響前進的動作流,請返回一個特徵化槽來確定故事。例如,如果您想收集有關新使用者的資訊,但不收集回訪使用者的資訊,您的故事可能如下所示:
1 stories: 2 - story: greet new user 3 steps: 4 - intent: greet 5 - action: check_user_status 6 - slot_was_set: 7 - new_user: true 8 - action: utter_greet 9 - action: new_user_form 10 - active_loop: new_user_form 11 - active_loop: null 12 13 - story: greet returning user 14 steps: 15 - intent: greet 16 - action: check_user_status 17 - slot_was_set: 18 - new_user: false 19 - action: utter_greet 20 - action: utter_how_can_help
使用 OR 語句和檢查點
OR 語句和檢查點 可用於減少您必須編寫的故事數量。但是,應謹慎使用它們。過度使用 OR 語句或檢查點會減慢訓練速度,建立過多的檢查點會使您的故事難以理解。
OR 語句
在機器人以相同方式處理不同意圖的故事中,您可以使用 OR 語句作為建立新故事的替代方法。
例如,您可以合併這兩個故事:
1 stories: 2 - story: newsletter signup 3 steps: 4 - intent: signup_newsletter 5 - action: utter_ask_confirm_signup 6 - intent: affirm 7 - action: action_signup_newsletter 8 9 - story: newsletter signup, confirm via thanks 10 steps: 11 - intent: signup_newsletter 12 - action: utter_ask_confirm_signup 13 - intent: thanks 14 - action: action_signup_newsletter
用 OR 語句合併成一個故事:
1 stories: 2 - story: newsletter signup with OR 3 steps: 4 - intent: signup_newsletter 5 - action: utter_ask_confirm_signup 6 - or: 7 - intent: affirm 8 - intent: thanks 9 - action: action_signup_newsletter
檢查點
檢查點對於將您的故事模組化為經常重複的單獨塊很有用。例如,如果您希望您的機器人在每個對話流程結束時詢問使用者反饋,您可以使用檢查點來避免在每個故事結束時包含反饋互動:
1 stories: 2 - story: beginning of conversation 3 steps: 4 - intent: greet 5 - action: utter_greet 6 - intent: goodbye 7 - action: utter_goodbye 8 - checkpoint: ask_feedback 9 10 - story: user provides feedback 11 steps: 12 - checkpoint: ask_feedback 13 - action: utter_ask_feedback 14 - intent: inform 15 - action: utter_thank_you 16 - action: utter_anything_else 17 18 - story: user doesn't have feedback 19 steps: 20 - checkpoint: ask_feedback 21 - action: utter_ask_feedback 22 - intent: deny 23 - action: utter_no_problem 24 - action: utter_anything_else
檢查點旨在使在許多不同的故事中重用某些對話部分變得更容易。強烈建議不要在現有檢查點內使用檢查點,因為這會顯著增加訓練時間並使故事難以理解。
在故事中創造邏輯中斷
在設計對話流程時,通常很想建立長篇故事示例,以捕捉從頭到尾的完整對話互動。在許多情況下,這將增加解釋分支路徑所需的訓練故事的數量。相反,考慮將較長的故事分成處理子任務的較小對話塊。
處理丟失信用卡的快樂路徑故事可能如下所示:
stories: - story: Customer loses a credit card, reviews transactions, and gets a new card steps: - intent: card_lost - action: check_transactions - slot_was_set: - reviewed_transactions: ["starbucks"] - action: utter_ask_fraudulent_transactions - intent: inform - action: action_update_transactions - intent: affirm - action: utter_confirm_transaction_dispute - action: utter_replace_card - action: mailing_address_form - active_loop: mailing_address - active_loop: null - action: utter_sent_replacement - action: utter_anything_else - intent: affirm - action: utter_help
處理丟失的信用卡涉及一系列子任務,即檢查欺詐交易的消費歷史,確認更換卡的郵寄地址,然後跟進使用者的任何額外請求。在此對話弧中,機器人會在多個位置提示使用者輸入,從而建立需要考慮的分支路徑。
例如,當提示“utter_ask_fraudulent_transactions”時,如果沒有任何適用,使用者可能會以“拒絕”意圖進行響應。當被問及機器人是否可以幫助他們做任何其他事情時,使用者還可以選擇以“拒絕”意圖進行響應。
我們可以將這個長故事分成幾個小故事:
1 stories: 2 - story: Customer loses a credit card 3 steps: 4 - intent: card_lost 5 - action: utter_card_locked 6 - action: spending_history_form 7 - active_loop: spending_history_form 8 - active_loop: null 9 - slot_was_set: 10 - reviewed_transactions: ["starbucks"] 11 - action: utter_ask_fraudulent_transactions 12 13 - story: Customer reviews transactions and gets a new card 14 steps: 15 - action: utter_ask_fraudulent_transactions 16 - intent: inform 17 - action: action_update_transactions 18 - slot_was_set: 19 - reviewed_transactions: ["target", "starbucks"] 20 - intent: affirm 21 - action: utter_confirm_transaction_dispute 22 - action: utter_replace_card 23 - action: mailing_address_form 24 - active_loop: mailing_address 25 - active_loop: null 26 - action: utter_sent_replacement 27 - action: utter_anything_else 28 29 - story: Customer has something else they need help with 30 steps: 31 - action: utter_anything_else 32 - intent: affirm 33 - action: utter_help