DOCS/plans/250808_감정시스템_현실적용_5단계_로드맵.md

12 KiB

로빙 감정 시스템 현실 적용 5단계 로드맵

작성자: happybell80 & Claude
목적: 감정 시스템 설계서를 현실적으로 구현 가능한 단계별 계획으로 구체화

핵심 원칙

  • MVP 우선: 복잡한 기능보다 작동하는 기본 기능
  • 측정 가능한 성과: 각 단계마다 명확한 KPI
  • 점진적 복잡도: 단순 → 복잡으로 진화
  • 서비스 분리: 단일 장애점 방지
  • 함수형 프로그래밍 100%: 하드코딩 0% 목표. 근거없는 하드코딩 값 절대 사용 금지
    • 모든 값은 설정 파일이나 환경변수에서 로드
    • 순수 함수 체인으로 구성
    • 상태 변경 최소화, 불변성 유지

Phase 1: 7개 감정 기본 구현 (이미 학습 완료)

목표

"이미 학습된 7개 한국어 감정 모델을 skill-embedding에 통합"

구현 범위

# AI Hub 데이터로 학습 완료된 7개 감정
EMOTIONS = [
    "fear",      # 공포 (기본정서)
    "surprise",  # 놀람 (기본정서)
    "anger",     # 분노 (기본정서)
    "sadness",   # 슬픔
    "neutral",   # 중립
    "happiness", # 행복  
    "disgust"    # 혐오
]
# 모델 성능: F1 56.3%, Temperature Scaling 1.232

# 엔트로피 계산 (7개 감정)
def calculate_entropy(probs: List[float]) -> float:
    """7개 감정 확률값으로 엔트로피 계산"""
    return -sum(p * log(p) for p in probs if p > 0)

기술 스택

  • 감정 모델: klue/bert-base 기반 → ONNX 변환 완료
  • 서비스: skill-embedding 확장 (포트 8515, /emotion 추가)
  • 저장: 기존 ChromaDB 활용 (메타데이터에 감정 추가)
  • 의사결정: 엔트로피 기반 복잡도 판단
  • 기존 코드: rb10508_micro의 memory/storage.py 재사용
  • 설정값: confidence=0.35, entropy=2.0, temperature=1.232

성능 목표

  • 응답시간: 500ms 이내
  • 정확도: 사용자 평가 3.5/5.0
  • 메모리: 200MB 이내

데이터 준비 (완료)

  • AI Hub 한국어 대화 데이터셋 38,594개 샘플
  • 7개 감정 균형 분포
  • 학습/검증/테스트 분할 완료
  • 클래스 가중치 적용

검증 방법

# 단위 테스트
pytest tests/test_basic_emotions.py

# 부하 테스트  
locust -f tests/load_test.py --users 10

# 응답시간 측정
curl -w "@curl-format.txt" http://localhost:8503/analyze

산출물

  • 7개 감정 모델 학습 완료 (training_emotion)
  • ONNX 변환 완료 (423MB)
  • skill-embedding 서비스에 /emotion 엔드포인트 추가
  • Temperature Scaling 적용 (1.232)
  • 엔트로피 계산기 구현
  • ChromaDB 메타데이터 통합
  • rb10508_micro 연동

아키텍처 결정 사항 (2025-08-12)

문제: 감정 분석을 어디에 구현할 것인가?

  • Option A: 별도 skill-emotion 서비스 (아키텍처 원칙)
  • Option B: skill-embedding에 통합 (자원 효율성)

최종 결정: skill-embedding에 통합

  • 이유: ONNX Runtime 공유, 메모리 200MB 절약, 레이턴시 감소
  • 트레이드오프: 서비스 역할 혼재 vs 실용성
  • 향후: 서비스명 변경 고려 (skill-embedding → skill-ai)

Phase 2: 성능 최적화 및 통합

목표

"ONNX 변환, 캐싱 구현, rb10508_micro 완전 통합"

최적화 전략

# LRU 캐시 적용
from functools import lru_cache

@lru_cache(maxsize=1000)
def get_emotion_embedding(text: str) -> np.ndarray:
    """자주 사용되는 텍스트의 임베딩 캐싱"""
    return model.encode(text)

# 배치 처리
async def batch_analyze(texts: List[str]):
    """여러 텍스트 동시 처리"""
    embeddings = model.encode(texts, batch_size=32)
    return [analyze_emotion(emb) for emb in embeddings]

ChromaDB 튜닝

  • 인덱스 최적화: HNSW 파라미터 조정
  • 쿼리 최적화: top-k를 10으로 제한
  • 연결 풀링: 커넥션 재사용

프로파일링

# 병목 지점 찾기
import cProfile
import pstats

cProfile.run('analyze_emotion(text)', 'profile_stats')
stats = pstats.Stats('profile_stats')
stats.sort_stats('cumulative').print_stats(10)

성능 목표

  • 응답시간: 200ms (60% 개선)
  • 동시 처리: 50 req/s
  • 캐시 적중률: 30%

산출물

  • ONNX 모델 변환 (442MB → 150MB)
  • LRU 캐시 시스템 (5분 TTL)
  • 배치 처리 API
  • ChromaDB 감정 메타데이터 인덱싱
  • 성능 모니터링 (Grafana)
  • rb10508_micro 감정 기반 응답 톤 조정

Phase 3: 감정 패턴 분석 및 개인화

목표

"장기 감정 패턴 추적, 사용자별 감정 프로파일 구축"

감정 패턴 분석

# 시간별 감정 추적
class EmotionTracker:
    def __init__(self, user_id: str):
        self.user_id = user_id
        self.history = []  # 시계열 감정 데이터
    
    def track(self, emotion_result: dict):
        """감정 결과를 시계열로 저장"""
        self.history.append({
            "timestamp": datetime.now(),
            "emotions": emotion_result["emotions"],
            "dominant": emotion_result["dominant"],
            "entropy": emotion_result["entropy"]
        })
    
    def get_pattern(self, period: str = "day"):
        """일/주/월 단위 감정 패턴 분석"""
        # 시간대별 주요 감정
        # 감정 변화 추이
        # 엔트로피 패턴
        return analyze_temporal_pattern(self.history, period)

개인화 전략

  • 사용자별 감정 프로파일 생성
  • 감정 응답 히스토리 학습
  • 개인별 감정 임계값 조정
  • 엔트로피 특이점 활용 (창발적 응답)

엔트로피 기반 의사결정

class EntropyBasedDecision:
    def __init__(self):
        self.entropy_threshold = 2.5  # 특이점 임계값
    
    def should_be_creative(self, entropy: float) -> bool:
        """높은 엔트로피일 때 창의적 응답"""
        return entropy > self.entropy_threshold
    
    def adjust_response(self, response: str, emotion_result: dict):
        """감정에 따른 응답 톤 조정"""
        if emotion_result["dominant"] == "sadness":
            return make_empathetic(response)
        elif emotion_result["dominant"] == "anger":
            return make_calm(response)
        elif self.should_be_creative(emotion_result["entropy"]):
            return make_creative(response)
        return response

성능 목표

  • 패턴 분석: 일 1회 배치 처리
  • 프로파일 업데이트: 실시간
  • 감정 히스토리: 30일 보관
  • 개인화 정확도: 70% 이상

산출물

  • 감정 패턴 분석기
  • 사용자 감정 프로파일 DB
  • 엔트로피 기반 의사결정 모듈
  • 시계열 감정 시각화
  • 개인화 응답 전략

Phase 4: 베이지안 학습 시스템

목표

"실시간 학습과 개인화된 감정 모델 구축"

베이지안 파라미터

class BayesianEmotionModel:
    def __init__(self):
        # Dirichlet 사전분포 (9개 감정)
        self.emotion_prior = np.ones(9)
        
        # Beta 분포 (저장 결정)
        self.save_alpha = 1
        self.save_beta = 1
        
        # Gamma 분포 (응답 길이)
        self.length_k = 2
        self.length_theta = 50
    
    def update_posterior(self, observation):
        """관측값으로 사후분포 업데이트"""
        self.emotion_prior += observation['emotion_counts']
        
        if observation['saved']:
            self.save_alpha += 1
        else:
            self.save_beta += 1
            
        # Gamma 업데이트 (moment matching)
        self.length_k, self.length_theta = \
            self.update_gamma(observation['response_length'])

예측-평가 루프

async def prediction_evaluation_loop(user_input):
    # 1. 예측
    prediction = model.predict_user_response(user_input)
    
    # 2. 실제 응답 생성
    actual_response = await generate_response(user_input)
    
    # 3. 사용자 반응 수집
    user_reaction = await collect_feedback()
    
    # 4. 오차 계산 (3종)
    kl_div = calculate_kl(prediction, user_reaction)
    brier = calculate_brier(prediction, user_reaction)
    ece = calculate_ece(prediction, user_reaction)
    
    # 5. 모델 업데이트
    if max(kl_div, brier, ece) > threshold:
        model.update_posterior(user_reaction)
    
    return actual_response

개인화

  • 사용자별 베이지안 파라미터 저장
  • 조직/팀/개인 3단계 계층 구조
  • Cold start: 조직 평균값 사용

성능 목표

  • ECE: ≤ 0.08
  • Brier Score: ≤ 0.20
  • 학습 수렴: 50회 상호작용
  • 개인화 효과: +15% 만족도

산출물

  • 베이지안 모델 클래스
  • 예측-평가 파이프라인
  • 3종 오차 메트릭
  • 사용자별 파라미터 저장소
  • 학습 곡선 분석

Phase 5: 프로덕션 및 확장

목표

"안정적인 프로덕션 배포와 고급 기능 추가"

프라이버시 게이트

class PrivacyGate:
    def __init__(self):
        self.pii_patterns = load_pii_patterns()
        self.sensitive_topics = load_sensitive_topics()
    
    def filter(self, text, metadata):
        # PII 감지
        if self.detect_pii(text):
            return self.anonymize(text)
        
        # 민감 주제 필터
        if self.is_sensitive(text):
            return {"summary": self.summarize(text), 
                   "original": None}
        
        # 24시간 옵트아웃
        if metadata.get('opt_out_requested'):
            return None
            
        return text

모니터링 시스템

# prometheus metrics
metrics:
  - emotion_analysis_duration_seconds
  - emotion_cache_hit_ratio
  - bayesian_update_count
  - prediction_error_rate
  - privacy_filter_triggers

alerts:
  - name: HighECE
    expr: emotion_ece > 0.1
    for: 5m
    
  - name: SlowResponse  
    expr: emotion_p95_latency > 500
    for: 10m

고급 기능

  • HDBSCAN 클러스터링 도입
  • 감정 전환 패턴 학습
  • 멀티모달 확장 준비 (음성/표정)
  • 설명가능 AI (LIME/SHAP)

확장성

# 수평 확장 준비
class EmotionAnalyzerCluster:
    def __init__(self, workers=4):
        self.workers = workers
        self.load_balancer = ConsistentHash()
    
    async def analyze(self, text, user_id):
        # 사용자별로 일관된 워커 할당
        worker = self.load_balancer.get_worker(user_id)
        return await worker.analyze(text)

최종 KPI

  • ECE: ≤ 0.05
  • Brier Score: ≤ 0.18
  • NDCG@10: ≥ 0.6
  • 응답시간 P95: ≤ 300ms
  • 가용성: 99.9%

산출물

  • 프라이버시 게이트 시스템
  • Prometheus/Grafana 대시보드
  • 수평 확장 아키텍처
  • HDBSCAN 클러스터링
  • 프로덕션 배포 (Docker/K8s)
  • 운영 문서 및 Runbook

리스크 및 완화 방안

기술적 리스크

  1. ChromaDB 성능 한계

    • 완화: Redis 캐시 레이어 추가
    • 대안: Pinecone/Weaviate 검토
  2. 모델 추론 속도

    • 완화: ONNX 변환, 양자화
    • 대안: DistilBERT 기반 경량 모델
  3. 베이지안 계산 복잡도

    • 완화: 근사 알고리즘 사용
    • 대안: 단순 EMA로 대체

데이터 리스크

  1. 라벨 품질

    • 완화: 다중 라벨러, 합의 메커니즘
    • 대안: 약지도 학습
  2. 개인정보 유출

    • 완화: 로컬 처리, 암호화
    • 대안: 연합 학습

운영 리스크

  1. 서비스 장애

    • 완화: Circuit breaker, 폴백
    • 대안: 기본 감정만 제공
  2. 비용 증가

    • 완화: 사용량 기반 스케일링
    • 대안: 엣지 디바이스 처리

성공 기준

Phase별 체크포인트

  • Phase 1: 5개 감정 인식 작동 확인
  • Phase 2: 200ms 응답시간 달성
  • Phase 3: 9개 감정 정확도 80%
  • Phase 4: 개인화 효과 측정 가능
  • Phase 5: 프로덕션 안정성 99.9%

전체 프로젝트 성공 지표

  1. 사용자 만족도: NPS 40 이상
  2. 기술 성능: 모든 KPI 목표치 달성
  3. 비즈니스 가치: 사용자 이탈률 20% 감소
  4. 확장 가능성: 일 100만 요청 처리


이 로드맵은 이상적인 설계를 현실적으로 구현 가능한 단계로 나눈 실행 계획입니다. 각 Phase는 독립적으로 가치를 제공하며, 상황에 따라 중단하거나 방향을 전환할 수 있습니다.