Bài trước mình đã thực hành làm quen với Rasa 3 và dạy chatbot chào hỏi cơ bản, và cũng gắn giao diện lên website UI nhìn cho thân thiện rồi. Bây giờ mình sẽ tìm hiểu tiếp làm sao để chatbot phản hồi thân thiện và "thông minh" hơn.
Bài viết này mục đích tường thuật lại các bước mình đã thực hành một cách đơn giản nhất để ai cũng có thể thực hành theo, các bạn tìm hiểu chuyên sâu hơn thì đọc tài liệu chính thức của Rasa nhé, mình để link ở phần Tài liệu tham khảo ở cuối bài viết.
Trích lọc thực thể từ nội dung chat
Ví dụ trong bài này mình muốn huấn luyện chatbot hỏi tên sau đó chào hỏi người dùng có kèm tên.
Để Chatbot trích lọc tên của người dùng từ nội dung chat và gắn vào câu chào mà chatbot phản hồi ta thực hiện các bước:
Bước 1: Định nghĩa ý định và các thực thể cần trích lọc từ ý định trong file /data/nlu.yml
Ví dụ người dùng chat câu "Tôi tên là Nam nhé", muốn chỉ cho Bot biết từ "Nam" là thực thể tên của người dùng ta khai báo như sau:
- intent: answer_name examples: | - Tôi tên là [Nam]{"entity": "user_name"} nhé
Trong đó:
- answer_name là tên ý định, muốn đặt như thế nào tùy ý.
- [<thực thể mẫu>] bao quanh đoạn text chỉ định thực thể mẫu.
- "user_name" là tên tùy ý mà mình đặt cho thực thể.
Định nghĩa càng nhiều mẫu thì chatbot sẽ càng trích lọc thực thể càng chính xác hơn.
Code mẫu file nlu.yml của mình như sau:
version: "3.1" nlu:
- intent: answer_name examples: | - Tôi tên là [Nam]{"entity": "user_name"} - Chị tên là [Hoa]{"entity": "user_name"} - Anh tên là [Long]{"entity": "user_name"} - Mình tên là [Phúc]{"entity": "user_name"} - Mình tên [Phát]{"entity": "user_name"} - Em tên [Hà]{"entity": "user_name"} nhé - Huy[Nam]{"entity": "user_name"} - Gọi mình là [Phụng]{"entity": "user_name"} nha - Tôi tên [Hoàng]{"entity": "user_name"} - chị tên [Cúc]{"entity": "user_name"} - anh tên [Đức]{"entity": "user_name"} - [Tuấn]{"entity": "user_name"} nhé - [Bình]{"entity": "user_name"} - [Lĩnh]{"entity": "user_name"} - [Viễn]{"entity": "user_name"} - [Duy]{"entity": "user_name"} - [Tú]{"entity": "user_name"} - [Tâm]{"entity": "user_name"} - [Xuân]{"entity": "user_name"} - [Kiều]{"entity": "user_name"} - [Thành]{"entity": "user_name"} - [Đăng]{"entity": "user_name"} - [Bình]{"entity": "user_name"} - [Đạt]{"entity": "user_name"} - [Vy]{"entity": "user_name"} - [Loan]{"entity": "user_name"} - [Luân]{"entity": "user_name"} - [Quang]{"entity": "user_name"} - [Thuận]{"entity": "user_name"} - [Trọng]{"entity": "user_name"} - [An]{"entity": "user_name"} - [Kim]{"entity": "user_name"} - [Hằng]{"entity": "user_name"} - [Cường]{"entity": "user_name"} - [Phú]{"entity": "user_name"} - [Thiện]{"entity": "user_name"} - intent: greet examples: | - hey - hello - hi - chào - xin chào - chào bot - có ai ở đó không - tôi cần hỗ trợ - Chào bạn - Chào anh - Chào chị - Chào buổi sáng - Có đó không - Rãnh không - Ê - Hú - chào em - em ơi, cho anh hỏi - bot ơi - cho mình hỏi chút - intent: goodbye examples: | - bye - goodbye - g9 - good night - bye bye - tạm biệt - Hẹn gặp lại - Ngủ ngon - Chúc ngủ ngon - Nói chuyện sau nhé - Tôi sẽ liên hệ sau - tạm biệt em - tạm biệt bot nhá - Biến - Không
Bước 2: Định nghĩa các câu trả lời của bot ở file domain.yml
Đầu tiên cần khai báo ý định answer_name:
intents: - answer_name
Tiếp theo, khai báo tên thực thể user_name:
entities: - user_name
Tiếp đến mình khai báo slot để lưu trữ tên người dùng:
slots: name: type: text mappings: - type: from_entity entity: user_name
Trong đó:
- name là tên biến, có thể đặt trùng tên thực thể nhưng trong ví dụ này mình đặt khác để dễ phân biệt.
- user_name là tên thực thể đã khai báo ở bước trước. Bạn có thể tìm hiểu các tùy chỉnh khác của slots ở đây.
Tới đây thì công đoạn khai báo để trích lọc thực thể từ nội dung chat của người dùng đã xong. Bây giờ mình sẽ sử dụng slot name đã khai báo trong nội dung response như sau:
responses: utter_greet_with_name: - text: "Xin chào {name}!\n{name} cần Bot giúp gì không?"
Nếu không được tác động gì thì slot sẽ được lưu giữ trong suốt thời gian session còn tồn tại, mình có thể tái sử dụng trong các xử lý khác, bài này mình sẽ sử dụng thêm slot name ở trong response utter_goodbye_with_name như sau:
utter_goodbye_with_name: - text: "Tạm biệt {name}!\nHãy quay lại với Bot khi {name} cần nhé!"
Nội dung đầy đủ của file domain.yml mình dùng như sau:
version: "3.1" intents: - answer_name - greet - goodbye entities: - user_name slots: name: type: text mappings: - type: from_entity entity: user_name responses: utter_greet: - text: "Xin chào! Tôi có thể giúp gì cho bạn?" - text: "Chào bạn! Bạn cần Bot giúp gì không?" - text: "Xin chào!\nTôi là Bot, rất hân hạnh được trò chuyện với bạn!" utter_goodbye: - text: "Bye" - text: "Tạm biệt bạn!" - text: "Tạm biệt!\nHẹn gặp lại!" utter_iamabot: - text: "I am a bot, powered by Rasa." utter_ask_name: - text: "Bạn vui lòng cho Bot biết tên để tiện xưng hô nhé!" utter_greet_with_name: - text: "Xin chào {name}!\n{name} cần Bot giúp gì không?" utter_goodbye_with_name: - text: "Tạm biệt {name}!\nHãy quay lại với Bot khi {name} cần nhé!" session_config: session_expiration_time: 60 carry_over_slots_to_new_session: true
Bước 3: Chỉ định cách ứng xử của bot trong file /data/stories.yml
Bạn cũng có thể dùng rule, nhưng bài trước mình dùng rule rồi nên bài này mình muốn làm quen với story.
Cú pháp khai báo story tương tự như rule. Điểm khác nhau ở rule và story là đối với rule khi 1 intent được khai báo với 1 action trong rule rồi thì không được khai báo với action khác trong cả rule và story. Còn story thì linh hoạt hơn, bạn có thể sáng tạo ra nhiều câu chuyện khác nhau để chatbot phản ứng với ý định của người dùng linh hoạt hơn.
Nội dung file stores.yml mẫu của mình như sau:
version: "3.1" stories: - story: Chào hỏi steps: - intent: greet - action: utter_ask_name - intent: answer_name - action: utter_greet_with_name - intent: goodbye - action: utter_goodbye_with_name
Bước 4: Chạy lệnh train và test kết quả
Chạy lệnh sau để rasa huấn luyện lại chatbot theo các nội dung mình đã định nghĩa ở các bước trên:
rasa train
Sau khi hoàn thành quá trình train thì mình chạy lệnh để run server chat:
rasa run --cors "*"
Đợi đến khi hiện thông báo như hình dưới là server đã sẵn sàng.
Cuối cùng mình dùng lệnh rasa shell hoặc mở web UI đã kết nối với chatbot và thử nghiệm thôi.
Nếu bạn chưa biết cách kết nối rasa với web UI thì có thể tham khảo bài viết này: link.
Kết quả sẽ như vầy:
Kịch bản chat bên trên vẫn chưa thực tế lắm, mình sẽ cố gắng tìm những kịch bản thực tế thú vị hơn để thực hành trong những bài sau, hoặc các bạn có đề bài nào cần huấn luyện cho chatbot thì comment bên dưới để mình cùng tìm hiểu nhé.