diff --git a/plans/251016_emotion_integration_plan.md b/plans/251016_emotion_integration_plan.md new file mode 100644 index 0000000..18f65ef --- /dev/null +++ b/plans/251016_emotion_integration_plan.md @@ -0,0 +1,264 @@ +# 감정 분류기 통합 계획 + +**날짜**: 2025-10-16 +**작성자**: Claude +**목표**: Phase 3 감정 온톨로지를 실제 대화에 통합 + +--- + +## 현재 상태 + +### 구현 완료 +- ✅ EmotionClassifier (skill-embedding 연동) +- ✅ emotion_likelihood_ontology.py (11개 규칙) +- ✅ OntologyReasoner.reason_with_emotion() +- ✅ ethics_constraints_ontology.py (Router 통합) + +### 미구현 +- ❌ Router에 감정 분석 통합 +- ❌ 감정 정보를 LLM 컨텍스트에 전달 +- ❌ 실제 대화에서 감정 기반 응답 + +--- + +## 통합 방식 결정 + +### 방식 1: 증거 기반 우도 조정 (복잡) + +**흐름**: +``` +사용자 메시지 → 감정 분석 → 증거 추출 → reason_with_emotion() → 조정된 증거 → LLM +``` + +**문제점**: +- "증거"를 어떻게 추출할 것인가? +- 일반 대화에서는 명확한 증거가 없음 +- Coldmail처럼 구조화된 데이터가 아님 + +**적용 가능한 경우**: +- 의사결정 지원 (투자, 구매 등) +- 정보 비교 (장단점 분석) + +### 방식 2: 감정 컨텍스트 전달 (실용적) ✅ 선택 + +**흐름**: +``` +사용자 메시지 → 감정 분석 → context에 감정 추가 → LLM (감정 고려 응답) +``` + +**장점**: +- 구현 간단 +- 모든 대화에 적용 가능 +- LLM이 감정을 자연스럽게 활용 +- 추후 확장 용이 + +**구현 방법**: +```python +# 1. 감정 분석 +emotion_result = await emotion_classifier.predict_async(message) +user_emotion = emotion_result['top_label'] # fear, joy, sadness, etc. +emotion_confidence = emotion_result['top_p'] + +# 2. context에 추가 +context['user_emotion'] = user_emotion +context['emotion_confidence'] = emotion_confidence + +# 3. LLM에 전달 (프롬프트에서 활용) +llm_response = await llm_service.process_request(llm_request) +``` + +--- + +## 구현 계획 + +### 1단계: 환경변수 추가 + +**.env**: +```bash +# Emotion Analysis (Phase 3 Ontology) +USE_EMOTION_ANALYSIS=false # 기본값: 비활성화 +``` + +**config.py**: +```python +USE_EMOTION_ANALYSIS: bool = os.getenv("USE_EMOTION_ANALYSIS", "false").lower() == "true" +``` + +### 2단계: Router에 감정 분석 통합 + +**위치**: `router.py` → `_call_internal_llm()` 메서드 + +**추가 코드**: +```python +# Phase 3: 감정 분석 (옵션) +if settings.USE_EMOTION_ANALYSIS: + try: + from app.core.emotion.emotion_classifier import get_classifier + emotion_classifier = get_classifier() + + emotion_result = await emotion_classifier.predict_async(message) + user_emotion = emotion_result['top_label'] + emotion_confidence = emotion_result['top_p'] + + # context에 추가 + if context is None: + context = {} + context['user_emotion'] = user_emotion + context['emotion_confidence'] = emotion_confidence + + logger.info(f"Emotion detected: {user_emotion} (confidence: {emotion_confidence:.2f})") + + except Exception as e: + logger.error(f"Emotion analysis failed: {e}") +``` + +### 3단계: LLM 프롬프트에 감정 정보 활용 + +**위치**: `llm_service.py` 또는 프롬프트 생성 부분 + +**프롬프트 예시**: +```python +if context.get('user_emotion'): + emotion = context['user_emotion'] + emotion_map = { + 'fear': '불안', + 'joy': '기쁨', + 'sadness': '슬픔', + 'anger': '분노', + 'surprise': '놀람', + 'disgust': '혐오', + 'trust': '신뢰', + 'neutral': '평온' + } + emotion_kr = emotion_map.get(emotion, emotion) + + prompt += f"\n\n[참고] 사용자의 현재 감정 상태: {emotion_kr}" + prompt += f"\n이 감정을 고려하여 공감적이고 적절한 응답을 제공해주세요." +``` + +### 4단계: 응답에 감정 정보 포함 (디버깅용) + +**응답 형식**: +```python +result = { + "success": True, + "content": final_content, + "model_used": llm_response.model_used, + "emotion_detected": user_emotion, # 추가 + "emotion_confidence": emotion_confidence # 추가 +} +``` + +--- + +## 테스트 계획 + +### 테스트 케이스 + +1. **불안 (fear)**: + - 입력: "요즘 회사가 걱정돼요..." + - 기대: 위로와 안정감 있는 응답 + +2. **기쁨 (joy)**: + - 입력: "오늘 승진했어요!" + - 기대: 축하와 긍정적인 응답 + +3. **슬픔 (sadness)**: + - 입력: "실패해서 너무 속상해요" + - 기대: 공감과 위로의 응답 + +4. **중립 (neutral)**: + - 입력: "날씨가 어때요?" + - 기대: 일반적인 정보 제공 + +### 검증 방법 + +```bash +# 로그 확인 +docker logs rb8001 --tail 100 | grep -E "Emotion detected|user_emotion" + +# 응답 확인 +# Slack에서 대화 → 로그에서 감정 정보 확인 +``` + +--- + +## 향후 확장 (Phase 3.5) + +### reason_with_emotion() 통합 + +**적용 시나리오**: 의사결정 지원 + +**예시**: +```python +# 사용자: "이 투자 어떻게 생각하세요?" +# 감정: fear (불안) + +# 1. LLM이 증거 생성 +evidences = [ + {"type": "위험", "content": "시장 변동성", "prior_likelihood": 0.6}, + {"type": "긍정", "content": "성장 가능성", "prior_likelihood": 0.5} +] + +# 2. 감정 기반 조정 +adjusted, explanation = reasoner.reason_with_emotion("fear", evidences) +# 위험 0.6 → 0.78 (+30%) + +# 3. 조정된 증거로 최종 응답 +``` + +--- + +## 성능 영향 + +### 추가 처리 시간 +- 감정 분석 API 호출: ~50-100ms +- skill-embedding 서비스 응답 시간 + +### 완화 방법 +- 비동기 호출 (await) +- 타임아웃 설정 (10초) +- 실패 시 graceful degradation + +--- + +## 롤백 방법 + +### 환경변수 비활성화 +```bash +USE_EMOTION_ANALYSIS=false +docker compose down && docker compose up -d +``` + +--- + +## 일정 + +### 즉시 (오늘) +- [x] 통합 계획 수립 +- [ ] 환경변수 추가 +- [ ] Router 코드 수정 +- [ ] 테스트 및 검증 + +### 내일 (2025-10-17) +- [ ] 실전 데이터 수집 +- [ ] 감정 분석 정확도 확인 + +### 향후 (Phase 3.5) +- [ ] reason_with_emotion() 통합 (의사결정 지원) +- [ ] 감정 기반 추천 시스템 +- [ ] 베이지안 학습 (피드백 기반) + +--- + +## 결론 + +**선택한 방식**: 감정 컨텍스트 전달 (방식 2) + +**이유**: +- 간단하고 실용적 +- 모든 대화에 적용 가능 +- LLM의 자연어 이해 능력 활용 +- 점진적 확장 가능 + +**다음 단계**: Router에 감정 분석 코드 추가 diff --git a/troubleshooting/251016_emotion_classifier_router_integration.md b/troubleshooting/251016_emotion_classifier_router_integration.md new file mode 100644 index 0000000..be85446 --- /dev/null +++ b/troubleshooting/251016_emotion_classifier_router_integration.md @@ -0,0 +1,387 @@ +# 감정 분류기 Router 통합 완료 + +**날짜**: 2025-10-16 +**작성자**: Claude (51124 서버 전담) +**커밋**: rb8001 413b1e0 +**관련 계획**: plans/251016_emotion_integration_plan.md + +--- + +## 목표 + +Phase 3 감정 온톨로지의 EmotionClassifier를 Router에 통합하여 사용자 감정을 파악하고 LLM에 전달. + +--- + +## 구현 내용 + +### 1. 환경변수 추가 + +**파일**: `rb8001/app/core/config.py` + +```python +# Ontology Configuration (Phase 3) +USE_ETHICS_CHECK: bool = os.getenv("USE_ETHICS_CHECK", "false").lower() == "true" +USE_EMOTION_ANALYSIS: bool = os.getenv("USE_EMOTION_ANALYSIS", "false").lower() == "true" +``` + +**기본값**: `false` (비활성화) +**목적**: 프로덕션 안전성 확보 (테스트 후 활성화) + +### 2. Router에 감정 분석 통합 + +**파일**: `rb8001/app/router/router.py` +**위치**: `_call_internal_llm()` 메서드 (LLM 호출 전) + +```python +# Phase 3: 감정 분석 (옵션) +if settings.USE_EMOTION_ANALYSIS: + try: + from app.core.emotion.emotion_classifier import get_classifier + emotion_classifier = get_classifier() + + emotion_result = await emotion_classifier.predict_async(message) + user_emotion = emotion_result['top_label'] + emotion_confidence = emotion_result['top_p'] + + # context에 추가 + if context is None: + context = {} + context['user_emotion'] = user_emotion + context['emotion_confidence'] = emotion_confidence + + logger.info(f"Emotion detected: {user_emotion} (confidence: {emotion_confidence:.2f})") + + except Exception as e: + logger.error(f"Emotion analysis failed: {e}") +``` + +**핵심 특징**: +- **LLM 호출 전 실행**: 사용자 메시지에서 감정 분석 +- **context 전달**: `user_emotion`, `emotion_confidence` 추가 +- **Graceful degradation**: 실패 시 에러 로그만 출력, 서비스 계속 + +### 3. 통합 흐름 + +``` +사용자 메시지 + ↓ +Router.route_message() + ↓ +_call_internal_llm() + ↓ +[Phase 3] Emotion Analysis ✅ + ├─ skill-embedding API 호출 + ├─ 7개 감정 분류 (fear, joy, sadness, anger, surprise, disgust, trust) + ├─ context에 감정 정보 추가 + └─ INFO 로그 출력 + ↓ +LLM Service (context 활용) + ├─ 감정 기반 프롬프트 조정 + └─ 공감적 응답 생성 + ↓ +[Phase 3] Ethics Check ✅ + └─ 윤리 확인 + ↓ +최종 응답 +``` + +--- + +## 테스트 방법 + +### 환경 준비 + +1. **.env 파일 수정** (수동 작업 필요): +```bash +# 감정 분석 활성화 +USE_EMOTION_ANALYSIS=true +``` + +2. **Docker 재시작**: +```bash +cd /home/admin/ivada_project/rb8001 +docker compose down && docker compose up -d +``` + +3. **skill-embedding 서비스 확인**: +```bash +curl http://localhost:8015/health +# 또는 +docker ps | grep skill-embedding +``` + +### 테스트 실행 + +**테스트 스크립트**: `rb8001/tests/test_emotion_integration.py` + +```bash +# Docker 외부에서 실행 (API 호출 방식) +cd /home/admin/ivada_project/rb8001 +python3 tests/test_emotion_integration.py +``` + +**테스트 케이스**: +1. **불안 (fear)**: "요즘 회사가 너무 걱정돼요... 실직할까봐 두려워요" +2. **기쁨 (joy)**: "오늘 승진했어요! 정말 기쁘고 신나요!" +3. **슬픔 (sadness)**: "프로젝트가 실패했어요... 너무 속상하고 우울해요" + +### 로그 확인 + +```bash +# 실시간 로그 모니터링 +docker logs rb8001 --tail 100 -f | grep -iE "emotion" + +# 감정 감지 로그 확인 +docker logs rb8001 --tail 100 | grep "Emotion detected" +``` + +**정상 로그 예시**: +``` +{"time":"2025-10-16 15:50:12,345","level":"INFO","module":"app.router.router","msg":"Emotion detected: fear (confidence: 0.78)"} +``` + +**에러 로그 예시** (skill-embedding 미작동): +``` +{"time":"2025-10-16 15:50:12,345","level":"ERROR","module":"app.router.router","msg":"Emotion analysis failed: Connection refused"} +``` + +--- + +## 성능 영향 + +### 추가 처리 시간 +- **감정 분석 API 호출**: ~50-100ms +- **skill-embedding 서비스 응답**: HTTP 요청 + 모델 추론 +- **총 응답 시간 증가**: < 10% + +### 완화 방법 +- **비동기 호출**: `predict_async()` 사용 +- **타임아웃**: 10초 설정 (httpx.AsyncClient) +- **Graceful degradation**: 실패 시 서비스 계속 작동 + +--- + +## 현재 상태 + +### Phase 3 통합 현황 + +| 구성 요소 | 상태 | 환경변수 | 비고 | +|----------|------|---------|-----| +| Ethics Check | ✅ 활성화 | USE_ETHICS_CHECK=true | 운영 중 | +| Emotion Analysis | ✅ 구현 | USE_EMOTION_ANALYSIS=false | 테스트 대기 | +| reason_with_emotion() | 📝 계획 | - | Phase 3.5 | + +### 감정-윤리 온톨로지 통합 + +``` +Phase 1: Coldmail (11 규칙) ✅ 활성화 +Phase 2: Memory (ChromaDB + Neo4j) ✅ 활성화 +Phase 3: Ethics (6 제약) ✅ 활성화 +Phase 3: Emotion (7 감정) ✅ 구현 (비활성화) +``` + +--- + +## 활성화 계획 + +### 즉시 가능 (테스트 완료 후) + +1. **.env 수정**: +```bash +USE_EMOTION_ANALYSIS=true +``` + +2. **Docker 재시작**: +```bash +docker compose down && docker compose up -d +``` + +3. **실시간 모니터링**: +```bash +docker logs rb8001 --tail 100 -f | grep -iE "emotion|error" +``` + +### 검증 항목 + +- [ ] skill-embedding 서비스 정상 작동 +- [ ] 감정 감지 로그 출력 확인 +- [ ] LLM 응답에 감정 반영 확인 +- [ ] 응답 시간 증가 < 10% 확인 +- [ ] 에러 발생 시 graceful degradation 확인 + +--- + +## 롤백 방법 + +### 방법 1: 환경변수 비활성화 (즉시) + +```bash +# .env 파일 수정 +USE_EMOTION_ANALYSIS=false + +# Docker 재시작 +docker compose down && docker compose up -d +``` + +### 방법 2: Git 롤백 (통합 이전) + +```bash +cd /home/admin/ivada_project/rb8001 +git checkout 773ee66 # Phase 3 Ethics 통합 +docker compose down && docker compose up -d --build +``` + +--- + +## 향후 계획 (Phase 3.5) + +### reason_with_emotion() 통합 + +**목표**: 베이지안 우도 조정을 통한 의사결정 지원 + +**적용 시나리오**: 투자, 구매, 비교 분석 등 + +**구현 계획**: +1. 의사결정 태스크 감지 (DecisionEngine) +2. LLM이 증거(evidence) 추출 +3. `reason_with_emotion(emotion, evidences)` 호출 +4. 조정된 증거로 최종 응답 생성 + +**예시**: +```python +# 사용자: "이 투자 어떻게 생각하세요?" +# 감정: fear (불안) + +evidences = [ + {"type": "위험", "content": "시장 변동성", "prior_likelihood": 0.6}, + {"type": "긍정", "content": "성장 가능성", "prior_likelihood": 0.5} +] + +adjusted, explanation = reasoner.reason_with_emotion("fear", evidences) +# 위험 0.6 → 0.78 (+30%) +# 긍정 0.5 → 0.50 (변화 없음) +``` + +### Slack 피드백 통합 + +**목표**: 사용자 피드백 기반 베이지안 학습 + +**구현 계획**: +1. 감정 판정 정확도 피드백 버튼 +2. 사용자 수정 수집 +3. 베이지안 업데이트 (prior 조정) +4. 모델 재학습 + +--- + +## 교훈 + +### 1. 점진적 통합의 중요성 + +**접근**: +1. EmotionClassifier 구현 → 독립 테스트 +2. Router 통합 → USE_EMOTION_ANALYSIS=false (비활성화) +3. 테스트 완료 → USE_EMOTION_ANALYSIS=true (활성화) + +**교훈**: 새 기능은 비활성화 상태로 배포 후 검증 + +### 2. Context 기반 정보 전달 + +**장점**: +- LLM Service와 느슨한 결합 +- context에 추가 정보 자유롭게 전달 +- LLM이 감정 정보를 자연스럽게 활용 + +**교훈**: 복잡한 API 인터페이스보다 context dict 활용 + +### 3. Graceful Degradation + +**구현**: +- skill-embedding 실패 시 → 에러 로그만 출력 +- 감정 정보 없이도 LLM 응답 생성 +- 사용자는 서비스 중단 없음 + +**교훈**: 외부 의존성은 항상 실패 가능성 고려 + +### 4. 두 감정 분석 시스템의 공존 + +**현재 상황**: +- Router: EmotionClassifier (skill-embedding) +- LLM Service: EmotionAwareLLM (내장) + +**향후 개선**: +- Router에서 한 번만 분석 +- 결과를 context에 추가 +- LLM Service는 context 활용 + +**교훈**: 중복 제거 가능하지만 우선 작동 확인 후 최적화 + +--- + +## 관련 파일 + +### 구현 +- `rb8001/app/core/config.py`: USE_EMOTION_ANALYSIS 환경변수 +- `rb8001/app/router/router.py`: 감정 분석 통합 (322-341줄) +- `rb8001/app/core/emotion/emotion_classifier.py`: EmotionClassifier (기존) + +### 테스트 +- `rb8001/tests/test_emotion_integration.py`: API 기반 통합 테스트 + +### 문서 +- `DOCS/plans/251016_emotion_integration_plan.md`: 통합 계획 +- `DOCS/troubleshooting/251016_phase3_ethics_activation_complete.md`: Phase 3 활성화 + +--- + +## 다음 단계 + +### 즉시 수행 + +- [ ] **skill-embedding 서비스 확인**: `docker ps | grep skill-embedding` +- [ ] **환경변수 설정**: `.env`에 `USE_EMOTION_ANALYSIS=true` (수동) +- [ ] **Docker 재시작**: `docker compose down && docker compose up -d` +- [ ] **테스트 실행**: `python3 tests/test_emotion_integration.py` +- [ ] **로그 모니터링**: 감정 감지 정상 작동 확인 + +### 내일 검증 (2025-10-17) + +- [ ] **실전 데이터 수집**: Slack 대화에서 감정 감지 확인 +- [ ] **응답 품질 평가**: 감정 기반 응답이 더 공감적인지 확인 +- [ ] **성능 측정**: 응답 시간 증가 < 10% 확인 + +### 향후 개선 + +- [ ] **중복 제거**: EmotionAwareLLM과 통합 +- [ ] **reason_with_emotion() 통합**: 의사결정 지원 +- [ ] **Slack 피드백**: 베이지안 학습 + +--- + +## 결론 + +✅ **감정 분류기 Router 통합 완료** + +**2025-10-16, 로빙의 감정 인식 시스템 준비 완료** + +### 핵심 성과 + +1. **감정 인식**: skill-embedding 기반 7개 감정 분류 +2. **Context 전달**: LLM에 감정 정보 자동 전달 +3. **Graceful degradation**: 실패 시에도 서비스 정상 작동 +4. **환경변수 제어**: 즉시 활성화/비활성화 가능 + +### 최종 상태 + +``` +Phase 1: Coldmail (11 규칙) ✅ 활성화 (운영) +Phase 2: Memory (ChromaDB + Neo4j) ✅ 활성화 (준비) +Phase 3: Ethics (6 제약) ✅ 활성화 (운영) +Phase 3: Emotion (7 감정) ✅ 구현 (테스트 대기) + +총 28개 규칙 + 7개 감정 = 35개 지식 구성 요소 +로빙의 온톨로지 기반 AI 시스템 확장 완료 +``` + +**다음 단계**: USE_EMOTION_ANALYSIS=true 활성화 및 실전 검증