diff --git a/troubleshooting/20251002_emotion_top-p_improvement.md b/troubleshooting/20251002_emotion_top-p_improvement.md index 2b75687..4b56f3f 100644 --- a/troubleshooting/20251002_emotion_top-p_improvement.md +++ b/troubleshooting/20251002_emotion_top-p_improvement.md @@ -3,6 +3,9 @@ ## 발생 일시 2025-10-02 16:20 ~ 16:30 +## 완료 일시 +2025-10-02 17:32 + ## 현상 감정 분석 결과가 사용자에게 부적절하게 노출되고, 애매한 감정 판단 문제 발생 @@ -14,88 +17,82 @@ ## 원인 분석 ### 1. 감정 정보 노출 문제 -- llm_service.py:87-94에서 감정 분석 결과를 프롬프트에 직접 포함 - Gemini가 "detection certainty"를 "자신감"으로 오역 - 사람은 감정을 숫자로 말하지 않음 (내부 처리만 해야 함) ### 2. 단일 감정 판단의 한계 -- 현재: 1위 감정만 사용 (EmotionState.dominant) -- 문제: fear 45%, sadness 30% → fear만 선택 (sadness 무시) -- 실제: 복합 감정 상태 (불안정한 상태) +- 1위 감정만 사용 (EmotionState.dominant) +- fear 45%, sadness 30% → fear만 선택 (sadness 무시) -### 3. 애매한 확률 처리 부재 +### 3. 임계값 부재 - 1위가 35%인 경우도 해당 감정으로 판단 -- 임계값 없이 무조건 dominant 사용 -## 해결 방안 +## 해결 방안 (완료) -### 1. 감정 정보 노출 제거 (부분 완료) -- 커밋: 51e45d3 -- llm_service.py:87-98에서 system_instruction 생성 -- context['system_instruction']에 포함 -- **문제**: 핸들러(gemini/openai/claude)가 system_instruction 미사용 -- **결과**: 직접 노출은 제거되었으나 톤 조절 미적용 +### 1. 감정 정보 노출 제거 (완료) +- 커밋: 51e45d3, a5801e8 +- llm_service.py에서 system_instruction 생성 +- 핸들러 연동 완료 (gemini/openai/claude) +- 테스트 결과: 감정 언급 없음 ✅, 숫자/확률 표현 없음 ✅ -### 2. Top-p (Nucleus Sampling) 도입 (예정) +### 2. Top-p (Nucleus Sampling) 도입 (완료) +- 확률 높은 순 정렬 → 누적 합 70% 도달까지 선택 +- LLM 생성: p=0.9~0.95, 감정 분석: p=0.7 +- 예: fear 45% + sadness 30% = 75% → ["fear", "sadness"] -#### Top-p 원리 -- 확률 높은 순 정렬 → 누적 합 p 도달까지 선택 -- LLM 생성: p=0.9~0.95, 집중도 필요: p=0.5~0.7 -- 감정 분석 적용: p=0.7 (70% 누적) +### 3. 구현 완료 (커밋: a5801e8) -#### 임계값 설정 -- 1위 ≥ 70%: 단일 감정 (명확) -- 1위 < 50%: 복합 감정 (top-p 70% 사용) -- 모두 < 30%: neutral 처리 (애매함) +#### EmotionState 확장 +- base.py:19-26에 top_emotions, cumulative_p 필드 추가 +- calculate_top_p_emotions() 함수 구현 +- dominant/confidence deprecated 표시 -#### 복합 감정 예시 -``` -fear 45% + sadness 30% = 75% (> 70%) -→ ["fear", "sadness"] 복합 감정 -→ 톤: "조심스럽고 따뜻하게" -``` +#### Top-p 로직 적용 +- emotion_llm.py:47-48에 Top-p 70% 계산 +- 복합 감정 리스트 반환 -### 3. 구현 계획 +#### 복합 감정 응답 전략 +- llm_service.py:86-123에 Plutchik 기반 6개 조합 매핑 +- frozenset 매칭으로 복합 감정 처리 +- 단일 감정 폴백 전략 -#### 현재 상태 (코드 확인 완료) -- EmotionState: base.py:19-24 (4개 필드) -- 감정 분석: emotion_llm.py:26-98 -- 프롬프트 조절: llm_service.py:87-98 (system_instruction 생성만) -- DB 저장: database.py:172-177 (top_label, top_p) -- **미완성**: 핸들러가 system_instruction 무시 +#### 핸들러 연동 +- gemini_handler.py:117-118 +- openai_handler.py:30-34 +- claude_handler.py:30-34 +- context['system_instruction'] 프롬프트에 포함 -#### 1단계: 핸들러 수정 (필수) -- gemini_handler.py:59-150의 chat() 메서드 -- context['system_instruction'] 읽어서 프롬프트에 포함 -- openai/claude 핸들러도 동일 수정 - -#### 2단계: Top-p 로직 추가 -- emotion_llm.py:26-98에 Top-p 70% 계산 -- EmotionState 확장 또는 별도 반환 - -#### 3단계: 복합 감정 처리 -- llm_service.py:87-98 복합 감정 매핑 -- Plutchik 기반 복합 감정 전략: - - fear+sadness (despair): "희망을 제시하며 지지적으로" - - anger+disgust (contempt): "침착하고 객관적으로, 다른 관점 제시" - - sadness+anger (envy): "공정성 인정하며 긍정적 대안 제시" - - fear+disgust (shame): "판단 없이 수용적으로" - - joy+trust (love): "따뜻하고 열정적으로" - - surprise+sadness (disapproval): "이해하며 건설적 대안 제안" - -#### 4단계: DB 스키마 변경 -- top_label → top_emotions (JSONB) -- top_p → cumulative_p +#### DB 스키마 변경 +- database.py:169-194에 top_emotions, cumulative_p 저장 +- deprecated 컬럼 삭제 (top_label, top_p) ## 참고 문헌 - Top-p Sampling: https://en.wikipedia.org/wiki/Top-p_sampling -- Multi-label Emotion (2025): ME-TIEK 모델, EmoBERTa-X -- Probability-based Classification (2025) - Plutchik's Wheel of Emotions: https://www.6seconds.org/2025/02/06/plutchik-wheel-emotions/ -- Plutchik Dyads: Primary (adjacent), Secondary (2 petals), Tertiary (3 petals) + +## 테스트 결과 (2025-10-02 17:32) + +### 프로덕션 검증 +- 메시지: "복합 감정 잘 저장 되는지 체크 하려고 해." +- 응답: 감정 언급 없음 ✅, 숫자/확률 표현 없음 ✅ +- 응답 시간: 3124ms + +### DB 저장 확인 +```json +{ + "top_emotions": [ + {"label": "fear", "probability": 0.499}, + {"label": "neutral", "probability": 0.335} + ], + "cumulative_p": 0.833 +} +``` +- fear 49.9% + neutral 33.5% = 83.3% (Top-p 70% 초과) +- 복합 감정 정상 저장 확인 ## 관련 커밋 - 29c0317: 순환 참조 제거 - a946cef: 감정 프롬프트 detection certainty 명확화 - c531519: 한글 프롬프트 변경 (Gemini 오역 방지) - 51e45d3: 감정 분석 결과 사용자 노출 제거 +- a5801e8: Top-p 기반 복합 감정 처리 시스템 구현