RAG 분류 및 아키텍처: 프로덕션급 시스템을 위한 가이드
요약
프로덕션 환경에서 Naive RAG의 한계를 극복하기 위한 RAG 아키텍처의 진화 과정을 다룹니다. 단순 검색을 넘어 검색 전후 최적화와 모듈형 파이프라인을 활용한 고급 RAG 설계 전략을 제시합니다.
핵심 포인트
- Naive RAG의 한계: 잘못된 청킹, 의미론적 드리프트, 환각 문제 발생
- Advanced RAG: 쿼리 재작성, HyDE, 재순위화 등을 통한 검색 품질 개선
- Modular RAG: 조합 및 라우팅이 가능한 유연한 파이프라인 구축
- 8가지 핵심 패턴: GraphRAG, Agentic RAG, Self-RAG 등 다양한 아키텍처 활용
만약 당신이 주말 동안 "문서와 채팅하기" 프로토타입을 출시했다면, 축하합니다 — 당신은 **Naive RAG (단순 RAG)**를 구축한 것입니다. 그리고 그 시스템이 프로덕션 환경에서 다단계 질문(multi-hop questions)에 대해 환각(hallucination)을 일으키고, 표(table) 데이터에서 막히며, 엉뚱한 PDF를 자신 있게 인용하는 것을 목격했다면... 이 또한 축하드립니다. 당신은 왜 "RAG"가 단일 아키텍처가 아닌 하나의 설계 공간 (design space) 인지를 깨달은 것입니다.
이 글은 제가 동일한 파이프라인을 네 번이나 다시 구축하기 전에 가졌더라면 좋았을 지도입니다.
요약 (TL;DR)
- Naive RAG (검색 → 컨텍스트 삽입 → 생성)는 빠르게 한계에 부딪힙니다: 잘못된 청킹 (chunking), 의미론적 드리프트 (semantic drift), 쿼리 이해 부족, 자기 수정 기능 부재.
- **Advanced RAG (고급 RAG)**는 검색 전/후 최적화 (쿼리 재작성 (query rewriting), HyDE, 재순위화 (re-ranking))를 통해 검색 품질을 개선합니다.
- **Modular RAG (모듈형 RAG)**는 검색을 고정된 체인이 아닌, 조합 가능하고 라우팅 가능한 파이프라인으로 취급합니다.
- 알아둘 가치가 있는 8가지 아키텍처 패턴이 있습니다: Standard, Hybrid, GraphRAG, CRAG, Self-RAG, Adaptive RAG, Agentic RAG, 그리고 Multi-Modal RAG.
- 유행이 아니라 당신의 **실패 모드 (failure mode)**에 기반하여 선택하세요. 하단에 결정 매트릭스가 포함되어 있습니다.
본격적으로 시작해 보겠습니다.
왜 Vanilla RAG는 프로덕션 환경에서 무너지는가
"Hello World" 수준의 RAG 루프는 다음과 같습니다:
사용자 쿼리 (User Query) → 임베딩 (Embed) → 벡터 검색 (Vector Search, top-k) → 프롬프트에 삽입 (Stuff into Prompt) → LLM → 답변
PDF 20개 정도가 있는 데모에서는 아주 잘 작동합니다. 하지만 누군가 실제적인 질문을 던지면 상황이 무너집니다:
| 실패 모드 (Failure Mode) | 실제로 발생하는 현상 |
|---|---|
| 청킹 아티팩트 (Chunking artifacts) | 표가 행 중간에서 분할됨; 답변이 기술적으로는 "검색"되었으나 의미론적으로는 쓰레기임 |
| ... |
이 모든 것이 "RAG가 망했다"는 뜻은 아닙니다. Naive RAG는 MVP (최소 기능 제품)일 뿐, 최종 목적지가 아니라는 뜻입니다. 아래의 모든 내용은 프로덕션 팀이 다음에 지향해야 할 단계들입니다.
RAG의 3가지 패러다임
다양한 아키텍처를 살펴보기 전에, 시야를 넓히는 것이 도움이 됩니다. 대부분의 RAG 시스템은 세 가지 진화 단계 중 하나에 속합니다.
1. Naive RAG — 검색 (Retrieve) → 읽기 (Read) → 생성 (Generate)
┌─────────┐ ┌──────────┐ ┌────────────┐ ┌──────────┐
│ Query │ --> │ Embed │ --> │ Vector DB │ --> │ LLM │ --> Answer
└─────────┘ └──────────┘ │ (top-k) │ └──────────┘
단일 임베딩(Single embed) → 단일 검색(single retrieve) → 단일 생성(single generate). 피드백 루프(feedback loops), 쿼리 이해(query understanding), 교정(correction)이 없습니다. 이것은 기준점(baseline)일 뿐, 실제 제품이 아닙니다.
2. Advanced RAG — 검색 전후 최적화 (Optimize Before and After Retrieval)
Advanced RAG는 선형적인 형태를 유지하면서 두 가지 최적화 단계를 추가합니다.
Pre-retrieval (검색 전): 인덱스(index)에 도달하기 전에 _쿼리(query)_를 개선합니다.
- 쿼리 재작성 / 확장 (Query rewriting / expansion)
- HyDE (Hypothetical Document Embeddings) — 가상의 "이상적인 답변"을 생성하고, 원문 질문 대신 _그것_을 임베딩하여 검색합니다.
- 다중 부분 질문을 위한 쿼리 분해 (Query decomposition)
Post-retrieval (검색 후): LLM에 도달하기 전에 _컨텍스트(context)_를 개선합니다.
- 재순위화 (Re-ranking) (교차 인코더(cross-encoders), 예: Cohere Rerank, BGE-reranker)
- 컨텍스트 압축 / 필터링 (Contextual compression / filtering)
- 중복 제거 (MMR — Maximal Marginal Relevance)
Query --> [Rewrite / HyDE] --> Retrieve --> [Re-rank / Filter] --> LLM --> Answer
이것은 대부분의 팀이 더 복잡한 기술을 찾기 전에 수행해야 할 가장 높은 ROI(투자 대비 효율)를 가진 업그레이드입니다.
3. Modular RAG — 구성 가능, 라우팅 가능, 비선형적 (Composable, Routable, Non-Linear)
Modular RAG는 파이프라인을 고정된 체인으로 취급하는 것을 멈추고, 검색(retrieval), 라우팅(routing), 메모리(memory), 퓨전(fusion), 태스크 어댑터(task adapters)와 같이 서로 교체 가능한 모듈들의 그래프로 취급하기 시작합니다. 이는 루프(loops)를 포함하여 문제가 요구하는 방식에 따라 서로 연결됩니다.
┌─────────────┐
│ Router │
└──────┬───────┘
다음 섹션의 모든 패턴은 사실 Modular RAG 구성 요소들의 _특정 구성(specific configuration)_입니다.
8가지 현대적 RAG 아키텍처 패턴
1. Standard (Dense) RAG
클래식한 방식입니다. 순수 밀집 벡터 유사도 검색(dense vector similarity search) — 임베딩(embeddings)을 입력하여 코사인/내적 유사도(cosine/dot-product similarity)를 출력합니다.
[Query] --embed--> [Query Vector]
│
v
사용 사례: 정확한 키워드 일치(exact keyword matches)가 크게 중요하지 않은, 의미론적으로 풍부하고 비정형화된 텍스트 코퍼스(문서, 위키, 지원 문서)의 경우.
장점: 단순함, 빠른 구축 가능, 잘 지원되는 도구들 (pgvector, Pinecone, Qdrant, Weaviate).
단점: 정확한 일치(exact-match)가 필요한 항목(SKU, 에러 코드, 약어)을 식별하지 못함; 관련성(relevance) 보장 불가; 단발성(single-shot) 검색.
2. Hybrid RAG (하이브리드 RAG)
밀집 검색(Dense search)만으로는 정확한 일치 용어(ERR_402, 제품 코드, 고유 명사 등 임베딩이 구분하도록 학습되지 않은 항목)를 처리하는 데 실패합니다. Hybrid RAG는 밀집 벡터 검색(dense vector search)과 희소 키워드 검색(sparse keyword search, BM25)을 결합하며, 일반적으로 **상호 순위 결합 (Reciprocal Rank Fusion, RRF)**을 통해 통합됩니다.
┌──────────────┐
┌───────────►│ Dense Search │───────────┐
│ │ (embeddings) │ │
...
사용 사례: 의미론적 검색과 정확한 일치 검색 요구사항이 모두 존재하는 혼합 코퍼스 — 기술 문서, 법률 텍스트, 이커머스 카탈로그.
장점: 두 방식의 장점을 모두 갖춘 재현율(recall); 임베딩이 놓치기 쉬운 희귀 단어 또는 미등록 단어(OOV, Out-of-Vocabulary) 처리 가능.
단점: 유지 관리해야 할 인덱스가 두 개임; 결합 튜닝(RRF 상수 k, 가중치 설정)을 위한 추가적인 관리 요소 발생.
3. GraphRAG
벡터 검색은 모든 청크(chunk)를 고립된 섬처럼 취급합니다. GraphRAG는 벡터 인덱스와 병행하여 — 또는 대신하여 — 지식 그래프(엔티티 + 관계, 주로 Neo4j 사용)를 구축하므로, 검색 시 단순 유사성이 아닌 관계를 탐색(traverse)할 수 있습니다.
[Query] --> [Entity Extraction] --> [Graph Traversal]
│
┌─────────────────┼─────────────────┐
...
사용 사례: 관계에 대한 멀티 홉 추론(multi-hop reasoning)이 필요한 질문 — "회사 X가 의존하고 있으면서 동시에 지역 Y와 연결된 공급업체는 어디인가?" 벡터 검색은 이에 답할 수 없지만, 그래프 탐색은 가능합니다.
장점: 관계적/구조적 지식 포착; 컴플라이언스, 조직도, 의존성 매핑(dependency-mapping) 쿼리에 강력함.
단점: 구축 및 유지 관리 비용이 높음 (엔티티 추출 + 그래프 구축 파이프라인); 단순 조회 작업에는 과함(overkill).
4. Corrective RAG (CRAG)
CRAG는 검색 (Retrieval) 단계 이후에 **품질 게이트 (quality gate)**를 추가합니다. 경량 평가기 (lightweight evaluator)가 검색된 각 청크의 등급을 매깁니다 (정확함 / 모호함 / 부정확함). 만약 신뢰도가 낮다면, LLM이 잘못된 컨텍스트 (garbage context)를 바탕으로 답변을 생성하게 두는 대신, Tavily나 DuckDuckGo를 통한 웹 검색과 같은 외부 폴백 (external fallback)을 트리거합니다.
[Query] --> Retrieve --> [Relevance Grader]
│
┌─────────────────┼─────────────────┐
...
사용 시점: 코퍼스 (corpus)에 커버리지 공백이 있고, 확신에 찬 환각 (confident hallucination) 대신 우아한 성능 저하 (graceful degradation)가 필요할 때.
장점: 부적절한 검색으로 인한 환각 (hallucination)을 획기적으로 줄임; 자가 치유 (self-healing) 가능.
단점: 추가적인 지연 시간 (grading 단계 + 잠재적인 외부 호출); 평가기 (grader)의 품질이 튜닝해야 할 새로운 의존성 (dependency)이 됨.
5. Self-RAG
Self-RAG는 성찰 (reflection) 과정을 생성 (generation) 단계로 밀어붙입니다. 모델은 자신의 출력을 평가하는 성찰 토큰 (reflection tokens)을 내뱉도록 훈련되거나 프롬프트됩니다: 검색이 정말 필요한가? 생성된 답변이 검색된 구절들에 의해 뒷받침되는가? 유용한가?
[Query] --> [Retrieve?] --yes--> Retrieve --> Generate --> [Self-Critique]
│no │
v ┌──────────────────┼──────────────────┐
...
사용 시점: 별도의 검증 서비스 (verifier service)를 추가로 붙이지 않고도 내장된 환각 탐지 (hallucination detection) 기능이 필요할 때.
장점: 더 엄격한 충실도 (faithfulness) 보장; 불필요할 경우 검색을 완전히 건너뛸 수 있음 (지연 시간/비용 절감).
단점: 최상의 결과를 얻으려면 미세 조정 (fine-tuned)되거나 정교하게 프롬프트된 비판 (critique) 단계가 필요함; 기성 일반 모델 (off-the-shelf general model)로 잘 구현하기가 더 어려움.
6. Adaptive RAG
모든 쿼리가 동일한 양의 메커니즘을 필요로 하지는 않습니다. Adaptive RAG는 쿼리를 _복잡도 계층 (complexity tier)_에 따라 라우팅합니다. 분류기 (classifier)가 쿼리에 검색이 필요 없는지, 단일 단계 검색이 필요한지, 아니면 전체 다단계 에이전트 추론 (multi-step agentic reasoning)이 필요한지를 결정합니다.
┌───────────────────┐
[Query] --> │ Complexity Router │
└──────────┬─────────┘
...
사용 사례: 다양한 유형의 쿼리(일상 대화 + FAQ + 심층 분석 질문)를 처리해야 하며, 모든 요청에 대해 전체 에이전트 오버헤드 (agentic overhead)를 감당할 여력이 없는 경우.
장점: 지연 시간(latency) 및 비용의 대폭 절감; 쿼리당 적절한 연산 규모(right-sizes compute) 할당.
단점: 라우터의 정확도가 결정적인 병목 지점이 됨 — 복잡한 쿼리가 잘못 분류되면 충분한 서비스를 제공받지 못함.
7. 에이전트형 / 멀티 에이전트 RAG (Agentic / Multi-Agent RAG)
검색(Retrieval)은 계획을 세우고, 도구를 호출하며, 결과를 관찰하고, 만족할 때까지 반복하는 에이전트(또는 전문화된 에이전트 팀)에 의해 오케스트레이션(orchestrated)되는 여러 도구 (tool) 중 하나가 됩니다. ReAct 스타일의 루프나 멀티 에이전트 핸드오프(multi-agent handoffs)를 떠올려 보세요.
┌─────────────────────────────────────────┐
│ Orchestrator Agent │
└──────────────────┬──────────────────────┘
...
사용 사례: 질문이 이질적인 소스(heterogeneous sources) — 데이터베이스, API, 문서, 라이브 웹 — 전반에 걸쳐 중간 계획 단계와 함께 다단계 추론 (multi-step reasoning)을 필요로 하는 경우.
장점: 가장 유연하고 역량 있는 패턴; 진정으로 어려운 다중 소스 작업을 처리함.
단점: 가장 높은 지연 시간 및 비용; 디버깅이 어려움 (비결정론적 루프); 통제 불능의 도구 호출 (runaway tool-calling)을 방지하기 위한 강력한 가드레일 (guardrails) 필요.
8. 멀티모달 RAG (Multi-Modal RAG)
실제 문서는 순수 텍스트가 아닙니다. 다이어그램, 표, 차트, 스캔된 이미지가 포함되어 있습니다. 멀티모달 RAG는 텍스트와 시각적 콘텐츠를 공유된 (또는 공동 인덱싱된) 공간에 임베딩(embed)하여, 검색 시 단순히 근처의 문단뿐만 아니라 적절한 다이어그램까지 가져올 수 있도록 합니다.
┌─────────────┐ ┌──────────────┐
[Document]-->│ Text Chunks │ │ Images/Tables/ │
│ │ │ Diagrams │
...
사용 사례: 코퍼스(corpus)가 아키텍처 다이어그램, 재무 표, 엔지니어링 도면 또는 스캔된 양식이 포함된 PDF인 경우.
장점 (Pros): 순수 텍스트 파이프라인이 조용히 놓치는 정보를 활용할 수 있으며, 인간이 실제로 기술 문서를 읽는 방식과 일치합니다.
단점 (Cons): 텍스트 전용 RAG에 비해 도구(tooling)가 미성숙하며, 멀티모달 임베딩 모델 (multi-modal embedding models)은 대규모 운영 시 더 무겁고 비용이 많이 듭니다.
실습: Python을 이용한 하이브리드 검색 (Hybrid Search) + 재순위화 (Re-ranking)
다음은 하이브리드 RAG (Hybrid RAG) (RRF를 통한 dense + BM25 결합)와 검색 후 단계인 **재순위화 (re-ranking)**를 결합한 간결하고 실행 가능한 패턴입니다. 이는 단순한(naive) 파이프라인에서 수행할 수 있는 가장 영향력 있는 업그레이드라고 할 수 있습니다.
from langchain_community.retrievers import BM25Retriever
from langchain_community.vectorstores import Chroma
from langchain_openai import OpenAIEmbeddings
...
이것이 중요한 이유: 앙상블 (ensemble) 단계는 순수 임베딩이 놓치는 것(정확한 에러 코드, 서비스 이름 등)을 포착하며, 재순위화 도구 (re-ranker)는 top-k 검색만으로는 프롬프트에 그대로 전달되었을 노이즈를 제거합니다. 이 한 가지 변화는 임베딩 모델을 교체하는 것보다 검색 정밀도 (retrieval precision)를 더 효과적으로 향상시킵니다.
비교를 위한 최소한의 CRAG 스타일 관련성 게이트 (relevance gate):
def grade_relevance(query: str, doc: str, llm) -> str:
prompt = f"""Query: {query}
Retrieved passage: {doc}
...
아키텍처 결정 매트릭스 (Architectural Decision Matrix)
| 아키텍처 | 복잡도 | 지연 시간 (Latency) | 비용 | 최적의 사용 사례 |
|---|---|---|---|---|
| 표준 (Dense) RAG | 낮음 | 낮음 | 낮음 | 균질한 비정형 텍스트 코퍼스 (corpora), FAQ, 문서 |
| ... |
핵심 요약 (Key Takeaways)
핵심 요약 (Key Takeaways)
- 단순하게 시작하세요. 표준적인 밀집 RAG (Standard dense RAG)는 범위가 좁고 균질한 코퍼스 (corpora)를 위한 정당한 프로덕션 아키텍처입니다. 단순히 유행한다는 이유로 GraphRAG를 선택하지 마세요.
- 모델을 수정하기 전에 검색 (Retrieval)을 먼저 수정하세요. 하이브리드 검색 (Hybrid search) + 재순위화 (Re-ranking)는 LLM을 교체하는 것보다 실제 환경의 실패 사례를 더 많이 해결해 줍니다.
- 환각 (Hallucination)이 비즈니스 리스크가 될 때만 교정 루프 (CRAG/Self-RAG)를 추가하세요. 기본값으로 추가해서는 안 됩니다. 이 방식들은 실제 지연 시간 (Latency)을 증가시킵니다.
- 트래픽 구성이 다양해지는 즉시 복잡도에 따라 라우팅하세요 (Adaptive RAG). 이는 규모가 커졌을 때 가장 비용 효율적인 승리 전략입니다.
- 에이전틱 RAG (Agentic RAG)는 마지막 수단으로 고려하세요. 이는 가장 강력하면서도 가장 비용이 많이 드는 패턴입니다. "에이전트 (Agents)"가 올해의 키워드라서가 아니라, 작업이 진정으로 다단계 도구 사용 (Multi-step tool use)을 필요로 할 때 사용하세요.
- 문서의 형태를 잊지 마세요. 코퍼스 (Corpus)가 다이어그램과 표로 가득 차 있다면, 멀티모달 RAG (Multi-Modal RAG)는 선택 사항이 아니라 정보를 조용히 놓치지 않기 위한 유일한 방법입니다.
여기서 진짜 기술은 8가지 아키텍처를 암기하는 것이 아닙니다. 실제로 어떤 실패 모드 (Failure mode)를 겪고 있는지 진단하고, 이를 해결할 수 있는 가장 작은 패턴을 찾아내는 것입니다.
AI 자동 생성 콘텐츠
본 콘텐츠는 Dev.to AI tag의 원문을 AI가 자동으로 요약·번역·분석한 것입니다. 원 저작권은 원저작자에게 있으며, 정확한 내용은 반드시 원문을 확인해 주세요.
원문 바로가기