From 3e78c7cf6e7afe3039a9b38e3ec2619f598de09d Mon Sep 17 00:00:00 2001 From: happybell80 Date: Sat, 21 Mar 2026 15:44:44 +0900 Subject: [PATCH] =?UTF-8?q?docs:=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=20keyword=20recall=3D0=20?= =?UTF-8?q?=EB=B0=8F=20grounding=20=EC=8B=A4=ED=8C=A8=20=EC=9B=90=EC=9D=B8?= =?UTF-8?q?=20=ED=99=95=EC=A0=95=20=EB=A6=AC=EC=84=9C=EC=B9=98?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - keyword recall 0: simple 토크나이저가 한국어 조사 분리 불가 (실측 recall 27%) - grounding 실패 3계층: 검색(8건), 라우팅 마커(3건), LLM 판단(정상) - prefix 매칭(:*) 적용 시 recall 27%→90% 즉시 개선 가능 Co-Authored-By: Claude Opus 4.6 (1M context) --- ...grounding_실패_원인확정_리서치.md | 113 ++++++++++++++++++ 1 file changed, 113 insertions(+) create mode 100644 journey/research/rag/260321_하이브리드검색_keyword_recall0_및_grounding_실패_원인확정_리서치.md diff --git a/journey/research/rag/260321_하이브리드검색_keyword_recall0_및_grounding_실패_원인확정_리서치.md b/journey/research/rag/260321_하이브리드검색_keyword_recall0_및_grounding_실패_원인확정_리서치.md new file mode 100644 index 0000000..58ac58f --- /dev/null +++ b/journey/research/rag/260321_하이브리드검색_keyword_recall0_및_grounding_실패_원인확정_리서치.md @@ -0,0 +1,113 @@ +tags: [research, rag, companyx, hybrid, keyword, tsvector, grounding] + +# 260321 하이브리드 검색 keyword recall=0 및 grounding 실패 원인 확정 리서치 + +## 목적 + +- 3중 검색(벡터+키워드+그래프) 구현 후 1차 검증에서 드러난 두 가지 실패의 직접 원인을 확정한다. +- 실패 1: 샘플 질문 16개 keyword recall이 0 +- 실패 2: 재오픈 20개 중 인덱싱 문서가 있는데도 grounding 실패하는 케이스 + +## 사실 (Facts) + +### 1. keyword recall = 0의 직접 원인: `simple` 토크나이저의 한국어 교착어 미처리 + +tsvector 트리거가 `to_tsvector('simple', chunk_text)`로 생성한다. `simple` 설정은 공백 기준 분리 + 소문자 변환만 수행하고 형태소 분석을 하지 않는다. + +한국어는 교착어로 어간에 조사/어미가 항상 붙기 때문에 다음이 발생한다: + +| 원문 | tsv 토큰 | tsquery 검색어 | 결과 | +|------|----------|---------------|------| +| `투자를 하다` | `'투자를'` | `'투자'` | 불일치 | +| `개인투자조합을 운용` | `'개인투자조합을'` | `'개인투자조합'` | 불일치 | +| `투자 유치` | `'투자'` | `'투자'` | 일치 | + +DB 실측 (키워드 '투자', Company X 청크 대상): + +| 방식 | 건수 | recall | +|------|------|--------| +| `chunk_text LIKE '%투자%'` | 1,099 | 100% | +| `tsv @@ to_tsquery('simple', '투자')` (현재) | 299 | 27% | +| `tsv @@ to_tsquery('simple', '투자:*')` (prefix) | 986 | 90% | + +- **주요 손실(~63%)**: 조사 미분리 — `'투자를'`, `'투자에'`, `'투자와'`가 `'투자'`와 exact match 실패 +- **추가 손실(~10%)**: 복합어 미분리 — `'개인투자조합'`, `'총투자금액'`이 하나의 토큰으로 저장되어 prefix로도 불가 + +`_build_keyword_tsquery()`는 Python에서 정규식 `[0-9A-Za-z가-힣]+`로 깨끗한 어절 토큰을 추출하지만, DB의 tsv 토큰에는 조사가 붙어 있어 구조적으로 불일치. + +### 2. grounding 실패의 세 가지 계층 + +재오픈 20개 중 expect_evidence=True인 11건을 분석한 결과, 실패는 세 계층에서 발생한다: + +#### A. 검색 계층 실패 (8건) — 근본 원인 + +검색이 관련 문서를 찾지 못함: +- keyword_score 전부 0.000 (위 원인) +- 벡터 검색도 의미적으로 엉뚱한 문서를 반환 (본점 소재지 변경 공문, 고유번호증 등) +- **옐로펀치 협약 문서를 원문 그대로 쿼리해도 top-5에 미등장** → 임베딩 공간에서 해당 청크가 쿼리와 먼 위치에 있거나 인덱싱 문제 + +해당 질문들: +- 오늘전통+옐로펀치 근거 +- Company X 프로그램 운영 흐름 +- 주요 프로그램 목록 +- 옐로펀치 협력 범위 +- 오늘전통 대상/조건 +- Company X 조직도/팀 구성 +- Company X 슬로건/미션 + +#### B. 라우팅 계층 실패 (3건) — 마커 미매칭 + +`should_handle_companyx_grounding()`의 intent_markers/domain_markers에 걸리지 않아 grounding 경로 자체에 미진입: + +| 질문 | 이유 | +|------|------| +| IR 채널 투자사 리스트 | `IR 채널` 마커 없음 | +| 프로그램 참여 기업 선정 기준 | 일반 질문, 마커 없음 | +| 프로그램 운영 기간/일정 | 일반 질문, 마커 없음 | + +이 케이스는 일반 챗봇 경로로 빠져서 "홍태주님, 확인해보니..." 톤으로 응답. + +#### C. LLM 판단 계층 (정상 동작) + +검색이 무관한 문서를 반환하면 LLM이 `failure_reason`을 설정하여 실패 응답 생성. 이는 엉뚱한 문서로 답변하는 것보다 나은 정상 동작. + +## 원인 요약 + +| 실패 | 직접 원인 | 계층 | +|------|----------|------| +| keyword recall = 0 | `simple` 토크나이저가 한국어 조사 분리 불가 | DB/인덱스 | +| 인덱싱 문서 있는데 검색 실패 | 벡터 임베딩이 해당 청크를 근접 이웃으로 잡지 못함 + keyword 보완 불가 | 검색 | +| 3건 grounding 미진입 | intent/domain 마커에 일반 질문 패턴 미포함 | 라우팅 | + +## 해결 방향 (구현은 별도 계획) + +### keyword recall 개선 옵션 + +| 옵션 | 방식 | 장점 | 단점 | +|------|------|------|------| +| prefix 매칭 | tsquery에 `:*` 접미 | 즉시 적용, recall 27%→90% | 복합어 내부 매칭 불가 | +| trigram (pg_trgm) | `chunk_text % :query` | 부분 문자열 매칭 가능 | GIN 인덱스 추가 필요, 정밀도 낮음 | +| 한국어 형태소 분석 | mecab + textsearch_ko | 근본 해결 | 확장 설치 필요 (51123 서버) | +| 하이브리드 보완 | ILIKE fallback | 간단 | 인덱스 미사용, 느림 | + +### 벡터 검색 품질 개선 + +- 200개 인덱싱 대상에 옐로펀치 협약/오늘전통 문서가 포함되어 있는지 확인 필요 +- 포함되어 있다면 청킹 경계에서 핵심 내용이 잘리는지 확인 +- 임베딩 모델(Gemini 768d)의 한국어 고유명사 처리 능력 검증 + +### 라우팅 마커 확장 + +- Company X team_id 사용자의 질문은 마커 없이도 grounding 시도하는 옵션 검토 +- 또는 일반 질문 패턴 마커 추가 (단, 하드코딩 확장은 금지 원칙에 저촉) + +## 검증에 사용한 데이터 + +- 테스트 결과: `/home/admin/robeing/tests/results/hybrid_vs_vector_comparison.json` +- 검증 스크립트: `/home/admin/robeing/tests/test_companyx_rag_hybrid.py` +- DB 실측: 51123 서버 `main_db.team_document_chunk` (team_id: `79441171-...`) + +## 관련 문서 + +- [260320 로빙 다형식문서 RAG 적용1 계획](../../plans/260320_로빙_다형식문서_RAG_적용1_계획.md) +- [260315 companyx rag 답변합성 시나리오동시종결 리서치](../260315_companyx_rag_답변합성_시나리오동시종결_리서치.md)