본문으로 건너뛰기

© 2026 Molayo

Dev.to헤드라인2026. 06. 07. 20:36

인과 관계를 실제로 이해하는 RAG 시스템을 구축하기 위해 보낸 4개월 — 내가 배운 것들 (그리고 그 뒤에 숨겨진 수학)

요약

기존 RAG 시스템이 겪는 '컨텍스트 윈도우 포이즈닝'과 '의미론적 표류' 문제를 분석하고, 이를 해결하기 위해 인과 관계를 이해하는 VORTEXRAG를 구축한 과정을 다룹니다. 단순 유사도 기반 검색의 한계를 지적하며 인과적 추론의 중요성을 강조합니다.

핵심 포인트

  • 코사인 유사도 기반 검색은 주제적 연관성은 찾지만 인과 관계는 구분 못 함
  • 컨텍스트 윈도우 포이즈닝으로 인해 LLM이 잘못된 서사를 생성할 수 있음
  • 단순 연관된 정보와 실제 원인을 구분하는 것이 RAG의 핵심 과제임
  • VORTEXRAG를 통해 인과 관계 중심의 검색 시스템 구축 시도

"ML(머신러닝) 커뮤니티 전체가 이미 해결되었다고 말하는 무언가를 만드는 데 4개월을 보냈습니다. 알고 보니, 그렇지 않았습니다.""

오늘날 프로덕션(production)에서 실행되는 모든 RAG(Retrieval-Augmented Generation, 검색 증강 생성) 시스템에 대해 불편한 진실 하나를 말씀드려야겠습니다.

그것들은 모두 같은 방식으로 망가져 있습니다. 그리고 거의 아무도 이에 대해 이야기하지 않습니다.

작동하지 않는다는 뜻이 아닙니다. 대부분의 경우 잘 작동합니다. 하지만 정확한 문서를 검색했을 때조차 환각(hallucination)을 일으키게 만드는 두 가지 조용한 실패 모드(failure modes)가 존재합니다. 이 문제로 몇 달 동안 머리를 싸매며 고민한 끝에, 저는 이 두 가지를 모두 해결하기 위해 VORTEXRAG를 구축했습니다. 이것은 그 과정에 대한 이야기입니다.

무언가 깊이 잘못되었다는 것을 깨달은 날

저는 금융 Q&A 시스템을 구축하고 있었습니다. SEC(미국 증권거래위원회) 공시 자료 코퍼스(corpus)를 인덱싱하고, 기업들이 왜 그런 성과를 냈는지에 대한 질문에 답하는 비교적 간단한 작업이었습니다.

질의(query): "왜 X사의 3분기 매출이 감소했습니까?"

저의 RAG 파이프라인(pipeline)은 올바른 문서를 검색했습니다. 로그를 통해 확인할 수 있었습니다. CEO가 공급망 중단에 대해 설명한 실제 실적 발표(earnings call) 녹취록이었습니다. 코사인 유사도(Cosine similarity): 0.91. 완벽했습니다.

하지만 LLM(대규모 언어 모델)의 답변은 완전히 틀렸습니다. 거시 경제 상황, 금리 민감도, 업계 전반의 역풍에 대해 이야기했습니다. 모두 _업계_에 대해서는 사실적으로 맞는 내용들이었습니다. 하지만 그 중 어느 것도 _실제 원인_은 아니었습니다.

저는 컨텍스트 윈도우(context window)를 조사했습니다. 올바른 청크(chunk)가 그곳에 있었습니다. 하지만 그 청크는 다른 7개의 청크에 둘러싸여 있었습니다:

  • 해당 기업의 10-K 위험 요인 (유사도: 0.87)
  • 업계 성과에 대한 애널리스트 보고서 (유사도: 0.84)
  • 해당 분기에 대한 연준(Fed)의 논평 (유사도: 0.82)
  • 주제와는 관련이 있지만 인과 관계는 없는 세 개의 추가 구절들

LLM은 이 모든 것을 보았습니다. 그리고 그것들을 평균화했습니다. 그 결과, 듣기에는 매우 그럴듯하지만 _이 특정 기업_에 대해서는 사실과 다른 서사를 환각해 냈습니다.

저는 **컨텍스트 윈도우 포이즈닝(Context Window Poisoning)**을 발견했습니다. 그리고 저도 모르게 몇 달 동안 이 문제와 싸워오고 있었던 것입니다.

아무도 완전히 해결하지 못한 두 가지 문제

그 순간 이후, 저는 깊이 파고들었습니다. 지난 3년 동안 발표된 모든 RAG 논문을 읽었습니다. Self-RAG, CRAG, RAG-Fusion, FiD, REALM, Atlas, Toolformer — 그 모든 것들을 말이죠. 훌륭한 논문들이었고, 똑똑한 사람들이었으며, 유의미한 발전들이었습니다.

하지만 그중 어느 것도 제가 목격하고 있는 문제를 완전히 해결하지는 못했습니다. 그 이유는 다음과 같습니다.

문제 1: 의미론적 표류 (Semantic Drift) 🎯

오늘날의 모든 RAG 시스템은 **코사인 유사도 (cosine similarity)**를 통해 검색을 수행합니다. 이는 주제적으로 관련된 콘텐츠를 찾는 데는 매우 효과적입니다. 하지만 다음과 같은 차이를 근본적으로 구분할 수 없습니다.

  • 무언가를 유발한 (caused) 청크 (Chunk)
  • 단순히 그것과 연관된 (associated) 청크

_"리먼 브라더스는 왜 붕괴했는가?"_라고 질문해 봅시다.

표준 RAG의 결과:

청크 (Chunk)유사도 (Similarity)인과 관계 (Causal)?
도드-프랭크 법(Dodd-Frank Act) 조항0.87❌ 붕괴에 대한 대응
CDS 가격 책정 오류 메커니즘0.91✅ 실제 원인
시스템적 리스크 보고서0.85❌ 결과
베어스턴스(Bear Stearns) 비교0.83❌ 병행 사건

LLM은 이 네 가지를 모두 가져옵니다. 그리고 규제 실패와 시스템적 리스크에 관한 답변을 생성합니다. CDS에 대해서는 전혀 언급하지 않습니다. 이 답변은 100% 환각 (hallucination)입니다. 실제 문서들로부터 구성되었지만, 잘못된 인과 사슬로 조립된 결과입니다.

이것이 바로 의미론적 표류 (Semantic Drift)입니다: 검색된 컨텍스트가 인과적 관련성에서 주제적 연관성으로 표류하는 현상입니다.

문제 2: 컨텍스트 윈도우 오염 (Context Window Poisoning) ☠️

설령 올바른 청크를 검색하더라도, 주변에 7개의 잘못된 청크가 있다면 LLM의 어텐션 (attention)은 희석됩니다. 이는 추측이 아닙니다. "Lost in the Middle" 논문 (Liu et al., 2023)에 의해 뒷받침되는 사실입니다. LLM은 **U자형 회상 곡선 (U-shaped recall curve)**을 가집니다. 컨텍스트의 시작과 끝은 가장 잘 기억하지만, 중간에 있는 정보는 체계적으로 놓칩니다.

따라서 올바른 청크가 컨텍스트 윈도우(context window) 안에 있더라도, 8개의 청크 중 4번째 위치에 놓인다면 LLM은 기능적으로 이를 무시할 수 있습니다.

이것이 바로 컨텍스트 윈도우 오염 (Context Window Poisoning)입니다: 컨텍스트 윈도우 내의 신호 대 잡음비 (noise-to-signal ratio)가 올바른 정보를 사용하려는 LLM의 능력을 파괴하는 현상입니다.

VORTEXRAG 구축하기: 4개월, 7개의 레이어, 하나의 집착

저는 단순한 질문 하나로 시작했습니다: 두 가지 문제를 동시에 해결하려면 무엇이 필요할까?

그 답은 7개의 레이어로 구성된 파이프라인이었습니다. 각 레이어는 특정한 실패 모드 (failure mode)를 해결합니다. 각 레이어가 무엇을 하는지뿐만 아니라, 왜 제가 그것을 구축했는지에 대해 설명해 드리겠습니다.

레이어 1: TVE — Tri-Vector Encoding (삼중 벡터 인코딩) 🔺

통찰 (The insight): 만약 유사도 검색 (similarity retrieval)이 인과 관계 (causality)를 포착할 수 없다면, 인과 관계를 직접 인코딩해야 합니다.

표준 RAG는 텍스트를 단일한 의미론적 벡터 (semantic vector, 보통 768차원)로 임베딩합니다. VORTEXRAG는 모든 청크 (chunk)를 **864차원의 삼중 벡터 (tri-vector)**로 인코딩합니다:

TVE score = α·cos_sem + β·cos_syn + γ·cos_cau

Where:
...

인과 관계 측면 (causal arm, 32차원)은 PropBank 스타일의 의미 역할 레이블 (semantic role labels)을 인코딩합니다: ARG0 (행위자, agent), ARG1 (대상, patient), ARGM-CAU (원인, cause), ARGM-EFF (결과, effect). "CDS가 리먼 브라더스의 붕괴를 초래했다"라는 청크는 "도드-프랭크 법이 붕괴에 대응했다"라는 청크와 비교했을 때, 쿼리 (query)와의 의미론적 유사도 (semantic similarity)가 동일하더라도 매우 다른 인과 벡터 (causal vector)를 가집니다.

이것이 다른 모든 것들이 구축되는 토대입니다.

레이어 2: VRC — Vortex Retrieval Cone (소용돌이 검색 원뿔) 🌀

통찰 (The insight): 검색은 리스트가 아니라 _기하학 (geometry)_입니다.

전통적인 top-k 검색은 후보군을 순위가 매겨진 리스트로 취급합니다. VORTEXRAG는 인과 벡터 공간 (causal vector space) 내에서 검색을 **나선형 확률 표면 (spiral probability surface)**으로 모델링합니다:

spiral_rank = TVE · e^(−λr) · cos(nθ)

Where:
...

핵심 항은 cos(nθ)입니다. 인과 방향 (causal direction)이 쿼리의 인과 방향으로부터 π/4 (45°) 이상 벗어난 청크들은 **기하학적으로 억제 (geometrically suppressed)**됩니다. 즉, 의미론적 유사도와 상관없이 이들의 나선형 순위 (spiral rank)는 0을 향해 떨어집니다. "소용돌이 (vortex)" 형태는 방사형 감쇠 (radial decay)와 각도 억제 (angular suppression)를 결합하여 나타납니다. 검색된 청크들은 리스트가 아닌 원뿔 (cone) 형태를 이룹니다.

레이어 3: SDC — Semantic Drift Corrector (의미론적 드리프트 교정기) 🛡️

통찰 (The insight): 드리프트 (drift)를 명시적으로 측정하고, 이를 기준으로 필터링하십시오.

각 후보 청크에 대해, SDC는 **의미론적 드리프트 점수 (Semantic Drift Score)**를 계산합니다:

D = v_cau(query) − v_cau(chunk)    ← 인과 드리프트 벡터 (causal drift vector)
SDS = 1 − tanh(‖D‖ / τ)           ← 드리프트 점수 (drift score) ∈ [0, 1]

‖D‖가 높을수록 해당 청크의 인과 구조(causal structure)가 쿼리로부터 더 많이 벗어났음을 의미합니다. τ는 민감도를 조절하며, 여기서 **11개의 도메인 프리셋 (11 domain presets)**이 사용됩니다:

도메인 (Domain)τ이유 (Why)
과학 (Scientific)0.30엄격함: 인과 관계 체인 (cause-effect chains)이 매우 긴밀해야 함
...

레이어 4: CPG — 컨텍스트 포이즌 가드 (Context Poison Guard) ⚗️

통찰 (The insight): 개별 청크뿐만 아니라 전체 윈도우 (window)가 건강해야 합니다.

각 청크가 개별적으로 SDC를 통과하더라도, 청크들의 _조합_이 여전히 컨텍스트를 오염시킬 수 있습니다. CPG는 전체 윈도우의 **유효 신호 비율 (Effective Signal Ratio, ESR)**을 측정합니다:

ESR = Σ(SDS_i · w_i) / (P + ε)

여기서:
...

만약 ESR < 3.5라면, CPG는 **탐욕적 제거 (greedy purge)**를 실행합니다: SDS 점수가 가장 낮은 청크를 제거합니다. 그 후 ESR을 다시 계산합니다. ESR ≥ 3.5가 될 때까지 이 과정을 반복합니다.

정리 5.1 (Theorem 5.1) (논문에서 증명됨): 최소 SDS 청크를 제거하는 것이 단계당 ESR 개선을 극대화합니다. 이 탐욕 알고리즘 (greedy algorithm)은 증명 가능한 최적의 방식입니다. 즉, 다른 어떤 단일 단계 제거 방식도 이보다 더 나은 ESR 증가를 만들어낼 수 없습니다.

이 정리는 CPG를 휴리스틱 (heuristic) 접근 방식과 구분 짓는 핵심입니다. 단순히

레이어 6: CCB — 인과 관계 컨텍스트 빌더 (Causal Context Builder) 🏗️

통찰 (The insight): 컨텍스트 윈도우 (context window) 내의 어느 위치에 정보를 배치하느냐가 매우 중요합니다.

"Lost in the Middle" 연구에 따르면, LLM은 위치 0(시작점)과 컨텍스트의 끝부분 근처에서 정보를 가장 잘 회상합니다. 중간 부분은 정보의 무덤과 같습니다.

CCB는 인과 의존성 그래프 (causal dependency graph)를 구축하고 위치를 할당합니다:

pos = rank(Φ+) × causal_depth

depth-0 root-cause chunks → 항상 pos = 0에 배치

인과적 근본 원인 (causal root) — 즉, _왜 (why)_를 설명하는 청크가 항상 가장 먼저 옵니다. 이를 뒷받침하는 증거들이 인과 순서에 따라 뒤따릅니다. 이를 통해 LLM은 자신이 가장 잘 주의를 기울일 수 있는(attending to) 정확한 위치에서 가장 중요한 정보를 전달받게 됩니다.

레이어 7: FV — 충실도 검증기 (Faithfulness Verifier) ✅

통찰 (The insight): LLM을 믿지 마세요. 측정하세요.

생성 후, FV는 다음을 계산합니다:

ΔR = 1 − ROUGE-L(answer, context) × NLI_score(answer, context)

ΔR ≤ 0.15 이면 수락

만약 ΔR > 0.15 (답변의 15% 이상이 컨텍스트에 근거하지 않음)라면, FV는 응답을 거부하고, 컨텍스트를 재순위화(rerank)한 뒤, 최대 3회까지 재시도합니다. NLI (Natural Language Inference)를 위해 DeBERTa-v3-small CrossEncoder를 사용합니다.

이것이 마지막 안전장치입니다. 이전 6개의 레이어가 모두 완벽하게 작동하더라도 LLM은 여전히 환각 (hallucination)을 일으킬 수 있습니다. FV는 환각을 측정 가능하고 포착 가능한 상태로 만듭니다.

결과 — 229번의 테스트와 6개의 벤치마크 이후

저는 표준 QA 벤치마크 제품군인 NQ, TriviaQA, WebQ, PopQA, HotpotQA, 2WikiMultiHopQA를 통해 VORTEXRAG를 테스트했습니다.

전체 성능

시스템EMF1충실도 (Faithfulness)의미론적 드리프트 (Semantic Drift)컨텍스트 오염 (Context Poisoning)지연 시간 (Latency)
VORTEXRAG74.882.60.9414%7%185ms
...
Naive RAG 대비 EM +13.6 증가. Self-RAG 대비 EM +6.4 증가. Self-RAG보다 2.2배 빠름.

데이터셋별 세부 분석

데이터셋 (Dataset)VORTEXRAGSelf-RAGΔ여기서 VORTEXRAG가 승리하는 이유
NQ74.167.2+6.9단일 홉 (Single-hop) 인과 관계 질의
...

가장 큰 성능 향상은 멀티 홉 (multi-hop) 데이터셋에서 나타났으며, 이는 바로 인과 추론 (causal reasoning)이 가장 중요한 지점입니다. 이것이 바로 제가 기대했던 검증 결과입니다.

절제 연구 (Ablation): 모든 레이어는 제 자리를 찾았다

가장 뿌듯했던 순간 중 하나는 절제 연구 (ablation study)를 수행했을 때입니다. 일부 레이어가 아무런 기여를 하지 못할까 봐 두려웠지만, 모든 레이어가 기여하고 있었습니다.

구성 (Configuration)EMF1충실도 (Faithfulness)+EM
A: Naive RAG 베이스라인61.269.40.71
...

단 하나의 레이어도 예외 없이 기여합니다. 불필요한 요소는 없습니다.

인간 평가 (Human Evaluation) — 가장 중요한 수치

자동화된 지표 (Automatic metrics)에는 한계가 있습니다. 저는 3명의 도메인 전문가(NLP 연구자, 현직 변호사, 생물 의학 과학자)를 통해 4가지 차원에서 각각 150개의 응답을 5점 리커트 척도 (5-point Likert scales)로 평가하도록 했습니다.

차원 (Dimension)VORTEXRAGSelf-RAGNaive RAG
사실적 정확도 (Factual Accuracy)4.5/53.9/53.2/5
...

Self-RAG 대비 인과적 일관성 (Causal Coherence)에서 나타난 +0.9는 제가 가장 자랑스럽게 생각하는 부분입니다. 이는 실제 도메인의 실제 사람들이 VORTEXRAG의 답변에 담긴 인과 추론이 현저히 더 뛰어나다고 판단했음을 의미합니다. 그 어떤 자동화된 지표도 이를 온전히 포착할 수 없습니다.

지금 바로 시도해보세요

5분 퀵스타트 (Quickstart)

git clone https://github.com/vignesh2027/VORTEXRAG
cd VORTEXRAG
pip install -r requirements.txt
...

첫 번째 인과 관계 질의 (Causal Query)

from vortexrag import VortexRAG

# 도메인을 선택하세요 — 파라미터가 자동 보정됩니다
...

레이어별 추적 (Layer-by-Layer Trace) (실제로 보게 될 화면)

Layer 1 [TVE]: 847개의 청크를 864차원 삼중 벡터 (tri-vectors)로 인코딩함 (8.2ms)
Layer 2 [VRC]: 상위 50개 후보를 나선형 순위 지정 (Spiral-ranked) (2.1ms)
              각도 억제 (Angular suppression): 12개 청크 억제됨 (θ > π/4)
...

이것을 구축하며 배운 것들

이것을 구축하며 배운 것들

1. 코사인 유사도 (Cosine similarity)는 지역 최적점 (local optima)이다. 전체 분야가 코사인 유사도를 중심으로 너무 강력하게 최적화된 나머지, 그것이 실체가 아닌 대리 지표 (proxy)일 뿐이라는 사실을 잊고 있었다. 인과적 관련성 (Causal relevance)이야말로 실체 그 자체다.

2. 모든 레이어 (layer)는 존재해야 할 수학적 근거가 필요하다. 개발 과정에서 3개의 레이어를 버렸는데, 그 레이어들이 최적인지 혹은 정당한지조차 증명할 수 없었기 때문이다. 정리 5.1 (Theorem 5.1, CPG 최적성)을 증명하는 데 3주가 걸렸지만, 그만한 가치가 있었다.

3. 지연 시간 (Latency)은 하나의 기능 (feature)이다. 185ms의 지연 시간에서 VORTEXRAG는 훨씬 더 많은 작업을 수행함에도 불구하고 Self-RAG보다 2.2배 더 빠르다. 왜일까? Self-RAG는 여러 개의 초안 응답을 생성한 뒤 선택하는 방식을 취하기 때문이다. VORTEXRAG의 생성 전 필터링 (pre-generation filtering) 방식은 LLM이 깨끗하고 작은 컨텍스트 (context)를 보고 단 한 번만 생성하게 만든다. 적을수록 많다 (Less is more).

4. 인간 평가 (Human evaluation)는 대체 불가능하다. 나의 생물 의학 전문가가 다단계 효소 경로 (multi-step enzyme pathway) 질문에서 EM, F1, 그리고 충실도 (faithfulness) 지표가 모두 놓친 실패 모드 (failure modes)를 잡아냈다. 자동화된 지표 (Automatic metrics)는 필요하지만 충분하지는 않다.

내가 거의 공유하지 않을 뻔했던 부분

AI 자동 생성 콘텐츠

본 콘텐츠는 Dev.to AI tag의 원문을 AI가 자동으로 요약·번역·분석한 것입니다. 원 저작권은 원저작자에게 있으며, 정확한 내용은 반드시 원문을 확인해 주세요.

원문 바로가기
0

댓글

0