DOCS/ideas/250808_감정시스템_현실적용_5단계_로드맵.md
happybell80 6435292b70 감정 시스템 문서 업데이트
- 감정 시스템 설계서 프로덕션-레디 버전 완성
- 현실 적용 5단계 로드맵 작성
- Phase 1-4 구현 완료 문서화

주요 내용:
- Inside Out 2축 모델 (기본정서 5 + 사회기능 4)
- 엔트로피 정의: 프로토타입 소프트맥스
- 2헤드 병렬 처리 구조
- 베이지안 학습 시스템
- Thompson Sampling
- 3종 오차 메트릭 (KL/Brier/ECE)
- 목표 KPI: ECE≤0.05, Brier≤0.18, NDCG@10≥0.6
2025-08-08 11:24:27 +09:00

10 KiB

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

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

핵심 원칙

  • MVP 우선: 복잡한 기능보다 작동하는 기본 기능
  • 측정 가능한 성과: 각 단계마다 명확한 KPI
  • 점진적 복잡도: 단순 → 복잡으로 진화
  • 서비스 분리: 단일 장애점 방지
  • 함수형 100%: 하드코딩 0%, 순수 함수 체인

Phase 1: 최소 기능 구현

목표

"5개 기본정서로 감정 인식이 작동하는 최소 시스템"

구현 범위

# 기본정서만 구현
BASIC_EMOTIONS = [
    "joy",      # 기쁨
    "sadness",  # 슬픔  
    "anger",    # 분노
    "fear",     # 두려움
    "disgust"   # 혐오
]

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

기술 스택

  • 임베딩: 기존 skill-embedding 서비스 활용 (포트 8502)
  • 저장: 기존 ChromaDB 활용
  • 의사결정: ε-greedy (ε=0.1)
  • 기존 코드: rb10508_micro의 memory/storage.py 재사용

성능 목표

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

데이터 준비

  • 감정당 100개 샘플 (총 500개)
  • Gemini로 초기 라벨 생성
  • 수동 검증 20%

검증 방법

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

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

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

산출물

  • skill-embedding 서비스에 감정 분석 엔드포인트 추가
  • 5개 감정 프로토타입 정의
  • 기본 엔트로피 계산기
  • 기존 ChromaDB 통합 코드
  • 최소 테스트 데이터 (100개)

Phase 2: 성능 최적화

목표

"응답시간 200ms 달성 및 캐싱 시스템 구축"

최적화 전략

# 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%

산출물

  • LRU 캐시 시스템
  • 배치 처리 API
  • ChromaDB 인덱스 최적화
  • 성능 모니터링 대시보드
  • 프로파일링 리포트

Phase 3: 사회기능 감정 추가

목표

"9개 감정으로 확장하고 2헤드 구조 도입"

확장 감정

# 사회기능 추가
SOCIAL_EMOTIONS = [
    "anxiety",       # 불안
    "envy",          # 질투
    "embarrassment", # 당혹
    "ennui"          # 권태
]

# 2헤드 병렬 처리
async def two_head_analysis(text: str, context: dict):
    basic_task = analyze_basic(text)      # 100ms 목표
    social_task = analyze_social(text, context)  # 300ms 목표
    
    basic, social = await asyncio.gather(basic_task, social_task)
    
    # 동적 가중치 계산
    w = calculate_weight(len(text), context)
    return w * basic + (1-w) * social

데이터 확장

  • 새 감정당 200개 샘플 추가
  • 총 1,300개 라벨 데이터
  • 크라우드소싱 활용 검토

Thompson Sampling 도입

class ThompsonSampler:
    def __init__(self):
        self.alpha = np.ones(9)  # 성공 횟수
        self.beta = np.ones(9)   # 실패 횟수
    
    def sample(self):
        """베타 분포에서 샘플링"""
        return np.random.beta(self.alpha, self.beta)
    
    def update(self, action, reward):
        """결과에 따라 파라미터 업데이트"""
        if reward > 0:
            self.alpha[action] += 1
        else:
            self.beta[action] += 1

성능 목표

  • 기본정서: 100ms
  • 사회기능: 300ms
  • 통합 응답: 350ms
  • 정확도: 4.0/5.0

산출물

  • 9개 감정 프로토타입
  • 2헤드 병렬 처리 시스템
  • Thompson Sampling 구현
  • 1,300개 라벨 데이터
  • A/B 테스트 결과

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는 독립적으로 가치를 제공하며, 상황에 따라 중단하거나 방향을 전환할 수 있습니다.