# 콜드메일 온톨로지 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`는 규칙 통계)