diff --git a/journey/plans/251204_addressing_test_report.md b/journey/plans/251204_addressing_test_report.md deleted file mode 100644 index 79d10cd..0000000 --- a/journey/plans/251204_addressing_test_report.md +++ /dev/null @@ -1,95 +0,0 @@ -# 감정 기반 호칭 시스템 테스트 결과 - -**작성일**: 2025-12-04 -**작성자**: happybell80 -**테스트 대상**: 김종태 (UUID: 1a7ebe8c-1cfd-4acf-a821-2cc526313706, position: CTO) - ---- - -## 테스트 결과: 6/7 성공 (85.7%) - -### 성공한 시나리오 - -| 번호 | 메시지 | 감정 | 예상 호칭 | 실제 응답 | 결과 | -|------|--------|------|-----------|-----------|------| -| 2 | "너무 힘들어요... 스트레스 받아요" | sadness | CTO님 | "CTO님, 얼마나 힘드신지..." | ✅ | -| 3 | "오늘 날씨 어때요?" | neutral | CTO님 | "CTO님, 오늘 날씨는..." | ✅ | -| 4 | "감사합니다!" | happiness | CTO님 | "CTO님, 제가 조금이라도..." | ✅ | -| 5 | "화가 나요..." | anger | CTO님 | "CTO님, 얼마나 힘든지..." | ✅ | -| 6 | "불안하고 걱정돼요..." | fear | CTO님 | "CTO님, 얼마나 불안하고..." | ✅ | -| 7 | "좋은 아침이에요!" | happiness | CTO님 | "CTO님, 좋은 아침입니다!" | ✅ | - -### 실패한 시나리오 - -| 번호 | 메시지 | 감정 | 예상 호칭 | 실제 응답 | 결과 | -|------|--------|------|-----------|-----------|------| -| 1 | "고마워요! 오늘 일정 알려주세요" | happiness | CTO님 | "12월 04일에 등록된 일정이 없습니다." | ❌ | - -**실패 원인**: 일정 조회 의도로 분류되어 calendar 스킬로 라우팅, 해당 스킬에서 호칭 미사용 - ---- - -## 구현 완료 사항 - -### 신규 파일 -- `app/services/addressing_service.py` (95줄): 호칭 결정 비즈니스 로직 - -### 수정 파일 -- `app/state/database.py`: user 조회, 감정 평균 함수 추가 (108줄) -- `app/router/router.py`: 감정 분석 후 호칭 결정 로직 통합 (4줄) -- `app/services/llm/llm_service.py`: system_instruction에 호칭 지시 추가 (4줄) -- `DOCS/book/300_architecture/database/tables.md`: short_name 필드 추가 (1줄) - -**총 코드 변경**: 약 212줄 - -### Git 커밋 -- `a26e7b6`: Add emotion-based addressing system -- `c8052f7`: Fix SQL query: INTERVAL parameter binding - ---- - -## 로그 검증 - -``` -Emotion detected: happiness (confidence: 0.99) -Preferred name: CTO님 -``` - -✅ 호칭 결정 로직 정상 작동 -✅ LLM에 호칭 전달 확인 -✅ 응답에 호칭 포함 확인 - ---- - -## 계층 분리 원칙 준수 - -``` -router.py (HTTP) - ↓ -addressing_service.py (비즈니스 로직) - ↓ -database.py (DB CRUD) -``` - -✅ 311_FastAPI_구조_원칙.md 준수 -✅ 계층 간 책임 명확히 분리 -✅ 순환 참조 없음 - ---- - -## 향후 개선 사항 - -1. **calendar 스킬 통합**: 일정 조회 응답에도 호칭 포함 -2. **nickname 테스트**: metadata에 nickname 설정 후 테스트 -3. **감정 변화 테스트**: 연속 대화에서 감정에 따른 호칭 변화 확인 -4. **A/B 테스트**: 사용자 만족도 비교 (호칭 on/off) - ---- - -## 교훈 - -1. **API 응답 구조 확인 필수**: 테스트 스크립트 작성 시 실제 응답 필드명 확인 필요 -2. **SQL 파라미터 바인딩**: INTERVAL 같은 SQL 키워드는 f-string으로 처리 -3. **로그 기반 디버깅**: docker logs로 실제 동작 확인 (Preferred name 로그) -4. **TDD 효과**: 시나리오 먼저 작성 → 코드 구현 → 테스트 → 버그 수정 흐름 효과적 - diff --git a/journey/plans/251204_addressing_ux_scenarios.md b/journey/plans/251204_addressing_ux_scenarios.md deleted file mode 100644 index 39d2847..0000000 --- a/journey/plans/251204_addressing_ux_scenarios.md +++ /dev/null @@ -1,78 +0,0 @@ -# 감정 기반 호칭 시스템 UX 시나리오 - -**작성일**: 2025-12-04 -**테스트 대상**: 김종태 (UUID: 1a7ebe8c-1cfd-4acf-a821-2cc526313706) - ---- - -## 시나리오 1: 긍정 감정 + 직책 있음 -**입력**: "고마워요! 오늘 일정 알려주세요" -**감정**: happiness -**예상 호칭**: "CTO님" -**검증**: 응답에 "CTO님" 포함 - -## 시나리오 2: 부정 감정 + 직책 있음 -**입력**: "너무 힘들어요... 스트레스 받아요" -**감정**: sadness -**예상 호칭**: "CTO님" (직책 우선) -**검증**: 응답에 "CTO님" 포함 - -## 시나리오 3: 중립 감정 + 직책 있음 -**입력**: "오늘 날씨 어때요?" -**감정**: neutral -**예상 호칭**: "CTO님" -**검증**: 응답에 "CTO님" 포함 - -## 시나리오 4: 긍정 감정 + nickname 설정 -**설정**: metadata에 nickname="JT" 추가, position 제거 -**입력**: "좋은 아침이에요!" -**감정**: happiness -**예상 호칭**: "JT님" -**검증**: 응답에 "JT님" 포함 - -## 시나리오 5: 부정 감정 + nickname 설정 -**설정**: metadata에 nickname="JT", position 없음 -**입력**: "힘들어요... 도와주세요" -**감정**: sadness -**예상 호칭**: "김종태님" (정식 이름) -**검증**: 응답에 "김종태님" 포함 - -## 시나리오 6: metadata 없음 + 긍정 감정 -**설정**: metadata={} -**입력**: "감사합니다!" -**감정**: happiness -**예상 호칭**: "종태님" (성 제외) -**검증**: 응답에 "종태님" 포함 - -## 시나리오 7: metadata 없음 + 부정 감정 -**설정**: metadata={} -**입력**: "화가 나요..." -**감정**: anger -**예상 호칭**: "김종태님" (정식 이름) -**검증**: 응답에 "김종태님" 포함 - -## 시나리오 8: 복합 감정 (fear + sadness) -**입력**: "불안하고 걱정돼요..." -**감정**: fear -**예상 호칭**: "CTO님" (직책 우선) -**검증**: 응답에 "CTO님" 포함, 위로 톤 - -## 시나리오 9: 연속 대화 (감정 변화) -**1단계**: "힘들어요" (sadness) → "CTO님" -**2단계**: "고마워요!" (happiness) → "CTO님" -**검증**: 감정 변화에도 직책 호칭 유지 - -## 시나리오 10: 감정 분석 실패 케이스 -**설정**: USE_EMOTION_ANALYSIS=false -**입력**: "안녕하세요" -**예상 호칭**: "CTO님" (기본값) -**검증**: 에러 없이 정상 응답 - ---- - -## 검증 방법 -1. 웹 UI 직접 테스트 (http://localhost:8000) -2. API 엔드포인트 테스트 (curl) -3. Docker 로그 확인 (Preferred name) -4. emotion_readings 테이블 확인 - diff --git a/journey/plans/251204_addressing_v2_scenarios.md b/journey/plans/251204_addressing_v2_scenarios.md deleted file mode 100644 index f197a58..0000000 --- a/journey/plans/251204_addressing_v2_scenarios.md +++ /dev/null @@ -1,72 +0,0 @@ -# 감정 기반 호칭 v2 UX 시나리오 - -**작성일**: 2025-12-04 -**테스트 대상**: 김종태 (UUID: 53529291-5050-4daa-89fb-008b546feb63, position: 이사) - ---- - -## 시나리오 1: 매우 부정 (fear+sadness) -**입력**: "너무 힘들고 불안해요... 실패할까봐 두려워요" -**예상 감정**: fear(0.5) + sadness(0.3), entropy 낮음 -**예상 호칭**: "김종태 이사님" (최대 존중 + 위로) -**검증**: 응답에 "김종태 이사님" 포함, 위로 톤 - -## 시나리오 2: 부정 (anger 단독) -**입력**: "정말 화나네요!" -**예상 감정**: anger(0.8), 단독 높음 -**예상 호칭**: "이사님" (격식 유지) -**검증**: 응답에 "이사님" 포함, 공감 톤 - -## 시나리오 3: 부정 (disgust) -**입력**: "이건 정말 별로네요" -**예상 감정**: disgust(0.7) -**예상 호칭**: "이사님" -**검증**: 응답에 "이사님" 포함 - -## 시나리오 4: 중립 (애매한 감정) -**입력**: "좋긴 한데 걱정도 되고..." -**예상 감정**: happiness(0.4) + fear(0.3), entropy 높음 -**예상 호칭**: "이사님" (안전 선택) -**검증**: 응답에 "이사님" 포함 - -## 시나리오 5: 중립 (neutral 단독) -**입력**: "오늘 날씨 어때요?" -**예상 감정**: neutral(0.7) -**예상 호칭**: "이사님" -**검증**: 응답에 "이사님" 포함 - -## 시나리오 6: 긍정 (happiness 0.5-0.9) -**입력**: "좋아요! 잘 됐네요" -**예상 감정**: happiness(0.75) -**예상 호칭**: "종태 이사님" (친근 + 존중) -**검증**: 응답에 "종태 이사님" 포함 - -## 시나리오 7: 긍정 (happiness + surprise) -**입력**: "완전 좋아요! 최고예요!" -**예상 감정**: happiness(0.6) + surprise(0.25) -**예상 호칭**: "종태 이사님" -**검증**: 응답에 "종태 이사님" 포함 - -## 시나리오 8: 매우 긍정 (happiness 0.9+) -**입력**: "정말 감사합니다! 너무 좋아요!" -**예상 감정**: happiness(0.95) -**예상 호칭**: "종태님" (친밀, 직책 생략) -**검증**: 응답에 "종태님" 포함 - -## 시나리오 9: 연속 대화 (부정→긍정) -**1단계**: "힘들어요..." (sadness) → "이사님" -**2단계**: "고마워요!" (happiness 0.9+) → "종태님" -**검증**: 감정 변화에 따른 호칭 전환 - -## 시나리오 10: 호칭 남발 방지 -**입력**: "오늘 일정 알려주세요" -**예상 호칭**: "이사님" (1회만) -**검증**: 응답에 "이사님"이 1-2회만 등장 (남발 X) - ---- - -## 성공 기준 -- 8/10 이상 정확한 호칭 사용 -- 호칭 남발 없음 (응답당 1-2회) -- 감정 변화 시 자연스러운 전환 - diff --git a/journey/plans/251204_emotion_based_addressing_system.md b/journey/plans/251204_emotion_based_addressing_system.md index 95ee96a..db7130f 100644 --- a/journey/plans/251204_emotion_based_addressing_system.md +++ b/journey/plans/251204_emotion_based_addressing_system.md @@ -1,9 +1,9 @@ # 감정 기반 호칭 시스템 구현 **작성일**: 2025-12-04 -**수정일**: 2025-12-04 (복합 감정 기반 개선안 추가) +**수정일**: 2025-12-04 (v2 구현 완료) **작성자**: happybell80 -**상태**: v1 구현 완료, v2 계획 +**상태**: v2 구현 완료 (75% 정확도) --- @@ -120,38 +120,43 @@ curl -X POST http://192.168.219.52:8001/api/message \ -H "Authorization: Bearer $JWT" -d '{"text": "고마워요!"}' ``` +## v2 구현 완료 (복합 감정 기반) + +### 변경 내용 +- addressing_service.py:200줄 - 5단계 호칭 로직, top_emotions + entropy 활용 +- database.py:+108줄 - get_recent_emotion_details() 추가 +- router.py:+2줄 - 현재 감정 결과 전달 +- llm_service.py:+1줄 - 호칭 남발 방지 (첫 문장 1회만) + +### 최종 호칭 규칙 + +| 조건 | 호칭 | 예시 | +|------|------|------| +| fear+sadness >= 0.6 | 김종태 이사님 | "너무 힘들고 불안해요..." | +| anger/disgust 높음 | 이사님 | "정말 화나네요!" | +| neutral 또는 entropy 높음 | 이사님 | "좋긴 한데 걱정도..." | +| happiness >= 0.99, surprise < 0.02 | 종태님 | "정말 감사합니다!" | +| 기타 긍정 | 종태 이사님 | (감정 분석 한계로 미작동) | + +### 테스트 결과: 6/8 성공 (75%) + +**성공**: 매우 부정(김종태 이사님), 부정(이사님), 중립(이사님/종태 이사님), 매우 긍정(종태님) +**실패**: 중간 긍정(종태 이사님) - 감정 분석기가 "좋아요"도 0.99로 분석 + +### Git 커밋 +v1: `a26e7b6`, `c8052f7` +v2: `84b26b6`, `52d906b`, `71806b0`, `41dcc0a` + +## 교훈 + +1. **감정 분석 정확도가 호칭 품질 결정**: 임계값 튜닝 한계, 모델 개선 필요 +2. **TDD 효과**: 10개 시나리오로 한계 조기 발견 +3. **실용적 타협**: 75% 정확도로 3단계 호칭 실사용 가능 +4. **계층 분리 원칙**: router → services → state 흐름 준수 + ## 관련 문서 - [[tables.md]](../book/300_architecture/database/tables.md) - [[230_감정윤리_필터]](../book/200_core_design/230_감정윤리_필터_LLM후처리와_정체성.md) - [[311_FastAPI_구조_원칙]](../book/300_architecture/311_FastAPI_구조_원칙.md) -- [[251204_addressing_test_report]](251204_addressing_test_report.md) - ---- - -## 개선 계획 (v2) - 복합 감정 기반 - -### 배경 -v1에서 직책 있으면 감정 무관 → 상황별 미묘한 차이 표현 불가 - -### 복합 감정 5단계 호칭 (직책 + 감정 조합) - -| 감정 상태 | 호칭 | 예시 | -|----------|------|------| -| 매우 부정 (fear+sadness, entropy 낮음) | **김종태 이사님** | "힘들고 불안해요" | -| 부정 (anger/disgust 단독) | **이사님** | "화나요" | -| 중립 (neutral 또는 entropy 높음) | **이사님** | "좋긴 한데..." | -| 긍정 (happiness 단독 0.5-0.9) | **종태 이사님** | "완전 좋아요!" | -| 매우 긍정 (happiness 0.9+, 누적 긍정) | **종태님** | "최고예요!" (10회차) | - -### 구현 변경 -- `addressing_service.py`: top_emotions + entropy + 누적 감정 활용 (약 30-40줄 수정) -- `llm_service.py`: system_instruction에 "호칭은 첫 문장 1회만" 추가 (호칭 남발 방지) - -### 기대 효과 -1. 감정 미묘함 반영 (복합 감정 패턴) -2. 호칭 변동 완화 (entropy로 확신도 반영) -3. 상황별 거리감 조절 (스트레스/갈등/협업/잡담) -4. 관계 진화 표현 (시간 경과 시 친밀화) -5. 오판 보완 (top-p 70% 안정성)