본문 바로가기

업무/챗봇 (Rasa)

[Rasa] 챗봇_ slot 이벤트에 따른 action진행 (SlotSet)

 

[ Rasa SDK ]

events

from rasa_sdk.events import (
    Restarted, SlotSet, SessionStarted, ActionExecuted, EventType,
    FollowupAction, ActiveLoop, Form, UserUtteranceReverted, ConversationPaused , AllSlotsReset
)

 

 

* SlotSet

from rasa_sdk import Action
from rasa_sdk.events import SlotSet

class ActionSaveUserInfo(Action):
    def name(self):
        return "action_save_user_info"

    def run(self, dispatcher, tracker, domain):
        # 사용자 메시지에서 정보 추출 (예: 이름)
        user_name = tracker.latest_message.get('text')
        
        # `user_name` 슬롯에 사용자 이름 저장
        return [SlotSet("user_name", user_name)]

=> 미리 지정해둔 'action_save_user_info' 액션에 대해 실행되는 클래스.

SlotSet("user_name", user_name) 

=> 사용자로부터 입력받은 메시지인 user_name 을 'user_name' 이라는 슬롯에 저장. 

 

 'user_name' 슬롯은  domain.yml 파일에서 지정

slots:
  user_name:
    type: text
    influence_conversation: false

 

슬롯이 채워졌으니 rule / stroy 에서 정의한 규칙대로 실행된다.

greeting.yml  파일에 rule과 story 정의.

**기본적으로는 rules.yml , stories.yml 별도의 두 개의 파일로 구성되어 있지만, 하나의 파일에 정의하여 기능별 파일로 구성하는 것도 가능.

version: "2.0"

rules:
- rule: 사용자 이름을 받았을 때 인사하기
  condition:
    - slot_was_set:
        - user_name: null  # user_name 슬롯이 채워져 있지 않은 상태
  steps:
    - intent: greet
    - action: utter_ask_name
    - intent: provide_name
    - action: action_save_user_info
    - action: utter_greet_by_name

stories:
- story: 사용자 이름을 이용한 개인화된 인사
  steps:
    - intent: greet
    - action: utter_ask_name
    - intent: provide_name
    - action: action_save_user_info
    - slot_was_set:
        - user_name
    - action: utter_greet_by_name

 

=> greet 인텐트(사용자의 인사)에 대해 utter_ask_name 액션(이름요청) 실행.

=> provide_name 인텐트(사용자이름)에 대해 action_save_user_info 액션(이름저장) 실행.

=> 슬롯이 채워지면 (slot_was_set  > user_name) utter_greet_by_name 액션(인사로응답) 실행.

 


 

** user_name이라는 값이 채워지기만 한다면   utter_greet_by_name 액션을 진행하기 때문에 

슬롯값에 대한 유효성검사를 진행하려면 custom action 필요.

actions.py  파일

from rasa_sdk import Action
from rasa_sdk.events import SlotSet
from rasa_sdk.executor import CollectingDispatcher

class ValidateUserName(Action):
    def name(self):
        return "validate_user_name"

    def run(self, dispatcher, tracker, domain):
        user_name = tracker.get_slot('user_name')
        
        # 사용자 이름 유효성 검사 로직
        if not user_name or len(user_name) < 2:  # 예: 이름이 너무 짧을 경우
            dispatcher.utter_message(text="이름이 너무 짧습니다. 다시 입력해주세요.")
            return [SlotSet("user_name", None)]  # 유효하지 않은 경우 슬롯을 비우거나 재설정
        else:
            dispatcher.utter_message(text=f"안녕하세요, {user_name}님!")
            return []

=> 채워진 slot값(user_name)이 조건을 만족하지 않는다면 슬롯값 초기화.

SlotSet("user_name", None)  

=> None을 넣어주어 'user_name' 슬롯값이 초기화.

=> 슬롯값이 다시 null이 되어  utter_ask_name 액션(이름요청) 실행 가능하도록 만들어준다.

 

greeting.yml  파일 수정.

version: "2.0"

rules:
- rule: 이름 재요청
  condition:
    - slot_was_set:
        - user_name: null
  steps:
    - action: utter_ask_name
    - intent: provide_name
    - action: validate_user_name

stories:
- story: 이름 요청 및 검증
  steps:
    - intent: greet
    - action: utter_ask_name
    - intent: provide_name
    - action: validate_user_name
    - slot_was_set:
        - user_name: null
    - action: utter_ask_name

 

=> greet 인텐트(사용자의 인사)에 대해 utter_ask_name 액션(이름요청) 실행.

=> provide_name 인텐트(사용자이름)에 대해 validate_user_name (유효성검사) 액션 실행.

=> 슬롯이 채워지면 (slot_was_set  > user_name) utter_greet_by_name 액션(인사로응답) 실행.

   => 이 부분이  validate_user_name 액션에 포함.