4.0 KiB
4.0 KiB
감정 기반 호칭 시스템 구현
작성일: 2025-12-04
작성자: happybell80
상태: 계획
배경 및 목표
- 현재: 모든 사용자를 "사용자님" 또는
user.name으로 획일적 호칭 - 문제: 감정 상태/상황 무시,
metadata(nickname, position) 미활용 - 목표: 감정 기반 호칭 동적 변경으로 공감 능력 강화, 한국 직장 문화 존중 표현
조사 결과 (웹 검색)
한국어 호칭 원칙:
- 친밀한 관계: 별명/애칭 사용
- 공식적/부정적 상황: 정식 이름 사용
- 출처: 한국어 호칭 연구, UX 라이팅 전략
AI 감정 반응:
- 챗GPT emotional rebound 효과: 부정 → 위로, 긍정 → 친근
- 출처: 프랑크 바르돌 연구 (m.etnews.com)
직장 문화: 직책 호칭 최우선 (대표님, 이사님)
설계 결정
방식: 휴리스틱 규칙 (Python)
이유: 일관성, 속도, 예측 가능성, 제어 용이
LLM 역할: 결정된 호칭 자연스럽게 사용만
호칭 결정 규칙
| 조건 | 호칭 |
|---|---|
metadata->>'position' 있음 |
"대표님", "이사님" (감정 무관) |
| 긍정 감정 + position 없음 | metadata->>'nickname' → "joann님" |
| 부정 감정 + position 없음 | user.name → "이고은님" |
| nickname 없음 | user.name 성 제외 → "고은님" |
긍정 감정: happiness, surprise, neutral
부정 감정: fear, anger, sadness, disgust
감정 소스: emotion_readings 최근 10분 평균 (현재 메시지 가중치 2배)
구현 (계층 분리 원칙 준수)
계층 구조
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:264-283
수정: 감정 분석 후 addressing_service 호출
from app.services.addressing_service import get_preferred_name
preferred_name = await get_preferred_name(user_id, user_emotion)
context['preferred_name'] = preferred_name
4. llm_service.py:131-132
수정: system_instruction에 호칭 지시
preferred_name = enhanced_context.get('preferred_name', '사용자')
system_instruction += f"사용자를 '{preferred_name}'으로 호칭하세요. "
5. tables.md
추가: user.metadata 컬럼 문서화
| metadata | JSONB | YES | nickname, position, short_name, preferences |
테스트 시나리오
- 긍정+직책: "고마워요" (happiness) + position="대표" → "대표님"
- 긍정+no직책: "좋은 아침" (happiness) + nickname="joann" → "joann님"
- 부정+no직책: "힘들어요" (sadness) + name="이고은" → "이고은님"
- 중립: "날씨는?" (neutral) + name="김종태" → "종태님"
검증
로그:
docker logs rb8001 --tail 100 | grep "Preferred name"
DB:
-- 최근 10분 감정 평균
SELECT user_id, AVG((probs->>'happiness')::float) FROM emotion_readings
WHERE created_at > NOW() - INTERVAL '10 minutes' GROUP BY user_id;
API:
curl -X POST http://192.168.219.52:8001/api/message \
-H "Authorization: Bearer $JWT" -d '{"text": "고마워요!"}'