From 8f5596875da152f7101b2dabe6548199a9ace456 Mon Sep 17 00:00:00 2001 From: Claude-51124 Date: Thu, 5 Feb 2026 18:00:33 +0900 Subject: [PATCH] docs: archive coldmail ontology plan and add troubleshooting --- ...251016_ontology_coldmail_implementation.md | 132 ----------------- journey/plans/README.md | 5 +- ...251016_ontology_coldmail_implementation.md | 137 ++++++++++++++---- ..._coldmail_ontology_phase2_3_memory_impl.md | 24 +++ 4 files changed, 134 insertions(+), 164 deletions(-) delete mode 100644 journey/plans/251016_ontology_coldmail_implementation.md create mode 100644 journey/troubleshooting/260205_coldmail_ontology_phase2_3_memory_impl.md diff --git a/journey/plans/251016_ontology_coldmail_implementation.md b/journey/plans/251016_ontology_coldmail_implementation.md deleted file mode 100644 index 4eecdf6..0000000 --- a/journey/plans/251016_ontology_coldmail_implementation.md +++ /dev/null @@ -1,132 +0,0 @@ -# 온톨로지 기반 Coldmail 필터 구현 계획 - -**날짜**: 2025-10-16 -**목표**: 임베딩 한계(파인티처 메일 누락)를 온톨로지 추론으로 해결 -**상태**: Phase 1-1.5 완료, Phase 2-3 미구현 - -**원칙 참조** (구현 전 필수 확인): -- `311_백엔드_구조_원칙.md`: 계층 분리, DB는 state 경유 -- `312_문서_작성_원칙.md`: 핵심만 간결, 파일명:줄번호 -- `315_테스트_원칙.md`: 테스트는 TDD로 진행 (Red → Green → Refactor) - ---- - -## Phase 1: Coldmail 온톨로지 (✅ 완료) - -→ 상세: `troubleshooting/251014_claude_coldmail_filter_tokenization_issue.md` - ---- - -## Phase 1.5: 베이지안 학습 (✅ 완료) - -→ 상세: `troubleshooting/260113_coldmail_ontology_phase1_5_implementation.md` - ---- - -## 남은 작업 - -### Phase 2-3: Neo4j 기억 시스템 및 감정-기억-윤리 (TDD 진행) -- **참고**: `../ideas/251016_coldmail_ontology_phase2_3_neo4j_emotion.md` -- **필요 작업**: Neo4j 기억 시스템, 감정-기억-윤리 삼각형 구현 - ---- - -## 문제 상황 (구체 시나리오) - -- 2025-10-14 09:05 Coldmail Daily Briefing에서 IR deck 메일이 Slack에 전송되지 않음 - (올굿즈컴퍼니 IR deck 30.35%, 빅웨이브 IR 행사 7.65%, 투자제안서 검토 28.38% → threshold 미달) -- 원인: 정규식 토큰화 실패(“회사소개서”, “ir에” 등 교착어 처리 불가)로 DB 키워드 매칭 실패 - → 임베딩/온톨로지 기반 추론 필요성 대두 -- 현재는 하이브리드(임베딩→LLM→Naive Bayes) + 온톨로지 규칙 + Slack 피드백 학습까지 적용 - (Phase 1/1.5 완료, 남은 것은 Neo4j 기억 시스템 확장) - -## 기대 효과 (UX 중심) - -- **누락 감소**: 중요한 콜드메일이 브리핑에서 빠지지 않아 “믿고 보는 브리핑” 경험 제공 -- **개인화 체감**: 맞음/틀림 피드백이 기억에 누적되어 사용자별 패턴 반영 정확도 향상 -- **설명 가능성**: 규칙·관계·기억 기반 근거로 “왜 콜드메일인지” 설명 가능 → 신뢰도 상승 - ---- - -## Phase 2-3 상세 작업 (결정 완료) - -### 0) 현재 Neo4j 위치 확인 (기반 코드 재사용) -- **클라이언트**: `rb8001/app/services/memory/neo4j_client.py:1-200` -- **환경변수**: `rb8001/.env:NEO4J_URI, NEO4J_USER, NEO4J_PASSWORD` (기본값 포함) -- **연결 위치 확인**: Neo4j는 **51123 서버(192.168.219.45)**에서 운영 - - Bolt: `neo4j://192.168.219.45:7687` (DOCS 아이디어/검증 문서 동일) - - HTTP: `http://192.168.219.45:7474` -- **기존 사용처**: `rb8001/app/services/memory_hybrid_retrieval.py`, `rb8001/app/services/startup_valuation.py` - -### 1) 데이터 구조 (Neo4j) -- **노드**: `Email`, `Rule`, `Company`, `Topic`, `User` -- **관계**: `(:Email)-[:MATCHED_RULE]->(:Rule)`, `(:Email)-[:MENTIONS]->(:Company|Topic)`, `(:User)-[:RECEIVED]->(:Email)` -- **필수 속성**: - - `Email`: `email_id`, `subject`, `sender`, `received_at`, `confidence`, `source`(hybrid/ontology) - - `Rule`: `rule_id`, `rule_type`, `confidence` - - `Company`: `name`, `domain` - - `Topic`: `keyword` - - `User`: `user_id` - -### 2) 서비스/레포지토리 구조 (계층 분리) -- **state/repositories**: `rb8001/app/state/repositories/coldmail_memory_repository.py` (Neo4j CRUD, 내부에서 `Neo4jClient` 사용) -- **services**: `rb8001/app/services/coldmail_memory_service.py` (기억 저장/조회/요약 로직) -- **services**: `rb8001/app/services/coldmail_ontology_reasoner.py`와 연결 (규칙/기억 반영) -- **workflows**: `rb8001/app/services/workflows/coldmail_workflow.py`에서 기억 저장 호출 - -### 3) 인터페이스 (입출력 고정) -- `save_email_memory(user_id, email_payload, matched_rules, topics, companies) -> memory_id` -- `get_recent_memory(user_id, limit=20) -> List[MemoryItem]` -- `get_rule_context(rule_id) -> Dict` (해당 규칙과 연결된 최근 이메일 요약) - -### 4) 데이터 흐름 (실행 순서) -1. hybrid_coldmail_filter 결과에 `matched_rules` 포함 -2. 콜드메일 확정 시 `coldmail_memory_service.save_email_memory()` 호출 -3. 온톨로지 판단 시 `get_rule_context()`로 기억 기반 보정 - -### 5) DB 스키마 확인/동기화 -- Neo4j 실제 스키마 확인 후 Repository/Service 동시 반영 -- 스키마 변경 시 ORM/DDL/Repository 동기화 원칙 준수 - -### 6) 테스트 (TDD, pytest) -- **파일**: `rb8001/tests/test_coldmail_memory_repository.py` - - Neo4j 저장/조회/관계 생성 검증 -- **파일**: `rb8001/tests/test_coldmail_memory_service.py` - - save/get 동작, rule context 요약 결과 검증 -- **UX 검증**: “왜 콜드메일인지” 설명 문구 포함 여부 확인 - -### 7) 완료 기준 -- Neo4j에 콜드메일 기억 저장/조회 성공 -- 온톨로지 판단에 기억 보정 값 반영 -- Slack 브리핑에서 누락/오판 사례 재현 시 개선 확인 - ---- - -## 스키마 확정 체크리스트 (구현 전 필수) - -- **Neo4j 실제 라벨/관계 확인**: 기존 데이터 라벨/관계 목록 수집 -- **필드명/타입 확정**: Email/Rule/Company/Topic/User 속성명 및 타입 확인 -- **인덱스/제약 확인**: 유니크 키, 필수 인덱스 목록 확인 -- **샘플 쿼리 검증**: 실제 데이터로 MATCH/CREATE 쿼리 1~2건 검증 -- **환경변수 검증**: `NEO4J_URI/USER/PASSWORD`로 연결 확인 -- **참고 근거**: `journey/ideas/251016_coldmail_ontology_phase2_3_neo4j_emotion.md`, `journey/troubleshooting/251016_phase2_neo4j_validation.md`, `journey/troubleshooting/260112_storehub_neo4j_add.md` - ---- - -## 실제 Neo4j 스키마 확인 결과 (51123) - -- **라벨**: `Startup`, `VC`, `Batch`, `Category`, `Tag`, `NewsArticle` -- **관계**: `BATCH`, `BELONGS_TO`, `TAGGED`, `MENTIONS` -- **인덱스(대표)**: `Batch.name`, `Category.name`, `NewsArticle.url` + lookup 인덱스 -- **제약(UNIQUENESS)**: `Batch.name`, `Category.name`, `NewsArticle.url`, `Startup.id`, `VC.id` - ---- - -## 참고 - -- `book/300_architecture/311_백엔드_구조_원칙.md` -- `book/300_architecture/315_테스트_원칙.md` -- `troubleshooting/251014_claude_coldmail_filter_tokenization_issue.md` -- `troubleshooting/251016_ontology_filter_validation.md` -- `troubleshooting/260113_coldmail_ontology_phase1_5_implementation.md` -- `book/200_core_design/225_온톨로지_기반_지식_표현.md` diff --git a/journey/plans/README.md b/journey/plans/README.md index 6988454..8514c74 100644 --- a/journey/plans/README.md +++ b/journey/plans/README.md @@ -14,6 +14,7 @@ 5. **동남아 스타트업 뉴스 아침브리핑 (260129)** - 완료 → `plans/archive/260129_동남아_스타트업_뉴스_아침브리핑.md` 6. **의도 런타임 하이브리드 (251023)** - 전체 완료 (260203) → `plans/archive/251023_happybell80_의도_런타임_하이브리드_임베딩_베이지안_동적학습.md` 7. **감정 시스템 Phase 1–3 (250808)** - 전체 완료 (260204) → `plans/archive/250808_감정시스템_현실적용_5단계_로드맵.md` +8. **콜드메일 온톨로지 Phase 2–3 (251016)** - 완료 (260205) → `plans/archive/251016_ontology_coldmail_implementation.md` 8. **뉴스 브리핑 LangGraph 전환 (260202)** - 완료 (260205) → `plans/archive/260202_뉴스브리핑_LangGraph_전환.md` --- @@ -62,9 +63,7 @@ - **참고**: `plans/archive/251225_admin_dashboard_code_refactoring.md` ### 2. 콜드메일 온톨로지 (251016) -- **완료**: Phase 1 온톨로지 필터 -- **남은 작업**: Phase 1.5 (베이지안 학습), Phase 2-3 (Neo4j 기억 시스템, 감정-기억-윤리) -- **참고**: `plans/251016_ontology_coldmail_implementation.md` +**상태**: ✅ 완료 → `plans/archive/251016_ontology_coldmail_implementation.md` --- diff --git a/journey/plans/archive/251016_ontology_coldmail_implementation.md b/journey/plans/archive/251016_ontology_coldmail_implementation.md index 45acf88..4eecdf6 100644 --- a/journey/plans/archive/251016_ontology_coldmail_implementation.md +++ b/journey/plans/archive/251016_ontology_coldmail_implementation.md @@ -1,8 +1,13 @@ -# 온톨로지 기반 Coldmail 필터 구현 계획 (Phase 1 완료) +# 온톨로지 기반 Coldmail 필터 구현 계획 **날짜**: 2025-10-16 **목표**: 임베딩 한계(파인티처 메일 누락)를 온톨로지 추론으로 해결 -**상태**: Phase 1 완료, Phase 1.5 계획 분리 +**상태**: Phase 1-1.5 완료, Phase 2-3 미구현 + +**원칙 참조** (구현 전 필수 확인): +- `311_백엔드_구조_원칙.md`: 계층 분리, DB는 state 경유 +- `312_문서_작성_원칙.md`: 핵심만 간결, 파일명:줄번호 +- `315_테스트_원칙.md`: 테스트는 TDD로 진행 (Red → Green → Refactor) --- @@ -10,44 +15,118 @@ → 상세: `troubleshooting/251014_claude_coldmail_filter_tokenization_issue.md` -### 구현 완료 내용 +--- -**파일**: `rb8001/app/services/coldmail_ontology_reasoner.py` -- 규칙 엔진 구현 (10개 규칙) -- 임베딩 분류(75%) + 온톨로지 추론 → 90%+ 달성 -- Threshold: 0.7 이상 확정, 0.4-0.7은 LLM fallback +## Phase 1.5: 베이지안 학습 (✅ 완료) -**검증 결과**: -- 파인티처 메일: coldmail 0.28 → 0.90 (성공) -- 기존 17건 재테스트: 정확도 100% - -**추론 규칙 (10개)**: - -**Coldmail 판정 (6개)**: -1. 제목 CONTAINS ["투자", "IR", "피칭"] + PDF 첨부 → 0.9 -2. 첨부파일명 CONTAINS ["회사소개서", "IR_Deck"] → 0.85 -3. 제목 "검토요청" + 첨부 → 0.8 -4. 미등록 발신자 + PDF → 0.7 -5. 본문 CONTAINS ["투자 유치", "펀딩", "밸류에이션"] → 0.75 -6. 발신자 도메인 IN ["startup", "ventures", "capital"] → 0.6 - -**Normal 판정 (4개)**: -7. 제목 CONTAINS ["행사", "초대", "세미나"] → 0.9 -8. 제목 CONTAINS ["영수증", "세금계산서"] → 0.95 -9. 제목 CONTAINS ["회의", "공지", "보고"] → 0.85 -10. 등록 발신자 + 규칙 1-6 미해당 → 0.8 +→ 상세: `troubleshooting/260113_coldmail_ontology_phase1_5_implementation.md` --- -## 후속 작업 +## 남은 작업 -- **Phase 1.5**: 베이지안 학습 구현 → `plans/260113_coldmail_ontology_phase1_5_bayesian_learning.md` -- **Phase 2-3**: Neo4j 기억 시스템 및 감정-기억-윤리 → `ideas/251016_coldmail_ontology_phase2_3_neo4j_emotion.md` +### Phase 2-3: Neo4j 기억 시스템 및 감정-기억-윤리 (TDD 진행) +- **참고**: `../ideas/251016_coldmail_ontology_phase2_3_neo4j_emotion.md` +- **필요 작업**: Neo4j 기억 시스템, 감정-기억-윤리 삼각형 구현 + +--- + +## 문제 상황 (구체 시나리오) + +- 2025-10-14 09:05 Coldmail Daily Briefing에서 IR deck 메일이 Slack에 전송되지 않음 + (올굿즈컴퍼니 IR deck 30.35%, 빅웨이브 IR 행사 7.65%, 투자제안서 검토 28.38% → threshold 미달) +- 원인: 정규식 토큰화 실패(“회사소개서”, “ir에” 등 교착어 처리 불가)로 DB 키워드 매칭 실패 + → 임베딩/온톨로지 기반 추론 필요성 대두 +- 현재는 하이브리드(임베딩→LLM→Naive Bayes) + 온톨로지 규칙 + Slack 피드백 학습까지 적용 + (Phase 1/1.5 완료, 남은 것은 Neo4j 기억 시스템 확장) + +## 기대 효과 (UX 중심) + +- **누락 감소**: 중요한 콜드메일이 브리핑에서 빠지지 않아 “믿고 보는 브리핑” 경험 제공 +- **개인화 체감**: 맞음/틀림 피드백이 기억에 누적되어 사용자별 패턴 반영 정확도 향상 +- **설명 가능성**: 규칙·관계·기억 기반 근거로 “왜 콜드메일인지” 설명 가능 → 신뢰도 상승 + +--- + +## Phase 2-3 상세 작업 (결정 완료) + +### 0) 현재 Neo4j 위치 확인 (기반 코드 재사용) +- **클라이언트**: `rb8001/app/services/memory/neo4j_client.py:1-200` +- **환경변수**: `rb8001/.env:NEO4J_URI, NEO4J_USER, NEO4J_PASSWORD` (기본값 포함) +- **연결 위치 확인**: Neo4j는 **51123 서버(192.168.219.45)**에서 운영 + - Bolt: `neo4j://192.168.219.45:7687` (DOCS 아이디어/검증 문서 동일) + - HTTP: `http://192.168.219.45:7474` +- **기존 사용처**: `rb8001/app/services/memory_hybrid_retrieval.py`, `rb8001/app/services/startup_valuation.py` + +### 1) 데이터 구조 (Neo4j) +- **노드**: `Email`, `Rule`, `Company`, `Topic`, `User` +- **관계**: `(:Email)-[:MATCHED_RULE]->(:Rule)`, `(:Email)-[:MENTIONS]->(:Company|Topic)`, `(:User)-[:RECEIVED]->(:Email)` +- **필수 속성**: + - `Email`: `email_id`, `subject`, `sender`, `received_at`, `confidence`, `source`(hybrid/ontology) + - `Rule`: `rule_id`, `rule_type`, `confidence` + - `Company`: `name`, `domain` + - `Topic`: `keyword` + - `User`: `user_id` + +### 2) 서비스/레포지토리 구조 (계층 분리) +- **state/repositories**: `rb8001/app/state/repositories/coldmail_memory_repository.py` (Neo4j CRUD, 내부에서 `Neo4jClient` 사용) +- **services**: `rb8001/app/services/coldmail_memory_service.py` (기억 저장/조회/요약 로직) +- **services**: `rb8001/app/services/coldmail_ontology_reasoner.py`와 연결 (규칙/기억 반영) +- **workflows**: `rb8001/app/services/workflows/coldmail_workflow.py`에서 기억 저장 호출 + +### 3) 인터페이스 (입출력 고정) +- `save_email_memory(user_id, email_payload, matched_rules, topics, companies) -> memory_id` +- `get_recent_memory(user_id, limit=20) -> List[MemoryItem]` +- `get_rule_context(rule_id) -> Dict` (해당 규칙과 연결된 최근 이메일 요약) + +### 4) 데이터 흐름 (실행 순서) +1. hybrid_coldmail_filter 결과에 `matched_rules` 포함 +2. 콜드메일 확정 시 `coldmail_memory_service.save_email_memory()` 호출 +3. 온톨로지 판단 시 `get_rule_context()`로 기억 기반 보정 + +### 5) DB 스키마 확인/동기화 +- Neo4j 실제 스키마 확인 후 Repository/Service 동시 반영 +- 스키마 변경 시 ORM/DDL/Repository 동기화 원칙 준수 + +### 6) 테스트 (TDD, pytest) +- **파일**: `rb8001/tests/test_coldmail_memory_repository.py` + - Neo4j 저장/조회/관계 생성 검증 +- **파일**: `rb8001/tests/test_coldmail_memory_service.py` + - save/get 동작, rule context 요약 결과 검증 +- **UX 검증**: “왜 콜드메일인지” 설명 문구 포함 여부 확인 + +### 7) 완료 기준 +- Neo4j에 콜드메일 기억 저장/조회 성공 +- 온톨로지 판단에 기억 보정 값 반영 +- Slack 브리핑에서 누락/오판 사례 재현 시 개선 확인 + +--- + +## 스키마 확정 체크리스트 (구현 전 필수) + +- **Neo4j 실제 라벨/관계 확인**: 기존 데이터 라벨/관계 목록 수집 +- **필드명/타입 확정**: Email/Rule/Company/Topic/User 속성명 및 타입 확인 +- **인덱스/제약 확인**: 유니크 키, 필수 인덱스 목록 확인 +- **샘플 쿼리 검증**: 실제 데이터로 MATCH/CREATE 쿼리 1~2건 검증 +- **환경변수 검증**: `NEO4J_URI/USER/PASSWORD`로 연결 확인 +- **참고 근거**: `journey/ideas/251016_coldmail_ontology_phase2_3_neo4j_emotion.md`, `journey/troubleshooting/251016_phase2_neo4j_validation.md`, `journey/troubleshooting/260112_storehub_neo4j_add.md` + +--- + +## 실제 Neo4j 스키마 확인 결과 (51123) + +- **라벨**: `Startup`, `VC`, `Batch`, `Category`, `Tag`, `NewsArticle` +- **관계**: `BATCH`, `BELONGS_TO`, `TAGGED`, `MENTIONS` +- **인덱스(대표)**: `Batch.name`, `Category.name`, `NewsArticle.url` + lookup 인덱스 +- **제약(UNIQUENESS)**: `Batch.name`, `Category.name`, `NewsArticle.url`, `Startup.id`, `VC.id` --- ## 참고 +- `book/300_architecture/311_백엔드_구조_원칙.md` +- `book/300_architecture/315_테스트_원칙.md` - `troubleshooting/251014_claude_coldmail_filter_tokenization_issue.md` - `troubleshooting/251016_ontology_filter_validation.md` +- `troubleshooting/260113_coldmail_ontology_phase1_5_implementation.md` - `book/200_core_design/225_온톨로지_기반_지식_표현.md` diff --git a/journey/troubleshooting/260205_coldmail_ontology_phase2_3_memory_impl.md b/journey/troubleshooting/260205_coldmail_ontology_phase2_3_memory_impl.md new file mode 100644 index 0000000..96545a6 --- /dev/null +++ b/journey/troubleshooting/260205_coldmail_ontology_phase2_3_memory_impl.md @@ -0,0 +1,24 @@ +# 콜드메일 온톨로지 Phase 2-3 Neo4j 기억 시스템 구현 + +**날짜**: 2026-02-05 +**작성자**: happybell80 +**관련 파일**: `rb8001/app/state/repositories/coldmail_memory_repository.py:1-108`, `rb8001/app/services/coldmail_memory_service.py:1-36`, `rb8001/app/services/coldmail_ontology_reasoner.py:273-338`, `rb8001/app/services/workflows/coldmail_workflow.py:100-270`, `rb8001/tests/test_coldmail_memory_repository.py:1-42`, `rb8001/tests/test_coldmail_memory_service.py:1-43` + +--- + +## 문제 상황 +- 콜드메일 온톨로지 Phase 2-3의 Neo4j 기억 저장/보정 흐름이 계획만 존재하고 코드 미구현 상태 + +## 해결 방안 +- Neo4j Repository/Service 추가로 기억 저장·조회·규칙 컨텍스트 조회 구현 +- 온톨로지 판단에 Neo4j 기억 컨텍스트 반영하여 confidence 보정 +- 워크플로우에서 콜드메일 확정 시 Neo4j 기억 저장 + +## 구현 완료 +- 커밋: `ed88796` (2026-02-05) +- 테스트: `pytest tests/test_coldmail_memory_repository.py tests/test_coldmail_memory_service.py -q` (6 passed) +- 배포 확인: `docker ps`에서 rb8001 재기동 및 healthy 확인 + +## 교훈 +- Neo4j 기반 기억 저장은 Repository/Service 분리로 유지보수성을 확보 +- 온톨로지 confidence 보정은 최근 기억 컨텍스트를 기준으로 점진 적용이 안전