DOCS/journey/troubleshooting/260113_coldmail_ontology_phase1_5_implementation.md

4.8 KiB
Raw Blame History

콜드메일 온톨로지 Phase 1.5 베이지안 학습 구현 완료

날짜: 2026-01-13
작성자: happybell80
목표: 온톨로지 규칙 confidence 값을 하드코딩에서 베이지안 학습 기반으로 전환
상태: 구현 완료


구현 내용

Phase 1.5.1: DB 스키마 설계

테이블: coldmail_ontology_rule_stats

  • rule_id (VARCHAR(50), UNIQUE): 규칙 ID (R1, R1B, R2 등)
  • alpha (FLOAT, DEFAULT 1.0): Beta 분포 α 파라미터
  • beta (FLOAT, DEFAULT 1.0): Beta 분포 β 파라미터
  • created_at, updated_at: 타임스탬프

구현 파일: rb8001/app/state/repositories/coldmail_ontology_repository.py

  • _ensure_table(): 모듈 로드 시 자동 테이블 생성

Phase 1.5.2: Repository 구현

파일: rb8001/app/state/repositories/coldmail_ontology_repository.py

구현 함수:

  • get_rule_confidence(rule_id): 규칙별 confidence 조회 (α/(α+β))
  • update_rule_feedback(rule_id, is_correct): 피드백 기반 alpha/beta 업데이트
    • is_correct=True: alpha += 1
    • is_correct=False: beta += 1
  • get_all_rule_stats(): 모든 규칙의 alpha/beta 조회
  • initialize_rule_stats(rule_ids): 초기 데이터 설정 (alpha=1.0, beta=1.0)

테스트: rb8001/tests/test_coldmail_ontology_repository.py

  • 존재하지 않는 규칙 조회 시 None 반환
  • 맞음/틀림 피드백 업데이트 검증
  • confidence 계산 정확성 검증

Phase 1.5.3: 온톨로지 Reasoner 수정

파일: rb8001/app/services/coldmail_ontology_reasoner.py

변경 사항:

  • decide_coldmail() 함수를 async로 변경
  • 매칭된 규칙의 confidence를 DB에서 동적 조회
  • DB 없을 때 하드코딩 값 폴백 (하위 호환성)

코드 구조: coldmail_ontology_reasoner.py:251-328

  • decide_coldmail(): DB에서 동적 confidence 조회, 없으면 하드코딩 값 폴백

호출부 수정:

  • coldmail_hybrid_filter.py: await is_coldmail_ontology() 호출
  • scripts/find_coldmail_candidates.py: await ontology_decide() 호출

Phase 1.5.4: 피드백 연동

파일:

  • rb8001/app/services/coldmail_feedback.py
  • rb8001/app/services/coldmail_processor.py
  • rb8001/app/services/slack/coldmail_service.py
  • rb8001/app/services/workflows/coldmail_workflow.py

변경 사항:

  1. matched_rules 저장:

    • coldmail_hybrid_filter.py:77,86: ontology_result["matched_rules"]를 반환값에 포함
    • coldmail_workflow.py:91: _matched_rules를 email 객체에 추가
    • coldmail_processor.py:583: 피드백 버튼 value에 matched_rules_json 포함
  2. 피드백 처리:

    • coldmail_feedback.py:11: process_coldmail_feedback()matched_rules_json 파라미터 추가
    • coldmail_feedback.py:30-35: 매칭된 규칙별로 update_rule_feedback() 호출
    • Naive Bayes 학습과 함께 온톨로지 규칙 학습 수행
  3. 피드백 버튼 value 형식:

    subject|||sender|||email_id|||doc_id|||company|||thread_id|||matched_rules_json
    
  4. 확인 버튼 처리:

    • slack/coldmail_service.py:56-73: handle_coldmail_confirm()에서 확인/거부 시 모두 피드백 처리

테스트 결과

초기 상태

  • DB 없을 때 하드코딩 값 사용 확인
  • 테이블 자동 생성 확인

피드백 업데이트

  • "맞음" 클릭 후 alpha 증가 확인
  • "틀림" 클릭 후 beta 증가 확인
  • confidence = α/(α+β) 계산 정확성 확인

다중 규칙

  • 여러 규칙 매칭 시 각각 독립적으로 업데이트 확인

하위 호환성

  • 기존 하드코딩 값 유지: DB에 규칙이 없으면 기존 하드코딩 confidence 값 사용
  • 점진적 전환: 기존 규칙 confidence를 DB에 마이그레이션하여 초기값 설정 가능
  • 피드백 버튼 형식: 기존 형식(3개 파트)과 새 형식(7개 파트) 모두 지원

성능

  • 비동기 처리: DB 조회는 async로 처리하여 필터링 속도 저하 방지
  • 인덱스: rule_id에 인덱스 생성으로 조회 성능 최적화

참고 문서

  • 계획 문서: plans/260113_coldmail_ontology_phase1_5_bayesian_learning.md
  • 원본 계획: plans/archive/251016_ontology_coldmail_implementation.md
  • Phase 1 구현: troubleshooting/251014_claude_coldmail_filter_tokenization_issue.md
  • 베이지안 패턴: app/core/emotion/bayesian.py, app/services/brain/intent_store.py

교훈

  • TDD 원칙 준수: 테스트 먼저 작성 후 구현하여 기능 검증
  • 하위 호환성 유지: 기존 하드코딩 값을 폴백으로 유지하여 점진적 전환
  • Repository 패턴: 도메인별 분리 유지 (coldmail_classifier_repository는 단어 카운트, coldmail_ontology_repository는 규칙 통계)