πŸ“š Rasa Form Validation 이슈 ν•΄κ²°κΈ°

엔케이·2025λ…„ 2μ›” 5일
0
post-thumbnail

πŸ“š Rasa Form Validation 이슈 ν•΄κ²°κΈ°

이번 κΈ€μ—μ„œλŠ” Rasaλ₯Ό ν™œμš©ν•œ λŒ€ν™”ν˜• 챗봇 개발 쀑 κ²ͺμ—ˆλ˜ Form Validation μ΄μŠˆμ™€ 이λ₯Ό μ–΄λ–»κ²Œ ν•΄κ²°ν–ˆλŠ”μ§€μ— λŒ€ν•΄ μ •λ¦¬ν–ˆμŠ΅λ‹ˆλ‹€.


🎯 문제 상황

Rasaλ₯Ό ν™œμš©ν•΄ μ—¬ν–‰ 일정을 μˆ˜μ§‘ν•˜λŠ” 챗봇을 κ°œλ°œν•˜κ³  μžˆμ—ˆμŠ΅λ‹ˆλ‹€. λŒ€ν™” 흐름은 λ‹€μŒκ³Ό κ°™μ•˜μŠ΅λ‹ˆλ‹€:

  1. μ‚¬μš©μžκ°€ "μ„œμšΈλ‘œ μ—¬ν–‰ κ°€κ³  μ‹Άμ–΄" μž…λ ₯
  2. 챗봇이 "λͺ‡ μΌλ™μ•ˆ 머무λ₯Ό μ˜ˆμ •μ΄μ•Ό?" 질문 (utter_ask_days)
  3. μ‚¬μš©μžκ°€ "5일"둜 응닡

문제:

  • μ‚¬μš©μžμ˜ 짧은 응닡(예: "5일", "3")에 λŒ€ν•΄ days 슬둯이 μ •μƒμ μœΌλ‘œ μ±„μ›Œμ§€μ§€ μ•Šμ•˜μŠ΅λ‹ˆλ‹€.
  • actions.py에 μž‘μ„±ν•œ validate_days ν•¨μˆ˜κ°€ ν˜ΈμΆœλ˜μ§€ μ•Šμ•˜μŠ΅λ‹ˆλ‹€.

πŸ” 문제 뢄석 κ³Όμ •

  1. Regex νŒ¨ν„΄ 점검:

    • 기쑴의 μ •κ·œ ν‘œν˜„μ‹μ΄ λ‹¨μˆœ 숫자 μž…λ ₯을 μΈμ‹ν•˜μ§€ λͺ»ν•˜λŠ” 문제λ₯Ό ν™•μΈν–ˆμŠ΅λ‹ˆλ‹€.
  2. NLU 데이터 λΆ€μ‘±:

    • 짧은 응닡에 λŒ€ν•œ ν•™μŠ΅ 데이터가 λΆ€μ‘±ν•˜μ—¬ μ—”ν‹°ν‹° 인식에 어렀움이 μžˆμŒμ„ λ°œκ²¬ν–ˆμŠ΅λ‹ˆλ‹€.
  3. Action Server μ„€μ • 였λ₯˜:

    • μ»€μŠ€ν…€ μ•‘μ…˜μ„ μ‹€ν–‰ν•˜κΈ° μœ„ν•œ endpoints.yml 섀정이 λˆ„λ½λ˜μ–΄ μžˆμ—ˆκ³ , 이둜 인해 μ•‘μ…˜ μ„œλ²„ 호좜이 λ˜μ§€ μ•Šμ•˜μŠ΅λ‹ˆλ‹€.
  4. Form Validation 둜직 λΆ€μž¬:

    • 폼 ν™œμ„±ν™” ν›„ μ‚¬μš©μž μž…λ ₯에 λŒ€ν•œ 검증 둜직이 μ •μƒμ μœΌλ‘œ λ™μž‘ν•˜μ§€ μ•ŠλŠ” 것을 ν™•μΈν–ˆμŠ΅λ‹ˆλ‹€.

πŸ› οΈ ν•΄κ²° κ³Όμ •

1번 λ°©λ²•μœΌλ‘œλŠ” λ¬Έμ œκ°€ ν•΄κ²°λ˜μ§€ μ•Šμ•˜μŠ΅λ‹ˆλ‹€. 2번 λ°©λ²•μœΌλ‘œ 데이터λ₯Ό μΆ”κ°€ν•˜κ³  μž¬ν•™μŠ΅μ„ μ§„ν–‰ν–ˆμ„ λ•Œ, μ •μƒμ μœΌλ‘œ λ™μž‘ν–ˆμŠ΅λ‹ˆλ‹€.

ν•˜μ§€λ§Œ 2번 방법은 λ„ˆλ¬΄ 쉽고, 데이터가 λΆˆν•„μš”ν•˜κ²Œ λ°©λŒ€ν•΄μ§„λ‹€κ³  νŒλ‹¨ν–ˆμŠ΅λ‹ˆλ‹€.

κ·Έλž˜μ„œ action μ„œλ²„κ°€ ν˜ΈμΆœλ˜μ§€ μ•ŠλŠ” 문제λ₯Ό ν•΄κ²°(3번)ν•˜κ³  4번 λ°©λ²•μœΌλ‘œ 문제 해결을 μ§„ν–‰ν–ˆμŠ΅λ‹ˆλ‹€.

1️⃣ endpoints.yml μ„€μ • μΆ”κ°€

action_endpoint:
  url: "http://localhost:5055/webhook"
  • μ•‘μ…˜ μ„œλ²„κ°€ 챗봇과 톡신할 수 μžˆλ„λ‘ μ„€μ •ν•©λ‹ˆλ‹€.
  • rasa run actions λͺ…λ Ήμ–΄λ‘œ μ•‘μ…˜ μ„œλ²„λ₯Ό μ‹€ν–‰ν•©λ‹ˆλ‹€.

2️⃣ actions.py μˆ˜μ • (Validation μ•‘μ…˜ μΆ”κ°€)

from typing import Any, Text, Dict
from rasa_sdk import Tracker, FormValidationAction
from rasa_sdk.executor import CollectingDispatcher
import re

class ValidateTravelForm(FormValidationAction):
    def name(self) -> Text:
        return "validate_travel_form"

    async def validate_days(
        self,
        slot_value: Any,
        dispatcher: CollectingDispatcher,
        tracker: Tracker,
        domain: Dict[Text, Any],
    ) -> Dict[Text, Any]:
        match = re.search(r"\d+", str(slot_value))
        if match:
            return {"days": match.group(0)}
        else:
            dispatcher.utter_message(text="μ •ν™•ν•œ 일수λ₯Ό μž…λ ₯ν•΄ μ£Όμ„Έμš”. 예: 3일, 5일")
            return {"days": None}
  • validate_days ν•¨μˆ˜λŠ” μ‚¬μš©μž μž…λ ₯μ—μ„œ 숫자λ₯Ό μΆ”μΆœν•˜μ—¬ days μŠ¬λ‘―μ— μ €μž₯ν•©λ‹ˆλ‹€.
  • 잘λͺ»λœ μž…λ ₯ μ‹œ μ‚¬μš©μžμ—κ²Œ μž¬μž…λ ₯을 μš”μ²­ν•©λ‹ˆλ‹€.

3️⃣ domain.yml μ„€μ • 보완

forms:
  travel_form:
    required_slots:
      - location
      - days

actions:
  - validate_travel_form

slots:
  days:
    type: text
    influence_conversation: true
    mappings:
      - type: from_entity
        entity: days
      - type: from_text
        conditions:
          - active_loop: travel_form
            requested_slot: days
  • actions μ„Ήμ…˜μ— validate_travel_form을 λ“±λ‘ν•©λ‹ˆλ‹€.
  • from_text 맀핑을 μΆ”κ°€ν•˜μ—¬ 짧은 μž…λ ₯도 μŠ¬λ‘―μ— μ €μž₯될 수 μžˆλ„λ‘ ν–ˆμŠ΅λ‹ˆλ‹€.

4️⃣ λͺ¨λΈ μž¬ν•™μŠ΅ 및 μ‹€ν–‰

rasa train
rasa run actions
rasa shell
  • λͺ¨λΈμ„ μž¬ν•™μŠ΅ν•˜κ³  μ•‘μ…˜ μ„œλ²„λ₯Ό μ‹€ν–‰ν•˜μ—¬ λ³€κ²½ 사항을 λ°˜μ˜ν–ˆμŠ΅λ‹ˆλ‹€.

βœ… μ΅œμ’… κ²°κ³Ό

  • μ‚¬μš©μžμ˜ 짧은 응닡(예: "5일", "3")에도 validate_days ν•¨μˆ˜κ°€ μ •μƒμ μœΌλ‘œ ν˜ΈμΆœλ˜μ—ˆμŠ΅λ‹ˆλ‹€.
  • μž…λ ₯값이 μ •ν™•νžˆ μΆ”μΆœλ˜μ–΄ days μŠ¬λ‘―μ— μ €μž₯λ˜μ—ˆμŠ΅λ‹ˆλ‹€.

μ˜ˆμƒ λŒ€ν™” 흐름:

μ‚¬μš©μž: μ„œμšΈλ‘œ μ—¬ν–‰ κ°€κ³  μ‹Άμ–΄
봇: λͺ‡ μΌλ™μ•ˆ 머무λ₯Ό μ˜ˆμ •μ΄μ•Ό?🧐
μ‚¬μš©μž: 5일
봇: μ’‹μ•„μš”πŸ˜ μ„œμšΈμœΌλ‘œ 5μΌλ™μ•ˆ μ—¬ν–‰ν•  일정을 κ³„νšν•΄λ³Όκ²Œμš”πŸ˜Ž

πŸ€” 배운 점

  1. μ•‘μ…˜ μ„œλ²„ μ„€μ •μ˜ μ€‘μš”μ„±:

    • endpoints.yml 섀정이 λˆ„λ½λ˜λ©΄ μ»€μŠ€ν…€ μ•‘μ…˜μ΄ μ‹€ν–‰λ˜μ§€ μ•ŠμŠ΅λ‹ˆλ‹€.
  2. Validation μ•‘μ…˜μ˜ μ •ν™•ν•œ λ§€ν•‘:

    • validate_<slot_name> ν˜•μ‹μœΌλ‘œ ν•¨μˆ˜ 이름을 μ§€μ •ν•΄μ•Ό μžλ™ ν˜ΈμΆœλ©λ‹ˆλ‹€.
  3. μœ μ—°ν•œ 슬둯 λ§€ν•‘:

    • from_entity와 from_textλ₯Ό ν•¨κ»˜ μ‚¬μš©ν•˜λ©΄ λ‹€μ–‘ν•œ μž…λ ₯ νŒ¨ν„΄μ„ μ²˜λ¦¬ν•  수 μžˆμŠ΅λ‹ˆλ‹€.
  4. λ””λ²„κΉ…μ˜ 힘:

    • --debug λͺ¨λ“œλ₯Ό ν™œμš©ν•˜λ©΄ 폼 ν™œμ„±ν™” 및 μ•‘μ…˜ 호좜 과정을 μƒμ„Ένžˆ 확인할 수 μžˆμŠ΅λ‹ˆλ‹€.

πŸš€ 마무리

이번 κ²½ν—˜μ„ 톡해 Rasa의 Form Validation λ‘œμ§μ„ 깊이 이해할 수 μžˆμ—ˆμŠ΅λ‹ˆλ‹€. 챗봇 개발 쀑 μœ μ‚¬ν•œ μ΄μŠˆκ°€ λ°œμƒν•œλ‹€λ©΄ 이 글이 도움이 되기λ₯Ό λ°”λžλ‹ˆλ‹€. πŸ™Œ

profile
FE 개발자

0개의 λŒ“κΈ€