DOCS/troubleshooting/20251002_happybell80_slack_bot_and_emotion_errors.md
happybell80 251cc6d123 docs: 감정 시스템 문서를 7감정 모델로 업데이트
- Inside Out 2축 모델 → ONNX 7감정 모델로 변경
- 250807_로빙_감정_시스템_설계도.md 업데이트
- 검토 결과 및 수정 사항 문서화

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <noreply@anthropic.com>
2025-10-02 14:09:47 +09:00

5.2 KiB

Slack 봇 메시지 403 에러 처리

발생 일시

2025-10-02 13:29 ~ 13:31

현상

robeing-gateway 로그에서 지속적인 403 Forbidden 에러 발생

에러 로그

app.services.slack_proxy - WARNING - No UUID found for Slack user U0935RJ60V6
app.routers.slack - ERROR - User not registered: team_id=T0925SXPS4D, slack_user_id=U0935RJ60V6

패턴

  • 빈도: 1-2분마다 반복 발생
  • HTTP 응답: 403 Forbidden
  • 영향: 불필요한 에러 로그 생성, 리소스 낭비

원인 분석

문제의 핵심

U0935RJ60V6는 로빙(Robeing) 봇의 Slack User ID로, 봇이 메시지를 보낼 때마다 게이트웨이가 이를 일반 사용자 메시지로 처리하려고 시도

상세 분석

  1. 현재 로직

    • 모든 Slack 이벤트에 대해 UUID 매핑 요구
    • 봇 메시지도 사용자 등록 검증 시도
    • UUID가 없으면 403 반환
  2. 정상 동작 vs 비정상 동작

    • 정상: U0925SXQFDK(사용자) → UUID 변환 성공 → rb8001 전달 → 200 OK
    • 비정상: U0935RJ60V6(봇) → UUID 찾기 실패 → 403 Forbidden

관련 파일

  • /home/admin/robeing-gateway/app/routers/slack.py (line 56-57)
  • /home/admin/robeing-gateway/.env

rb8001 EmotionState 객체 생성 에러

발생 일시

2025-10-02 13:29:52, 13:30:01 (KST)

  • 서버: 51124
  • 컨테이너: rb8001 (Up About an hour, healthy)
  • 발생 빈도: 10월 1일 이후 2회

현상

  • 입력: "로빙 하이"
  • 응답: "죄송합니다. 요청을 처리할 수 없습니다."
  • 연속 입력 "왜?"에도 동일한 에러 응답

에러 추적

1. 인사 패턴 미인식

  • decision_engine.py의 GREETING 패턴: "안녕", "hello", "hi", "반가워"
  • "로빙 하이"는 전체가 UNKNOWN으로 분류됨
  • UNKNOWN 타입은 LLM 처리로 넘어감

2. EmotionState 생성자 불일치

rb8001/app/core/emotion/base.py:16-23 (51124 서버 확인)

class EmotionState(NamedTuple):
    basic_dist: List[float]  # 5개 기본정서 분포
    social_dist: List[float]  # 4개 사회기능 분포
    combined_dist: List[float]  # 9개 통합 분포
    entropy: float  # 엔트로피 값
    dominant: str  # 주요 감정
    mode: str  # 'basic', 'social', 'combined'

에러 발생 위치 (4곳)

rb8001/app/llm/emotion_llm.py:35

emotion_state = EmotionState(
    emotions=result['probs'],  # 잘못된 필드명, 3개 인자만 전달
    dominant=result['top_label'],
    entropy=result['entropy']
)

rb8001/app/llm/emotion_llm.py:67

except Exception as e:
    logger.error(f"감정 분석 실패: {e}")
    return EmotionState()  # 빈 생성자 호출 - 6개 인자 필요

rb8001/app/llm/emotion_llm.py:80-83

emotion_state = EmotionState(
    emotions=user_emotion.get('probs', {}),  # 잘못된 필드명, 3개 인자만 전달
    dominant=user_emotion.get('top_label', 'neutral'),
    entropy=user_emotion.get('entropy', 1.0)
)

rb8001/app/llm/emotion_llm.py:89

else:
    emotion_state = EmotionState()  # 빈 생성자 호출

3. 에러 발생 순서

  1. "로빙 하이" → UNKNOWN 분류 (DecisionEngine)
  2. LLM 처리 시도 (app.llm.llm_service)
  3. EmotionState() 빈 생성자 호출 또는 3개 인자만 전달
  4. TypeError: EmotionState.new() missing 6 required positional arguments: 'basic_dist', 'social_dist', 'combined_dist', 'entropy', 'dominant', and 'mode'
  5. fallback_message 반환: "죄송합니다. 요청을 처리할 수 없습니다."

문제 파일

  • /home/happybell/projects/ivada/rb8001/app/llm/emotion_llm.py (line 35, 67, 80-83, 89)
  • /home/happybell/projects/ivada/rb8001/app/core/emotion/base.py (line 16-23)

해결 전략

EmotionState 기본값 함수 추가

rb8001/app/core/emotion/base.py에 추가:

def create_default_emotion_state() -> EmotionState:
    basic_dist = [0.2] * 5
    social_dist = [0.25] * 4
    combined_dist = [1.0/9] * 9
    return EmotionState(basic_dist, social_dist, combined_dist, 2.197, 'neutral', 'combined')

emotion_llm.py 수정

  • Line 67: return create_default_emotion_state()
  • Line 89: emotion_state = create_default_emotion_state()
  • Line 80-84: 올바른 필드명으로 재구성

인사 패턴 추가

rb8001/app/brain/decision_engine.py:103-105

IntentType.GREETING: [
    r"안녕", r"hello", r"hi", r"반가워", r"하이", r"로빙.*하이"
]

추가 검토 사항 (2025-10-02 14:30)

수정 완료 항목

  • create_default_emotion_state 함수 추가 및 init.py export
  • emotion_llm.py 4곳 EmotionState 생성 수정 (6개 필수 인자)
  • test_endpoint.py await 누락 수정 (line 132)
  • test_endpoint.py emotions 속성 → basic_emotions로 변경 (line 137)
  • 인사 패턴에 '하이', '로빙' 추가

잔여 이슈

  1. BASIC_EMOTIONS 불일치: 환경변수 기본값 'disgust' vs 코드 'surprise' 매핑
  2. dominant 확률 계산: 'neutral', 'happiness'가 ALL_EMOTIONS에 없음 (joy는 있음)
  3. 이모지 사용: format_emotion_info 함수 정의됨 (실제 호출 없어 안전)
  4. asyncio.new_event_loop(): emotion_classifier.py:52에 있지만 predict_async만 사용하므로 안전