From 5cc4e5aa08517c762aa7ccbb7d7555f865a5d4fe Mon Sep 17 00:00:00 2001 From: happybell80 Date: Sat, 21 Mar 2026 16:05:13 +0900 Subject: [PATCH] =?UTF-8?q?plan:=20=ED=95=98=EC=9D=B4=EB=B8=8C=EB=A6=AC?= =?UTF-8?q?=EB=93=9C=20=EA=B2=80=EC=83=89=20=ED=92=88=EC=A7=88=20=EA=B0=9C?= =?UTF-8?q?=EC=84=A0=20=EA=B3=84=ED=9A=8D=20(P0=203=EA=B1=B4=20+=20P1=202?= =?UTF-8?q?=EA=B1=B4)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - P0: prefix 매칭, keyword threshold 분리, RRF 점수 정규화 - P1: 초과 청크 재분할, grounding 라우팅 완화 - 260321 리서치 원인 5개 → 조치 5개 1:1 매핑 Co-Authored-By: Claude Opus 4.6 (1M context) --- ...이브리드검색_품질개선_계획.md | 93 +++++++++++++++++++ 1 file changed, 93 insertions(+) create mode 100644 journey/plans/260321_하이브리드검색_품질개선_계획.md diff --git a/journey/plans/260321_하이브리드검색_품질개선_계획.md b/journey/plans/260321_하이브리드검색_품질개선_계획.md new file mode 100644 index 0000000..f575b72 --- /dev/null +++ b/journey/plans/260321_하이브리드검색_품질개선_계획.md @@ -0,0 +1,93 @@ +# 260321 하이브리드 검색 품질 개선 계획 + +## 목적 + +- 260321 리서치에서 확정된 5개 원인을 해소하여 3중 검색이 실제로 동작하는 상태로 만든다. +- 260320 적용1 계획의 닫는 조건(샘플 질문 검증 통과)을 달성하기 위한 직접 선행 작업이다. + +## 참조 문서 + +- [260321 하이브리드 검색 keyword recall=0 및 grounding 실패 원인 확정 리서치](../research/rag/260321_하이브리드검색_keyword_recall0_및_grounding_실패_원인확정_리서치.md) +- [260320 로빙 다형식문서 RAG 적용1 계획](./260320_로빙_다형식문서_RAG_적용1_계획.md) + +## 원인 → 조치 매핑 + +| # | 원인 | 조치 | 서버 | 우선순위 | +|---|------|------|------|----------| +| 1 | `simple` 토크나이저 조사 미분리 | `_build_keyword_tsquery()`에서 각 토큰에 `:*` prefix 접미 | 24 (skill-rag-file) | P0 | +| 2 | keyword threshold 0.35가 ts_rank 최대 0.089를 전부 필터링 | keyword_search threshold를 모드별 분리 — keyword 단독 시 0.001, hybrid 내부는 현행 0.0 유지 | 24 (skill-rag-file) | P0 | +| 3 | RRF score(0.01~0.03) ≪ threshold(0.35) 스케일 불일치 | hybrid 모드의 relevance_score를 RRF 원점수가 아닌 정규화 점수로 변환. 또는 hybrid용 threshold를 별도 설정 (0.005) | 24 (skill-rag-file) | P0 | +| 4 | 쿼리-문서 임베딩 거리 문제 (긴 청크 2,703자 vs 짧은 쿼리) | 청킹 기준(chunk_size=1000) 초과 청크 재분할. 인덱싱 파이프라인에서 기존 초과 청크 탐지 + 재인덱싱 | 23 (DB) + 24 (skill-rag-file) | P1 | +| 5 | grounding 라우팅 마커 미매칭 (3건) | Company X team_id 사용자는 마커 없이도 grounding 우선 시도. `should_handle_companyx_grounding()`에서 team_id == COMPANYX_TEAM_ID이면 마커 체크 건너뛰기 | 24 (rb8001) | P1 | + +## 작업 상세 + +### P0-1: prefix 매칭 적용 (skill-rag-file) + +- 파일: `app/services/postgres_vector_store.py` → `_build_keyword_tsquery()` +- 변경: 각 토큰에 `:*` 접미 +- 예: `"아크로셀 | 개인투자조합"` → `"아크로셀:* | 개인투자조합:*"` +- 예상 효과: recall 27% → 90% (실측 기준) + +### P0-2: keyword threshold 분리 (skill-rag-file) + +- 파일: `app/services/postgres_vector_store.py` → `keyword_search()` +- 변경: threshold 파라미터를 keyword용으로 분리. 기본값 0.001 +- `search.py`에서 keyword 단독 호출 시 `keyword_threshold` 사용 +- hybrid 내부 호출은 현행 0.0 유지 + +### P0-3: RRF 점수 정규화 (skill-rag-file) + +- 파일: `app/services/postgres_vector_store.py` → `_merge_rrf()` +- 옵션 A: RRF 점수를 0~1로 정규화 — `rrf_normalized = rrf_raw / max_rrf_raw` +- 옵션 B: hybrid 모드에서 relevance_score를 `max(vector_score, rrf_score)`로 설정 +- 옵션 C: hybrid용 threshold를 별도 파라미터로 분리 (기본 0.005) +- 권장: **옵션 A** — 정렬과 필터링이 일관됨 + +### P1-4: 초과 청크 재분할 (23 DB + 24 skill-rag-file) + +- 탐지: `SELECT document_id, chunk_index, length(chunk_text) FROM team_document_chunk WHERE length(chunk_text) > 1200 AND team_id = '79441171-...'` +- 해당 문서를 chunk_size=1000, overlap=200 기준으로 재인덱싱 +- 스크립트: `skill-rag-file/scripts/reindex_oversized_chunks.py` + +### P1-5: grounding 라우팅 완화 (rb8001) + +- 파일: `app/services/companyx_grounding_service.py` → `should_handle_companyx_grounding()` +- 변경: `team_id == COMPANYX_TEAM_ID`이면 `_looks_like_companyx_grounding_question()` 체크를 건너뛰고 항상 grounding 시도 +- 주의: grounding 실패 시 일반 경로로 fallback하는 기존 흐름 유지 필요 + +## 실행 순서 + +``` +P0-1 (prefix) ─┐ +P0-2 (threshold)├─ 병렬 → skill-rag-file 재배포 → 검증 +P0-3 (RRF 정규화)─┘ + ↓ +P1-4 (청크 재분할) → 재인덱싱 → 검증 +P1-5 (라우팅 완화) → rb8001 재배포 → 검증 + ↓ + 통합 검증 (16개 + 20개) +``` + +- P0 3건은 병렬 작업 후 한 번에 배포 +- P1은 P0 검증 후 순차 + +## 검증 기준 + +- keyword 단독 검색에서 "아크로셀 정기주총" 쿼리 결과 1건 이상 +- hybrid 검색에서 relevance_score가 threshold를 자체적으로 통과 +- 옐로펀치 MOU 문서가 "옐로펀치 컴퍼니엑스 협약" 쿼리로 top-5 진입 +- 기존 통과 케이스 회귀 없음 (vector 16/16 유지) +- 재오픈 20개 중 마커 미진입 3건이 grounding 경로로 진입 + +## 닫는 조건 + +- 16개 샘플 질문: vector/keyword/hybrid 모두 결과 반환 +- 재오픈 20개: grounding 경로 진입 실패 0건 +- 적용1 계획 검증 결과 기록 테이블에 결과 기입 완료 + +## 금지 + +- 질문별 하드코딩 특례 추가 금지 (260320 계승) +- threshold를 0으로 내리는 것은 금지 (노이즈 결과 유입) +- 기존 vector 단독 검색 품질 회귀 금지