Files
exAichatbot_agent/exAiChatBot-chatbot2.0-agent/scripts/handlers/intent_detector.py
T
Macbook 4b86b2a660 Agent 2.0 exdev 서버 배포 스택
- server-dev start/stop/deploy 및 Gitea push 자동 배포
- local-dev 로컬 개발 환경

Co-authored-by: Cursor <cursoragent@cursor.com>
2026-07-21 22:57:30 +09:00

116 lines
3.8 KiB
Python

"""
의도 감지 모듈
──────────────
사용자 질문의 의도를 분류 (인사, 종료, 불만, 일반 등)
"""
from typing import Dict, List, Optional
from dataclasses import dataclass
@dataclass
class Intent:
"""의도 분류 결과"""
name: str # "greeting", "farewell", "general"
confidence: float # 0.0 ~ 1.0
matched_keywords: List[str] # 매칭된 키워드
def is_special(self) -> bool:
"""특별 처리가 필요한 의도인지 (인사, 종료만)"""
return self.name in ["greeting", "farewell"]
class IntentDetector:
"""사용자 의도 감지기"""
# 의도별 키워드 패턴
INTENT_PATTERNS = {
"greeting": {
"keywords": [
"안녕", "안녕하세요", "안녕하십니까",
"처음", "반가", "반갑습니다",
"hi", "hello", "hey",
"처음 뵙겠습니다", "처음입니다"
],
"priority": 1 # 우선순위 (낮을수록 높음)
},
"farewell": {
"keywords": [
"감사", "고마워", "고맙습니다", "감사합니다",
"잘됐", "해결", "알겠", "알았",
"끝", "종료", "그만",
"bye", "goodbye", "끝내", "닫기",
"도움 됐", "도움됐", "충분"
],
"priority": 2
}
# complaint 제거: 감정 분석(EmotionDetector)으로만 처리
}
def detect(self, query: str, ts: Optional[str] = None) -> Intent:
"""의도 감지
Args:
query: 사용자 질문
ts: 타임스탬프 (로깅용)
Returns:
Intent 객체
"""
query_lower = query.lower().strip()
# 빈 문자열 체크
if not query_lower:
return Intent(name="general", confidence=1.0, matched_keywords=[])
# 각 의도별 매칭 점수 계산
intent_scores = {}
for intent_name, config in self.INTENT_PATTERNS.items():
matched = []
for keyword in config["keywords"]:
if keyword.lower() in query_lower:
matched.append(keyword)
if matched:
# 매칭된 키워드 개수와 우선순위를 고려한 점수
score = len(matched) * (1.0 / config["priority"])
intent_scores[intent_name] = {
"score": score,
"matched": matched,
"priority": config["priority"]
}
# 매칭된 의도가 없으면 일반 질문
if not intent_scores:
return Intent(name="general", confidence=1.0, matched_keywords=[])
# 가장 높은 점수의 의도 선택
best_intent = max(intent_scores.items(), key=lambda x: x[1]["score"])
intent_name = best_intent[0]
intent_data = best_intent[1]
# 신뢰도 계산 (0.7 ~ 0.95)
confidence = min(0.95, 0.7 + (intent_data["score"] * 0.1))
result = Intent(
name=intent_name,
confidence=confidence,
matched_keywords=intent_data["matched"]
)
if ts:
print(f"[IntentDetector] {ts} 의도 감지: {result.name} (신뢰도: {result.confidence:.2f}, 키워드: {result.matched_keywords})")
return result
def is_greeting(self, query: str) -> bool:
"""인사 여부 판단 (간단한 헬퍼)"""
intent = self.detect(query)
return intent.name == "greeting"
def is_farewell(self, query: str) -> bool:
"""종료 인사 여부 판단"""
intent = self.detect(query)
return intent.name == "farewell"