Dialog Flow — Parameter(s) Validation [Dialog Flow ท่ายาก]
Blog นี้เกิดขึ้นมา เพราะว่าช่วงที่ผ่านมา ได้ใช้ชีวิตใกล้ชิดกับ Dialogflow มาก ในตอนแรกที่ได้รู้จักกับ api.ai (ก่อนจะเปลี่ยนชื่อมาเป็น Dialogflow) ก็รู้สึกว่า
Dialogflow ว้าววววววววว มากกกกกกกก
ไม่ว่าจะเป็นเรื่องของความสามารถที่จะเข้าใจภาษาธรรมชาติ (รองรับภาษาไทยด้วย), ตัวช่วยชั้นดีอย่าง Entity, ระบบ Context และที่สำคัญคือรองรับการ Integrate กับ Platform ต่าง ๆ มากมาย หรือเอาไปประยุกต์ใช้กับระบบอื่น ๆ ได้ ผ่านการเรียก API ตรง ๆ ก็ได้ครับ
แต่เมื่อเริ่ม Implement จริง ความ “Ship หาย” ก็มาเยื่อน เนื่องจากหลาย ๆ Use case ตัว Dialogflow เองยังไม่ค่อยรองรับได้ดีนัก รวมถึงเรื่องการรองรับ Platform ต่าง ๆ ไม่เท่ากัน เช่น เรื่อง Event ที่ Google Assistant Plaform จัดเต็มมาก แต่กับ Platform อื่น ๆ นี่ลูกเมียน้อยมาก (บาง Platform ไม่มี แม้แต่ Welcome Event ให้ด้วยซ้ำ วิธีจัดการกับเรื่องพวกนี้ จะเขียนใน Blog ถัดไปนะครับ)
Greek Alert
จากจุดนี้เป็นต้นไป เนื้อหาลึกมากขึ้น และอธิบายเรื่องอื่นน้อยลงแล้วนะครับ สำหรับใครที่หลงเข้ามาอ่านแล้ว ยังยังไม่ค่อยเข้าใจ แนะนำว่าลองหาอ่าน Blog ที่อธิบายเรื่อง Intent, Entity, Event, Fulfillment หรือ Slot-filling พวกนี้ก่อนนะครับ
กลับมาเข้าเรื่องกันต่อ สำหรับตัว Dialogflow แล้ว หนึ่งในเรื่องที่ควรจะง่าย แต่ไม่ง่าย นั่นก็คือการทำ Parameter Validation ยิ่งในกรณีที่ Entity ไม่รองรับ หรือรองรับแค่บางภาษา หึหึ (รายการ Entity ทั้งหมด) แต่ต้องระวังให้ดีนะครับ ในบางกรณี Entity บางตัว มีแค่ในบางภาษาเท่านั้น เช่น Entity email มีแน่ ๆ ในภาษาอังกฤษ แต่ภาษาไทยไม่มี …
แต่ละภาษา จะมี Entity ให้ใช้ไม่เท่ากัน
แล้ว ต้องทำอย่างไรล่ะครับ ?
แนวทางการแก้ปัญหาที่คือ ใช้ Context และ Intent หลาย ๆ ตัว มาทำงานร่วมกัน ตัวอย่างเช่น ต้องการถามข้อมูล 2 อย่าง คือ เบอร์โทรศัพท์และที่อยู่ ตามลำดับ เพื่อจะใช้จัดส่งสินค้า ในกรณีนี้ เราจะต้องมีอย่างน้อง 3 Intent เพื่อให้ทำงานได้
แต่เอ๊ะ คนที่เคยใช้ Dialogflow มาก่อน อาจจะคิดว่า แบบนี้ใช้ Slot-filling ก็ได้นี่นา คำตอบคือ ใช่และไม่ใช่ครับ
ใช้ Slot-filling ได้ ถ้าไม่ต้องการ Validate ว่าข้อมูลถูกต้องหรือไม่
ใช้ Slot-filling ไม่ได้ ถ้าต้องการ Validate ว่าข้อมูลถูกต้องหรือไม่
เนื่องจาก Slot-filling ไม่มี Feature ด้านการทำ Validation ครับ (ข้อมูลวันที่ 23 ธันวาคม 2561) ตัว Slot-filling เองถูกออกแบบมาเพื่อทำ “dynamic prompts” เมื่อ User ไม่ได้ใส่ข้อมูลที่จำเป็นมา (Missing required parameter) และในระหว่างที่ Slot-filling กำลังทำงาน ตัว Dialogflow จะสร้าง Context ขึ้นมาจัดการตัว Slot-filling เอง เราไม่สามารถไปยุ่งอะไรกับ Context ตัวนี้ได้ครับ
ลงมือทำ
ผมจะยกตัวอย่าง กรณีที่ต้องการทำ Validation ข้อมูล 2 อย่าง คือ เบอร์โทรศัพท์และที่อยู่ ตามลำดับ เราจะใช้ทำ Intent หลาย ๆ Intent และใช้ Context เข้ามาช่วย โดยมีขั้นตอนดังนี้ครับ
- สร้าง Intent ที่จะแสดงคำถาม เบอร์โทรศัพท์ (Prompt Tel Intent)
- กำหนด Output Context สำหรับ Prompt Tel Intent (tel-context)
- สร้าง Intent ที่จะเก็บ เบอร์โทรศัพท์ (Get Tel Intent) โดยผูก Input phase กับ Parameter และที่สำคัญคือ เปิดใช้ Fulfillment ด้วยนะครับ
- กำหนด Input Context ให้ Get Tel Intent เป็นตัวเดียวกับ Output Context ของ Prompt Tel Intent (tel-context)
- ตรงนี้สำคัญ ห้ามตั้ง Output Context (tel-context) บน Get Tel Intent เด็ดขาด เพราะเราจะไปทำบน Fulfillment กันครับ
- ทำส่วน Validation บน Fulfillment ให้เรียบร้อย โดย
- ถ้าเบอร์โทรศัพท์ถูกต้อง อาจจะแสดงข้อความประมาณว่า เบอร์โทรศัพท์ถูกต้องแล้วถามที่อยู่ต่อ จากนั้นให้ตั้ง Output Context (address-context) สำหรับ Intent ตัวต่อไป นั่นคือ Intent ที่จะเก็บที่อยู่ (Get Address Intent) แล้วจึงแสดงข้อความสำหรับถามที่อยู่
- แต่ถ้าเบอร์โทรศัพท์ไม่ถูกต้อง อาจจะแสดงข้อความประมาณว่า เบอร์โทรศัพท์ไม่ถูกต้อง จากนั้นให้ตั้ง Output Context ให้เหมือนกับ Input Context (tel-context) แต่ให้กำหนด Life span เป็น 1 แล้วจึงแสดงข้อความสำหรับถามเบอร์โทรศัพท์ซ้ำอีกที
สำหรับการ Validate ที่อยู่ สามารถทำซ้ำขั้นตอนที่ 2–6 ได้เลยครับ
ถ้าหากมีสิ่งที่ต้องการตรวจสอบมากกว่านี้ หลัก ๆ แล้วก็จะเป็นการทำซ้ำข้อ 2–6 นั่นแหละครับ
รวมถึงการใส่ลูกเล่นบางอย่าง เช่น หากผู้ใช้ ใส่ข้อมูลผิดติดต่อกันเกินจำนวนที่กำหนด เราอาจจะต้องทำอะไรเป็นพิเศษ เราสามารถใส่ตัว Counter ไปใน Context ได้ครับ
ก่อนจะจากกัน
มาถึงจุดนี้ ทุกคนก็น่าจะมีความรู้สึกว่า
ทำไมทีม Dialogflow ถึงไม่ทำให้ Slot-filling ทำ Validation ได้ (ว่ะ)
ก็หวังว่า Blog นี้จะเป็นประโยชน์กับทุกท่านที่ได้อ่านนะครับ
ขอบคุณครับ
References
- จากแหล่งข้อมูลที่ยังไม่สามารถเปิดเผยได้ :-)