RAG 테이블 청킹 시각적 비교 및 pgvector 하이브리드 RRF 벤치마크를 위한 로컬 FastAPI 워크벤치 구축
요약
본 기사는 RAG 파이프라인에서 발생하는 청킹 오류 및 검색 성능 문제를 다루며, 로컬 FastAPI 워크벤치를 구축하여 벤치마킹 결과를 제시합니다. pgvector와 전체 텍스트 검색(FTS)을 결합한 하이브리드 역순위 융합(RRF) 전략이 순수 벡터 또는 FTS 대비 모든 지표에서 압도적인 성능(Recall@5: 100.0%)을 보여주었습니다.
핵심 포인트
- 기본 청커는 마크다운 테이블 등 구조화된 데이터의 행 중간 부분을 잘라낼 수 있습니다.
- 하이브리드 RRF 검색은 Recall@5, MRR@10에서 100.0%와 1.000으로 최고 성능을 기록했습니다.
- 로컬 워크벤치를 통해 API 비용 없이 재현 가능하고 신뢰성 높은 벤치마킹이 가능합니다.
- 순수 밀집 벡터 검색은 코드/SKU 같은 군집화된 항목에서 Recall@1 하락 문제가 있었습니다.
최근 FastAPI와 PostgreSQL을 사용한 RAG 파이프라인 작업을 진행하면서 세 가지 문제에 지속적으로 직면했습니다. 기본 문자(Default character) 및 슬라이딩 윈도우 스플리터(sliding-window splitters)가 마크다운(Markdown)이나 PDF 금융 테이블의 행 중간 부분을 조용히 잘라냈고, 슬라이딩 윈도우는 토큰 중복률이 80%를 초과하는 청크를 생성하여 LLM이 숫자를 환각(hallucinate)하게 만들었습니다. 모든 커밋에 대해 클라우드 LLM-as-a-judge 평가를 수행하는 것은 너무 느렸고 OpenAI API 크레딧을 빠르게 소모했습니다. 비록 잘못된 답변의 90%가 단순히 결정론적 검색 누락(deterministic retrieval misses) 때문이었음에도 말입니다. 또한, pgvector와 전체 텍스트 검색(full-text search, ts_rank_cd)을 결합한 DIY 하이브리드 검색을 PostgreSQL에 연결하자, 어휘적 순위(lexical ranks)가 동률일 때마다 테스트 점수가 실행마다 무작위로 변동하는 문제가 발생했습니다. 그래서 저는 Python, FastAPI, 그리고 HTMX를 사용하여 로컬 진단 워크벤치를 구축했습니다 (Node나 npm 설정 없이 127.0.0.1:8787에서 실행). 이 워크벤치는 PostgreSQL 17과 pgvector 0.8.7을 기반으로 하며, Polars와 NumPy를 이용해 30개의 엔터프라이즈 청크(SEC 10-K 매출 테이블, 클라우드 DB 가격 매트릭스, WAL 장애 런북, 하드웨어 SKU 등)와 15개의 골든 쿼리를 대상으로 일대일 벤치마킹을 수행했으며 API 비용은 $0였습니다. 로컬에서 세 가지 검색 전략이 어떻게 작동했는지 보여드립니다:
순수 밀집 벡터 검색 (Pure Dense Vector Search, pgvector <=>)
Recall@1: 73.3% | Recall@3: 86.7% | Recall@5: 100.0% | MRR@10: 0.819 | 지연 시간(Latency): 1.23 ms | API 비용: $0.00
순수 희소 전체 텍스트 검색 (Pure Sparse Full-Text Search, ts_rank_cd)
Recall@1: 66.7% | Recall@3: 66.7% | Recall@5: 66.7% | MRR@10: 0.667 | 지연 시간(Latency): 0.74 ms | API 비용: $0.00
하이브리드 역순위 융합 (Hybrid Reciprocal Rank Fusion, pgvector + FTS + RRF)
Recall@1: 100.0% | Recall@3: 100.0% | Recall@5: 100.0% | MRR@10: 1.000 | 지연 시간(Latency): 1.99 ms | API 비용: $0.00
테스트 과정에서 두드러지게 나타난 세 가지 버그:
첫째, 정확한 오류 코드 및 SKU(예: ERR-PG-9042-WAL 또는 SKU-NVME-9940-REV-B)의 경우, 순수 밀집 벡터 검색은 같은 데이터베이스 런북에서 나온 청크들이 코사인 공간에 너무 가깝게 군집화되어 있어 Recall@1이 73.3%까지 떨어졌습니다.
생성된 TSVECTOR GIN 인덱스를 Reciprocal Rank Fusion (k=60)과 결합하여 정확한 SKU 및 오류 일치 항목을 항상 Rank 1로 끌어올렸습니다. 둘째, 키워드가 없는 의미적 패러프레이즈(semantic paraphrases)의 경우, 순수 Postgres 전체 텍스트 검색은 Recall@5가 0.0%로 떨어졌지만, Hybrid RRF는 HNSW 벡터 후보를 통해 100.0% Recall@5를 유지했습니다. 셋째, 인덱싱 전에 사전 인덱스 청크 스캐너(pre-index chunk scanner)를 실행하여 손상된 Markdown 테이블 2개(잘린 행 및 누락된 헤더 구분자), 토큰 중복률이 각각 90.3%와 94.1%인 슬라이딩 윈도우 청크 2개, 그리고 문장 중간에서 잘린 경우 2건을 포착했습니다.
또한 결정론적 타이브레이커(deterministic tiebreaker)를 강제하는 것(ORDER BY rrf_score DESC, id ASC)을 통해 CI 점수 변동 문제를 해결하고, SET LOCAL hnsw.iterative_scan = 'relaxed_order'를 사용하여 메타데이터 필터 고갈(metadata filter starvation)을 방지했습니다.
로컬에서 자체 청크를 테스트하고 싶은 분들을 위해 3열 시각적 테이블 차이점 스튜디오(visual table diff studio)의 전체 스크린샷, SQL 분석 내용, 그리고 CLI 건강 스캐너 및 30청크 벤치마크 데이터셋에 대한 무료($0) 다운로드 링크를 제 Dev.to 글에 여기에 올렸습니다: https://dev.to/mtalha5/what-broke-when-i-tested-pgvector-vs-postgres-full-text-search-vs-hybrid-rrf-on-30-tricky-rag-chunks-and-how-i-fixed-it-for-0
누구나 이상한 PDF 또는 Markdown 테이블 분할이나 pgvector HNSW 필터링 문제에 직면한다면, 저희가 사용했던 정확한 SQLAlchemy 2.0 비동기(async) RRF 쿼리를 공유해 드릴 수 있습니다.
RAG 테이블 청킹을 시각적으로 비교하고 pgvector Hybrid RRF를 $0 API 비용으로 벤치마크하기 위한 로컬 FastAPI 워크벤치를 구축했습니다. /u/Correct_Progress_231 제출 [링크] [댓글]
AI 자동 생성 콘텐츠
본 콘텐츠는 Reddit AI Engineering의 원문을 AI가 자동으로 요약·번역·분석한 것입니다. 원 저작권은 원저작자에게 있으며, 정확한 내용은 반드시 원문을 확인해 주세요.
원문 바로가기