6개월간 RAG를 수정하며 발견하고 구축한 것들
요약
표준 RAG 시스템이 멀티홉 질문에서 겪는 의미론적 드리프트와 컨텍스트 오염 문제를 해결하기 위한 6개월간의 디버깅 과정을 다룹니다. 저자는 이를 해결하기 위해 의미론적, 구문론적, 인과적 축을 결합한 삼중 벡터 인코딩(Tri-Vector Encoding) 기술을 포함한 7개 레이어의 VORTEXRAG 프레임워크를 구축했습니다.
핵심 포인트
- 표준 RAG는 멀티홉 질문 시 쿼리 재구성 과정에서 발생하는 의미론적 드리프트와 잘못된 정보가 섞이는 컨텍스트 오염에 취약함
- 단일 벡터 임베딩의 정보 압축 한계를 극복하기 위해 의미론적(Semantic), 구문론적(Syntactic), 인과적(Causal) 축을 결합한 삼중 벡터 인코딩(TVE) 제안
- 특히 인과적 축(Causal arm)은 단순 유사성을 넘어 'X가 Y를 유발한다'와 같은 관계성을 포착하여 검색 정확도를 높임
- VORTEXRAG는 특정 실패 모드를 방어하기 위해 설계된 7개의 레이어로 구성된 프레임워크임
이것은 연구 논문으로 발전하게 된 디버깅 세션에 관한 이야기입니다.
모든 일의 시작이 된 버그
저는 문서 Q&A 시스템을 구축하고 있었습니다. 특별할 것 없는 표준적인 RAG (Retrieval-Augmented Generation) 설정이었습니다. FAISS 인덱스, SBERT 임베딩 (embeddings), 그리고 리더 (reader)로서의 GPT를 사용했습니다. 전형적인 방식이었죠. 간단한 질문에는 잘 작동했습니다. "환불 정책은 무엇인가요?" → 정확한 답변.
그다음, 저는 멀티홉 (multi-hop) 질문으로 테스트를 진행했습니다: "4.2절에 설명된 제조 공정에 사용되는 화학 물질을 처리하는 시설의 환경 준수 요구 사항은 무엇인가요?"
모델의 답변은 자신감이 넘쳤고, 상세했습니다. 그리고 완전히 틀렸습니다. 검색된 문서들은 모두 그곳에 있었습니다. 정답을 맞히기 위해 필요한 모든 정보가 컨텍스트 윈도우 (context window) 안에 있었습니다. 하지만 모델은 어떤 문서에도 나타나지 않는 숫자를 환각 (hallucination) 했습니다.
저는 로그를 남기기 시작했습니다. 제가 발견한 것은 두 가지 뚜렷한 실패 모드 (failure modes)가 동시에 발생하고 있다는 점이었습니다:
실패 모드 1: 의미론적 드리프트 (Semantic Drift). 멀티홉 검색을 위해 쿼리 (query)가 재구성되는 과정에서, 임베딩 (embedding)이 원래의 의도에서 너무 멀리 벗어나 잘못된 문서를 검색하게 되었습니다. 약간 틀린 수준이 아니었습니다. 코퍼스 (corpus)의 완전히 다른 섹션에 있는 문서들이었습니다.
실패 모드 2: 컨텍스트 오염 (Context Poisoning). 대부분 정확한 문서를 검색했을 때조차, 1~2개의 부수적으로 관련되어 있지만 모순되는 청크 (chunks)들이 섞여 들어왔습니다. 그리고 그 오염된 청크들은 모델을 탈선시키기에 충분했습니다.
표준 RAG는 이 두 가지에 대한 방어 기제가 없습니다. 파이프라인은 본질적으로 다음과 같습니다: 임베딩 (embed) → 검색 (retrieve) → 컨텍스트에 채워넣기 (stuff into context) → 기도하기 (hope). 저는 더 나은 무언가가 필요했습니다.
6개월 후: VORTEXRAG
오늘 전체 프레임워크를 공개합니다. 7개의 레이어 (layers)로 구성되어 있으며, 각 레이어는 특정 실패 모드를 겨냥합니다. 제가 무엇을 구축했는지, 그리고 각 레이어가 왜 존재하는지 설명하겠습니다.
레이어 1: 삼중 벡터 인코딩 (Tri-Vector Encoding, TVE)
문제점: 단일 벡터 임베딩 (single-vector embeddings)은 너무 많은 정보를 압축해 버립니다. "은행이 수수료를 부과했다"와 "강둑이 가팔랐다"는 대부분의 검색 컨텍스트에서 의미론적으로 관련이 없음에도 불구하고, SBERT 공간에서는 유사한 임베딩을 공유합니다.
해결책: 세 가지 인코딩 축 (Three encoding arms):
- 의미론적 축 (Semantic arm): 표준 SBERT 768d
s = sbert_model.encode(chunk) # shape: (768,) - 구문론적 축 (Syntactic arm): 품사 (POS) + 의존 구조 (dependency structure)
t = syntactic_encoder(chunk) # shape: (64,) - 인과적 축 (Causal arm): 동사-논항 체인 (verb-argument chains)
c = causal_encoder(chunk) # shape: (32,)
융합 벡터 (Fused vector):
v = concat([α·s, β·t, γ·c]) # shape: (864,)
인과적 축 (Causal arm)이 핵심적인 혁신입니다. 이는 순수하게 의미론적 유사성 (semantic similarity)만으로는 완전히 놓치기 쉬운 "X가 Y를 유발한다"는 관계를 포착합니다. 이를 통해 파이프라인은 특정 개념을 단순히 언급하는 문서와 그 이면의 인과 기제 (causal mechanism)를 설명하는 문서를 구분할 수 있게 됩니다.
레이어 2: Vortex Retrieval Cone (VRC)
문제점: 평면적인 코사인 유사도 (flat cosine similarity)는 유사도가 높은 모든 문서를 동일하게 취급합니다. 하지만 정렬된 리스트 내의 문서 #1과 문서 #47이 동일한 가중치를 가져서는 안 됩니다. 관련성에는 자연스러운 하락 (falloff)이 존재하기 때문입니다.
해결책: 와류 역학 (vortex dynamics)에서 영감을 얻은 나선형 순위 지정 (Spiral ranking):
spiral_rank = TVE · e^(−λr) · cos(nθ)
여기서 r은 반경 거리 (radial distance, 순위 위치)이며, θ는 인과적 깊이 (causal depth)를 인코딩하는 각 위상 (angular phase)입니다. 인과적 관련성이 높은 문서는 위상상의 이점을 얻어, 약간 낮은 의미론적 유사도 점수를 극복할 수 있습니다.
실제 적용 시: VRC에 의해 반환된 상위-k (top-k) 문서들은 동일한 인덱스에서 평면적인 코사인 검색 (flat cosine search)으로 반환된 문서들보다 인과적으로 더 밀도가 높습니다.
레이어 3: Semantic Drift Corrector (SDC)
문제점: 멀티홉 쿼리 (Multi-hop queries)는 각 홉 (hop)을 거칠 때마다 스스로를 재구성합니다. 각 재구성 과정에서 원래의 의도로부터 조금씩 이탈 (drift)할 수 있습니다. 3~4번의 홉을 거치면, 이 오차는 누적되어 완전히 다른 쿼리가 되어버립니다.
해결책: 임베딩 궤적 (embedding trajectory)을 추적합니다. 각 홉에서:
drift = query_embedding - anchor_embedding
SDS = 1 - tanh(np.linalg.norm(drift) / τ)
if SDS < 0.72:
query_embedding = re_anchor(query_embedding, anchor_embedding)
SDS 점수 (Semantic Drift Score)는 우리가 얼마나 멀리 이탈했는지를 측정합니다. 점수가 0.72 미만이면, 원래 쿼리 의도에 다시 고정 (re-anchor)합니다. 이 단 한 번의 개입만으로도 멀티홉 환각 (multi-hop hallucinations) 현상의 대부분을 제거할 수 있었습니다.
Layer 4: 컨텍스트 독성 방어 (Context Poison Guard, CPG)
문제점: 컨텍스트 윈도우 (context window) 내에 단 1~2개의 모순되거나 주제에서 벗어난 청크 (chunk)만 있어도 모델의 답변을 오염시키기에 충분합니다. 우리는 이러한 청크들이 LLM에 도달하기 전에 식별하고 제거할 방법이 필요했습니다.
해결책: 청크당 엔티티 돌출도 비율 (Entity-salience ratio per chunk, ESR): ESR = sum(SDS_i * w_i for each entity i) / (num_propositions + ε). 만약 ESR < 3.5라면: flag_for_purging(chunk). 이 제거 (purging) 알고리즘은 증명 가능한 탐욕적 최적 (greedy-optimal) 방식입니다 (논문에 정식 증명을 포함했습니다). 이 방식은 토큰 예산 (token budget)을 준수하면서 유지되는 컨텍스트 전체의 총 ESR을 최대화합니다. 어블레이션 연구 (ablation studies) 결과, CPG만 제거했을 때 충실도 (faithfulness)가 0.94에서 0.75로 떨어졌으며, 이는 단일 레이어만으로 0.19 포인트가 하락한 수치입니다.
Layer 5: 랭크 퓨전 게이트 (Rank Fusion Gate, RFG)
문제점: 대부분의 랭크 퓨전 (rank fusion) 방식은 가산적 (additive)입니다. 단 하나의 형편없는 신호가 섞여도 희석될 뿐, 나쁜 문서를 완전히 제거하지는 못합니다.
해결책: 승법적 퓨전 (Multiplicative fusion): Φ = TVE^α × SDS^β × ESR^γ. 세 가지 신호 중 어느 하나라도 0에 가깝다면, Φ는 0을 향해 붕괴합니다. 의미론적 유사도 (semantic similarity) 점수는 0.9이지만 CPG 점수가 0.1인 문서는 Φ ≈ 0.09를 얻게 되어 사실상 제거됩니다. 이는 의도적인 설계 선택이었습니다. 높은 이해관계가 걸린 검색 (high-stakes retrieval, 의료, 법률, 금융 분야)에서는 인기 투표가 아닌 거부권 (veto mechanism)이 필요하기 때문입니다.
Layer 6: 인과적 컨텍스트 빌더 (Causal Context Builder
해결책: 검색된 컨텍스트(retrieved context)에 대해 후보 답변의 점수를 측정합니다: ΔR = 1 - (ROUGE_L * NLI_entailment_score). 만약 ΔR > 0.15라면: regenerate_answer(). 답변이 소스 문서로부터 15% 이상 벗어날 경우 (NLI 함의(entailment)로 가중치를 둔 ROUGE-L로 측정), 해당 답변은 폐기되고 다시 생성됩니다. 이는 모델이 문장은 올바르게 바꾸어 말하지만(paraphrase) 중요한 숫자나 이름을 바꾸는 미묘한 환각(hallucination) 사례를 잡아냅니다.
4개의 표준 벤치마크(NQ, HotpotQA, MuSiQue, 2WikiMultiHopQA)에서 테스트된 결과:
| 시스템 | EM | F1 | 충실도 (Faithfulness) |
|---|---|---|---|
| Naive RAG | 61.2 | 68.4 | 0.71 |
| HyDE | 63.8 | 71.2 | 0.74 |
| Self-RAG | 65.4 | 73.1 | 0.79 |
| FLARE | 64.9 | 72.8 | 0.77 |
| VORTEXRAG | 74.8 | 82.6 | 0.94 |
Naive RAG 대비 EM +13.6, F1 +14.2, 충실도(Faithfulness) +0.23 향상되었습니다. 절제 연구(ablation study) 결과 7개의 모든 레이어가 기여하고 있음을 보여줍니다. 가장 큰 개별 기여 요소 두 가지는 CPG (+0.19 충실도)와 SDC (특히 멀티홉(multi-hop) 벤치마크에서 +0.08 EM)입니다.
빠른 시작 (Quick Start)
pip install vortexrag
from vortexrag import VortexRAG, VortexConfig
config = VortexConfig(
sdc_threshold=0.72,
cpg_esr_threshold=3.5,
fv_delta_r_threshold=0.15,
)
rag = VortexRAG(config)
rag.index(your_documents)
answer = rag.query("Your complex multi-hop question here")
다음 단계 (What's Next)
이 프레임워크는 MIT 라이선스로 제공됩니다. (공식 증명이 포함된) 전체 연구 논문은 Zenodo에 있습니다. 만약 RAG 시스템을 구축하면서 환각(hallucination) 문제에 부딪히고 있다면 — 특히 멀티홉(multi-hop) 또는 도메인 특화(domain-specific) 질의에서 — 이 프레임워크는 정확히 그 문제를 해결하기 위해 설계되었습니다.
GitHub: https://github.com/vignesh2027/VORTEXRAG
논문: https://doi.org/10.5281/zenodo.20285144
라이브 데모 문서: https://vignesh2027.github.io/VORTEXRAG
질문이 있으신가요? 댓글로 남겨주세요. 어떤 레이어에 대해서든 깊이 있게 다룰 준비가 되어 있습니다.
AI 자동 생성 콘텐츠
본 콘텐츠는 Dev.to AI tag의 원문을 AI가 자동으로 요약·번역·분석한 것입니다. 원 저작권은 원저작자에게 있으며, 정확한 내용은 반드시 원문을 확인해 주세요.
원문 바로가기