4b86b2a660
- server-dev start/stop/deploy 및 Gitea push 자동 배포 - local-dev 로컬 개발 환경 Co-authored-by: Cursor <cursoragent@cursor.com>
172 lines
6.7 KiB
Python
172 lines
6.7 KiB
Python
"""
|
|
감정별 공감 응답 핸들러
|
|
──────────────────────
|
|
감정에 따른 공감 메시지 및 프롬프트 커스터마이징
|
|
"""
|
|
|
|
from typing import Optional
|
|
|
|
|
|
class EmotionHandler:
|
|
"""감정별 공감 응답 생성기"""
|
|
|
|
# 감정별 공감 프리픽스
|
|
EMPATHY_PREFIXES = {
|
|
"angry": [
|
|
"고객님의 불편한 경험에 대해 진심으로 사과드립니다. 😔",
|
|
"불편을 드려 정말 죄송합니다. 😔",
|
|
"고객님의 화나신 마음을 충분히 이해합니다. 😔"
|
|
],
|
|
"frustrated": [
|
|
"답답하셨겠습니다. 😓",
|
|
"막막하셨을 것 같습니다. 😓",
|
|
"불편하셨겠네요. 저희가 더 명확히 안내드리겠습니다. 😓"
|
|
],
|
|
"satisfied": [
|
|
"도움이 되셨다니 정말 기쁩니다! 😊",
|
|
"만족하셨다니 다행입니다! 😊",
|
|
"고객님께 도움을 드릴 수 있어 기쁩니다! 😊"
|
|
],
|
|
"confused": [
|
|
"이해하기 어려우셨군요. 제가 더 명확히 설명드리겠습니다. 🤔",
|
|
"헷갈리셨을 것 같네요. 차근차근 설명드리겠습니다. 🤔",
|
|
"복잡하게 느껴지셨나봅니다. 쉽게 풀어서 설명드릴게요. 🤔"
|
|
],
|
|
"worried": [
|
|
"걱정되시는 부분이 있으시군요. 안심하셔도 됩니다. 😌",
|
|
"염려하지 않으셔도 괜찮습니다. 자세히 안내드릴게요. 😌",
|
|
"불안하셨겠습니다. 정확한 정보를 드리겠습니다. 😌"
|
|
],
|
|
"neutral": []
|
|
}
|
|
|
|
# 감정별 시스템 프롬프트 추가 지시사항
|
|
EMOTION_INSTRUCTIONS = {
|
|
"angry": (
|
|
"\n【감정 고려사항 - 화난 고객】\n"
|
|
"⚠️ 고객이 매우 화가 난 상태입니다:\n"
|
|
"1. 먼저 진심으로 사과하세요.\n"
|
|
"2. 고객의 감정을 인정하고 공감하세요.\n"
|
|
"3. 구체적인 해결책을 빠르게 제시하세요.\n"
|
|
"4. 추가 불편을 드리지 않도록 명확하고 간결하게 답변하세요.\n"
|
|
"5. 필요시 상담원 연결이나 콜센터 안내를 제안하세요."
|
|
),
|
|
"frustrated": (
|
|
"\n【감정 고려사항 - 답답한 고객】\n"
|
|
"💡 고객이 문제 해결에 어려움을 겪고 있습니다:\n"
|
|
"1. 고객의 답답함에 공감하세요.\n"
|
|
"2. 복잡한 설명보다는 단계별로 쉽게 설명하세요.\n"
|
|
"3. 즉시 실행 가능한 해결 방법을 제시하세요.\n"
|
|
"4. 추가 도움이 필요한지 물어보세요."
|
|
),
|
|
"satisfied": (
|
|
"\n【감정 고려사항 - 만족한 고객】\n"
|
|
"😊 고객이 긍정적인 상태입니다:\n"
|
|
"1. 긍정적인 톤을 유지하세요.\n"
|
|
"2. 추가로 도움이 될 만한 정보를 제안하세요.\n"
|
|
"3. 다른 질문이 있는지 자연스럽게 물어보세요."
|
|
),
|
|
"confused": (
|
|
"\n【감정 고려사항 - 혼란스러운 고객】\n"
|
|
"🤔 고객이 개념 이해에 어려움을 겪고 있습니다:\n"
|
|
"1. 전문 용어를 피하고 쉬운 말로 설명하세요.\n"
|
|
"2. 예시를 들어 설명하세요.\n"
|
|
"3. 단계를 나눠서 차근차근 설명하세요.\n"
|
|
"4. 추가 질문을 환영하는 분위기를 만드세요."
|
|
),
|
|
"worried": (
|
|
"\n【감정 고려사항 - 걱정하는 고객】\n"
|
|
"😌 고객이 불안해하거나 걱정하고 있습니다:\n"
|
|
"1. 먼저 안심시키세요.\n"
|
|
"2. 정확하고 신뢰할 수 있는 정보를 제공하세요.\n"
|
|
"3. 예방 방법이나 주의사항을 함께 안내하세요.\n"
|
|
"4. 문제가 없음을 명확히 전달하세요."
|
|
),
|
|
"neutral": ""
|
|
}
|
|
|
|
def get_empathy_prefix(self, emotion_name: str, intensity: float) -> Optional[str]:
|
|
"""감정에 맞는 공감 프리픽스 반환
|
|
|
|
Args:
|
|
emotion_name: 감정 이름
|
|
intensity: 감정 강도 (0.0 ~ 1.0)
|
|
|
|
Returns:
|
|
공감 메시지 또는 None
|
|
"""
|
|
prefixes = self.EMPATHY_PREFIXES.get(emotion_name, [])
|
|
|
|
if not prefixes:
|
|
return None
|
|
|
|
# 강도에 따라 선택
|
|
if intensity > 0.7:
|
|
# 강한 감정 → 첫 번째 (가장 강한 공감)
|
|
return prefixes[0]
|
|
elif intensity > 0.4:
|
|
# 중간 감정 → 두 번째
|
|
return prefixes[min(1, len(prefixes) - 1)]
|
|
else:
|
|
# 약한 감정 → 마지막 (가장 약한 공감)
|
|
return prefixes[-1]
|
|
|
|
def get_emotion_instruction(self, emotion_name: str) -> str:
|
|
"""감정별 시스템 프롬프트 추가 지시사항"""
|
|
return self.EMOTION_INSTRUCTIONS.get(emotion_name, "")
|
|
|
|
def should_add_empathy(self, emotion_name: str, intensity: float, confidence: float) -> bool:
|
|
"""공감 메시지를 추가해야 하는지 판단
|
|
|
|
Args:
|
|
emotion_name: 감정 이름
|
|
intensity: 감정 강도
|
|
confidence: 신뢰도
|
|
|
|
Returns:
|
|
공감 메시지 추가 여부
|
|
"""
|
|
# 중립 감정은 공감 불필요
|
|
if emotion_name == "neutral":
|
|
return False
|
|
|
|
# 신뢰도가 낮으면 공감 추가 안함
|
|
if confidence < 0.6:
|
|
return False
|
|
|
|
# 부정적 감정 (angry, frustrated, worried)은 강도 상관없이 공감
|
|
if emotion_name in ["angry", "frustrated", "worried"]:
|
|
return True
|
|
|
|
# 긍정적/혼란 감정은 강도가 충분히 높을 때만
|
|
return intensity > 0.5
|
|
|
|
def enhance_answer_with_empathy(
|
|
self,
|
|
answer: str,
|
|
emotion_name: str,
|
|
intensity: float,
|
|
confidence: float
|
|
) -> str:
|
|
"""답변에 공감 메시지 추가
|
|
|
|
Args:
|
|
answer: 원본 답변
|
|
emotion_name: 감정 이름
|
|
intensity: 감정 강도
|
|
confidence: 신뢰도
|
|
|
|
Returns:
|
|
공감 메시지가 추가된 답변
|
|
"""
|
|
if not self.should_add_empathy(emotion_name, intensity, confidence):
|
|
return answer
|
|
|
|
empathy_prefix = self.get_empathy_prefix(emotion_name, intensity)
|
|
|
|
if not empathy_prefix:
|
|
return answer
|
|
|
|
# 공감 메시지를 답변 앞에 추가
|
|
return f"{empathy_prefix}\n\n{answer}"
|