# task-1529.1 완료 보고서

## SCQA

**S**: InsuWiki의 kakao_knowledge 모듈이 카카오톡 오픈채팅방 대화에서 보험 지식을 추출하고 있으나, 스레드 분리가 30분 시간 gap + 날짜 변경만으로 이루어져 동시 다발적 질문이 하나의 스레드에 섞이고 있다.

**C**: 오픈채팅방에서 여러 질문이 동시에 올라오면 하나의 wiki 항목에 복수 주제가 혼재되고, 인사/리액션 노이즈가 지식 항목에 포함되며, LLM 정제 프롬프트가 약해 품질이 낮다. 또한 Gemini API 의존성을 Anthropic Haiku로 전환해야 한다.

**Q**: 다중 신호 기반 스레드 분리 + 노이즈 필터링 + LLM 프롬프트 강화로 원자적(1질문-1답변) wiki 항목 품질을 달성할 수 있는가?

**A**: `#궁금증` 태그 기반 강제 분리, 질문 패턴 감지, 15분 gap 축소, 노이즈 필터링(인사/리액션/환영 메시지), Anthropic Haiku 전환 + Zettelkasten 기반 정제 프롬프트를 구현했다. wiki_entries.json 재생성 결과 145건→125건으로 노이즈 20건 감소. pytest 45건 전부 PASS, pyright 0건.

## 수행 내역

### 1. 스레드 분리 고도화 (`_split_into_threads`)
- **1a. `#궁금증` 태그 기반 분리**: 태그 출현 시 무조건 새 스레드 시작
- **1b. 질문 패턴 감지**: `질문 드립니다`, `문의 드립니다`, `궁금합니다`, `여쭤봅니다`, `확인 부탁` 패턴 시 새 스레드
- **1d. 시간 gap 축소**: 30분 → 15분

### 2. 노이즈 필터링 (`_is_noise_message`)
- 완전 제거: 환영 메시지 패턴 (`📚 한 발 앞서가는`, `━━━━━`, `여기서 배우고`)
- 부분 제거: 단순 인사 (`안녕하세요`, `감사합니다`만 있는 메시지), 리액션 (`ㅋㅋ`, `ㅎㅎ`, `ㄴㄴ`)

### 3. LLM 전환 (Gemini → Anthropic Haiku)
- `google.generativeai` → `anthropic` 패키지로 교체
- 모델: `claude-haiku-4-5-20251001`
- 환경변수: `GLM_API_KEY` → `ANTHROPIC_API_KEY`
- 정제 프롬프트: Zettelkasten 원자적 노트 원칙 기반으로 강화
- `is_noise` 판정 + 품질 검증 로직 추가 (제목 길이, 답변=질문 체크, 키워드 수)

### 4. wiki_entries.json 재생성
- 기존: 145건 → 신규: 125건 (-20건)
- 카테고리 분포: 고지의무 39→27, 보상 45→23, 상품 27→18, 약관 3→3, 기타 31→54
- 기타 카테고리 증가는 규칙 기반 분류의 한계 (LLM 모드 사용 시 개선 가능)

### 5. 테스트 (14건 추가)
- TestThreadSplitByQuestionTag (3건): 같은 시간대 #궁금증 2개 → 2개 스레드
- TestThreadSplitByQuestionPattern (3건): 질문 패턴 감지 분리
- TestThreadSplitBy15MinGap (2건): 15분 gap 분리/비분리
- TestNoiseFiltering (4건): 인사/리액션 제거, 실질 메시지 유지
- TestLlmPromptJsonParsing (2건): mock LLM JSON 파싱, noise 감지

## 발견 이슈 및 해결

### 자체 해결 (3건)
1. **질문 패턴 분리 스레드가 필터링됨** — `_split_into_threads`에서 질문 패턴으로 분리된 스레드에 `has_question_tag=True` 설정 추가 (knowledge_extractor.py:205)
2. **pyright Optional 구독 에러** — `_analyze_thread_with_llm` 반환값이 `Optional[dict]`이므로 테스트에 `assert result is not None` 추가 (test_knowledge_extractor.py:857)
3. **미사용 함수 `_is_question_start` 경고** — 함수 제거, `_RE_QUESTION_PATTERN`을 `_split_into_threads` 내에서 직접 사용

## 산출물

- `/home/jay/projects/insuwiki/.worktrees/task-1529.1-dev6/scripts/kakao_knowledge/knowledge_extractor.py`
- `/home/jay/projects/insuwiki/.worktrees/task-1529.1-dev6/scripts/kakao_knowledge/tests/test_knowledge_extractor.py`
- `/home/jay/projects/insuwiki/.worktrees/task-1529.1-dev6/scripts/kakao_knowledge/wiki_entries.json`
- `/home/jay/projects/insuwiki/.worktrees/task-1529.1-dev6/scripts/kakao_knowledge/wiki_entries.json.bak`

## 테스트 결과
- pytest: **45 passed** (기존 31 + 신규 14), 0 failed
- pyright: **0 errors**, 0 warnings

## 머지 판단
- **머지 필요**: Yes
- **브랜치**: task/task-1529.1-dev6
- **워크트리 경로**: /home/jay/projects/insuwiki/.worktrees/task-1529.1-dev6
- **머지 의견**: 모든 테스트 통과, pyright 에러 0건, 기존 기능 호환성 유지. `kakao_parser.py`는 수정하지 않아 파서 영향 없음. wiki_entries.json 재생성 결과도 양호 (노이즈 20건 감소).

## 모델 사용 기록
- 스바로그(백엔드): knowledge_extractor.py 구현 / sonnet
- 벨레스(테스터): test_knowledge_extractor.py 테스트 작성 / sonnet
- 라다(프론트): wiki_entries.json 재생성 + 비교 분석 / sonnet
