DOCS/journey/troubleshooting/251204_emotion_based_addressing_system.md
Claude-51124 0e385b24b9 Fix 312 principles & move completed plan to troubleshooting
- Move: plans/251204_emotion_based_addressing_system.md → troubleshooting/
- Update: 312 원칙 명확화 (plans vs troubleshooting 구분)
- Add: 시나리오/테스트 별도 파일 금지 명시
- Follow: 구현 완료 시 troubleshooting 이동 규칙 준수
2025-12-04 17:13:45 +09:00

145 lines
5.4 KiB
Markdown
Raw Permalink Blame History

This file contains invisible Unicode characters

This file contains invisible Unicode characters that are indistinguishable to humans but may be processed differently by a computer. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

# 감정 기반 호칭 시스템 구현
**작성일**: 2025-12-04
**수정일**: 2025-12-04 (v2 구현 완료)
**작성자**: happybell80
**관련 파일**: `services/addressing_service.py`, `state/database.py`, `router/router.py`
---
## 배경 및 목표
- 현재: 모든 사용자를 "사용자님" 또는 `user.name`으로 획일적 호칭
- 문제: 감정 상태/상황 무시, `metadata` (nickname, position) 미활용
- 목표: 감정 기반 호칭 동적 변경으로 공감 능력 강화, 한국 직장 문화 존중 표현
## 조사 결과 (웹 검색)
**한국어 호칭 원칙**:
- 친밀한 관계: 별명/애칭 사용
- 공식적/부정적 상황: 정식 이름 사용
- 출처: 한국어 호칭 연구, UX 라이팅 전략
**AI 감정 반응**:
- 챗GPT emotional rebound 효과: 부정 → 위로, 긍정 → 친근
- 출처: 프랑크 바르돌 연구 (m.etnews.com)
**직장 문화**: 직책 호칭 최우선 (대표님, 이사님)
## 설계 결정
### 방식: 휴리스틱 규칙 (Python)
이유: 일관성, 속도, 예측 가능성, 제어 용이
LLM 역할: 결정된 호칭 자연스럽게 사용만
### 호칭 결정 규칙 (v1 - 구현 완료)
| 조건 | 호칭 |
|------|------|
| `metadata->>'position'` 있음 | "대표님", "이사님" |
| 긍정 감정 + position 없음 | `metadata->>'nickname'` → "joann님" |
| 부정 감정 + position 없음 | `user.name` → "이고은님" |
| nickname 없음 | `user.name` 성 제외 → "고은님" |
**긍정 감정**: happiness, surprise, neutral
**부정 감정**: fear, anger, sadness, disgust
**감정 소스**: emotion_readings 최근 10분 평균 (현재 메시지 가중치 2배)
**v1 문제점**: 직책 있으면 감정 무관 → 상황별 미묘한 차이 표현 불가
## 구현 (계층 분리 원칙 준수)
### 계층 구조
```
router.py (감정 분석 후)
services/addressing_service.py (신규, 호칭 결정 비즈니스 로직)
state/database.py (DB CRUD만)
```
### 1. services/addressing_service.py (신규)
**기능**: 호칭 결정 비즈니스 로직
- `get_preferred_name(user_id: str, current_emotion: str) -> str`
- state 호출: user 정보, 최근 감정 조회
- 호칭 규칙 적용 (직책 → 긍정감정=nickname → 부정감정=정식이름)
- 약 100줄 예상
### 2. state/database.py
**기존 함수 확인 후**:
- 없으면 추가: `get_user_basic_info(user_id)` - name, metadata 반환
- 없으면 추가: `get_recent_emotions(user_id, minutes=10)` - 감정 평균
- DB CRUD만, 비즈니스 로직 금지
### 3. router.py:282-286
**수정**: addressing_service 호출, 현재 감정 결과 전달
### 4. llm_service.py:134-135
**수정**: system_instruction에 호칭 지시, 호칭 남발 방지 (첫 문장 1회만)
### 5. tables.md:44
**추가**: user.metadata 컬럼 (nickname, position, short_name)
## 테스트 시나리오
1. **긍정+직책**: "고마워요" (happiness) + position="대표" → "대표님"
2. **긍정+no직책**: "좋은 아침" (happiness) + nickname="joann" → "joann님"
3. **부정+no직책**: "힘들어요" (sadness) + name="이고은" → "이고은님"
4. **중립**: "날씨는?" (neutral) + name="김종태" → "종태님"
## 검증
- 로그: `docker logs rb8001 | grep "Preferred name"`
- DB: emotion_readings 최근 10분 평균 확률 조회
- API: /api/message 엔드포인트로 JWT 인증 테스트
## 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`
## 교훈
### 원인
v1에서 직책 있으면 감정 무관 호칭 UX 피드백으로 감정별 차별화 필요 발견
### 교훈
1. **모델 검증 우선**: 임계값 튜닝 감정 분석기 정확도 확인 필수 (증상 치료 vs 본질 해결)
2. **TDD 효과**: 10개 시나리오로 한계 조기 발견, 75% 정확도 수용 판단
3. **실용적 타협**: 완벽 추구보다 3단계 호칭 실사용 선택
### 원칙 준수
- 311: 계층 분리 (router services state)
- 312: 문서 통합 (plans troubleshooting 이동, 중복 문서 3개 삭제)
- 311: database.py 650줄 초과 emotion_repository.py 분리 예정
## 관련 문서
- [[tables.md]](../book/300_architecture/database/tables.md)
- [[230_감정윤리_필터]](../book/200_core_design/230_감정윤리_필터_LLM후처리와_정체성.md)
- [[311_FastAPI_구조_원칙]](../book/300_architecture/311_FastAPI_구조_원칙.md)