# rb8001: IR Deck 응답 오류 — RAG 혼입 + 저품질 추출 이슈

## 개요 (KST 00:39–00:48, 2025-10-22)
- 증상: Slack에서 IR Deck PDF 페이지별 분석 요청 시, 서로 다른 문서 스니펫이 섞여 응답되거나(혼입), 깨진 텍스트 기반의 추정 서술이 포함됨.
- 영향: 답변 정확성 저하, 페이지 경계 불일치, 근거 인용 부재.

## 증상
- RAG 스니펫 혼입: 업로드 파일(서비스 프로세스_리버스마운틴.pdf) 직후에도 `[파일: AIdol_251010.pdf] … TEAM MEMBERS …`가 주입되어 문서 내용이 혼재.
- 저품질 근거 사용: 스니펫이 가비지/깨진 텍스트라 “(추정)” 서술과 일반화가 섞여 사실성 저하.
- 페이지 경계 상실: 청크 수가 1 수준인 케이스에서 페이지별 분석을 강행, 실제 페이지 구조와 불일치.

## 근거 로그 (요약)
- rb8001: `[Graph] uploading to RAG: …리버스마운틴.pdf` → 직후 `Injected 2 snippet(s)`와 함께 AIdol 스니펫 포함된 Router result 발생.
- skill-rag-file: `File already exists … returning existing document_id`로 중복 판단, 재추출/재인덱싱 없이 과거 인덱스 텍스트 사용.

## 원인
1) 문서 식별/고정 미흡 → 동일 스레드에서 과거 인덱스(AIdol) 스니펫이 검색 결과로 혼입.
2) 추출 품질 저하 → PyPDF2가 일부 텍스트를 반환해 OCR 강제 전환이 트리거되지 않음(가비지 포함), 초기 인덱스 품질 불량.
3) 스니펫 의존 → 본문 직접 확인 없이 짧은 조각으로 페이지별 분석을 일반화.

## 조치 (코드 반영)
- LangGraph 강화(업로드 흐름)
  - 업로드 직후 `/api/reindex`(force_ocr) 호출 → OCR 강제/재청킹/재인덱싱 → `/api/text/{doc}`로 full-text 우선 분석 → 스니펫은 보조.
  - 파일: `rb8001/app/pipelines/langgraph_document.py`, `rb8001/app/router/slack_handler.py`
- 추출 품질 개선(skill-rag-file)
  - PDF 추출 순서: `pdftotext → PyPDF2 → OCR(pytesseract)`
  - 품질 휴리스틱(len/garbage_ratio/unique_chars) 도입 → 저품질이면 강제 OCR → 텍스트/품질 메타 저장(`ocr_used`, `quality`).
  - 파일: `skill-rag-file/app/services/text_extractor.py`, `skill-rag-file/app/api/upload.py`
- 텍스트 직접 조회 API
  - `/api/text/{document_id}`에서 full-text+메타 제공(분석·검증용).
  - 파일: `skill-rag-file/app/api/text.py`, `skill-rag-file/app/main.py`
- 문서 고정
  - thread_ts → `{team_id, document_ids}` 캐시로 동일 스레드의 RAG 대상 문서를 고정.
  - 파일: `rb8001/app/router/thread_doc_cache.py`, `rb8001/app/router/slack_handler.py`

## 검증
- 업로드/분석 시 로그: `[Graph] downloading → uploading → reindex(force_ocr) → searching → Injected …` 순서 확인.
- 텍스트 품질: `/api/text/{doc}`에서 `ocr_used: true`, `quality.garbage_ratio` 개선 확인.
- 응답 근거: 페이지별 분석에 실제 본문 인용(섹션명/쪽 정보) 포함, 혼입/추정 서술 제거.

## 교훈 ✍️
- RAG는 “문서 고정(doc_id)”과 “본문 직접 확인(full-text-first)”이 정확성을 좌우한다.
- PDF는 pdftotext 선호, 실패/저품질 시 즉시 OCR 강제 전환 및 재인덱싱으로 품질 가드 필요.
- 재시작/컨테이너 교체 시 로그 공백이 생기므로 외부 스토리지 감사로그를 병행해 트레이싱 신뢰도를 높인다.
