+2

[RASA 3] Bài 3 - Trích lọc thông tin từ nội dung chat của người dùng

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. image.png

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:

image.png

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é.

Tài liệu tham khảo

https://rasa.com/docs/rasa/nlu-training-data

https://rasa.com/docs/rasa/domain/#slot-mappings


All Rights Reserved

Viblo
Let's register a Viblo Account to get more interesting posts.