Skip to main content

RAG (Retrieval-Augmented Generation)

RAG는 LLM이 답변을 생성하기 전에 외부 지식 저장소에서 관련 정보를 검색하여 참고하는 기법입니다. 모델의 파라미터에 저장된 지식만으로는 답변하기 어려운 질문에 대해, 실시간으로 검색한 문서를 컨텍스트로 제공하여 정확도를 높입니다.

LLM의 한계와 RAG의 필요성

LLM은 학습 데이터에 포함된 지식만 활용할 수 있습니다. 이로 인해 세 가지 근본적인 한계가 있습니다.
  • 환각(Hallucination): 학습 데이터에 없는 내용을 그럴듯하게 생성합니다
  • 지식 컷오프: 학습 이후의 정보를 알 수 없습니다
  • 도메인 지식 부족: 사내 문서, 비공개 데이터 등 학습에 포함되지 않은 지식에 접근할 수 없습니다
RAG는 이 한계를 극복하기 위해, 질문과 관련된 문서를 검색하여 LLM의 프롬프트에 함께 전달합니다. 이를 통해 LLM은 자신이 학습하지 않은 정보에 대해서도 근거 기반의 답변을 생성할 수 있습니다.

기본 RAG 파이프라인

RAG의 기본 구조는 세 단계로 구성됩니다. 사용자 질문을 받으면 벡터 데이터베이스에서 관련 문서를 검색하고, 검색된 문서를 컨텍스트로 LLM에 전달하여 답변을 생성합니다.
1

Indexing (인덱싱)

문서를 청크로 분할하고, 각 청크를 임베딩 모델로 벡터로 변환하여 벡터 데이터베이스에 저장합니다. 이 과정은 질문이 들어오기 전에 미리 수행합니다.
2

Retrieval (검색)

사용자 질문을 동일한 임베딩 모델로 벡터로 변환한 뒤, 벡터 데이터베이스에서 코사인 유사도가 높은 문서 청크를 검색합니다.
3

Generation (생성)

검색된 문서 청크를 컨텍스트로 LLM 프롬프트에 포함하여 답변을 생성합니다.
각 단계의 세부 내용은 아래 페이지에서 확인할 수 있습니다.

LangGraph 기본 구현

기본 RAG 파이프라인을 LangGraph로 구현하면 다음과 같습니다.
from typing import TypedDict, List
from langchain_core.documents import Document
from langchain_openai import ChatOpenAI, OpenAIEmbeddings
from langchain_community.vectorstores import Chroma
from langchain_core.prompts import ChatPromptTemplate
from langchain_core.output_parsers import StrOutputParser
from langgraph.graph import StateGraph, START, END

class GraphState(TypedDict):
    question: str
    documents: List[Document]
    generation: str

# 벡터 스토어 및 LLM 초기화
embeddings = OpenAIEmbeddings()
vectorstore = Chroma(collection_name="documents", embedding_function=embeddings)
retriever = vectorstore.as_retriever(search_kwargs={"k": 4})
llm = ChatOpenAI(model="gpt-4o-mini", temperature=0)

def retrieve(state: GraphState) -> GraphState:
    """벡터 데이터베이스에서 관련 문서를 검색합니다."""
    documents = retriever.invoke(state["question"])
    return {"documents": documents}

def generate(state: GraphState) -> GraphState:
    """검색된 문서를 기반으로 답변을 생성합니다."""
    prompt = ChatPromptTemplate.from_messages([
        ("system", "다음 컨텍스트를 참고하여 질문에 답변하세요.\n\n{context}"),
        ("human", "{question}"),
    ])
    chain = prompt | llm | StrOutputParser()
    context = "\n\n".join(doc.page_content for doc in state["documents"])
    generation = chain.invoke({"context": context, "question": state["question"]})
    return {"generation": generation}

# 그래프 구성
workflow = StateGraph(GraphState)
workflow.add_node("retrieve", retrieve)
workflow.add_node("generate", generate)
workflow.add_edge(START, "retrieve")
workflow.add_edge("retrieve", "generate")
workflow.add_edge("generate", END)

app = workflow.compile()
result = app.invoke({"question": "LangGraph란 무엇인가요?"})

기본 RAG의 한계

기본 RAG는 구현이 간단하지만 여러 한계가 있습니다.
사용자 질문과 문서 사이의 의미적 차이(semantic gap)로 관련 없는 문서가 검색될 수 있습니다. 예를 들어 “파이썬으로 웹 서버 만들기”라는 질문에 “파이썬 설치 방법” 문서가 검색될 수 있습니다.
검색된 문서가 부정확하거나 불충분할 때, LLM이 검색 결과를 무시하고 자체 지식으로 답변을 생성할 수 있습니다.
검색된 여러 문서가 유사한 내용을 반복하거나, 질문과 무관한 내용을 포함할 수 있습니다. 이로 인해 LLM의 컨텍스트 윈도우가 비효율적으로 소비됩니다.
검색 결과가 질문에 적합한지, 생성된 답변이 문서에 근거하는지 확인하는 단계가 없습니다.
이러한 한계를 극복하기 위해 쿼리 변환, 재순위화, 자기 평가 등을 추가한 발전된 아키텍처들이 제안되었습니다. Advanced RAG부터 이어서 확인하세요.

실전 RAG 파이프라인

실제 프로덕션 환경에서는 기본 RAG에 여러 최적화 단계를 추가합니다. 아래 다이어그램은 실전에서 자주 사용되는 RAG 파이프라인의 전체 흐름입니다. 각 최적화 기법의 상세 내용은 RAG 전략 섹션에서 다룹니다.

아키텍처 진화 과정

RAG는 기본 검색-생성 파이프라인에서 시작하여, 점차 자기 평가, 오류 보정, 적응형 라우팅, 에이전트 기반 구조로 발전해 왔습니다.

아키텍처 비교

아키텍처핵심 특징검색 결정오류 보정그래프 구조
Advanced RAG쿼리 변환 + 재순위화항상 검색없음선형 (확장)
FLARE생성 중 능동적 검색불확실할 때 검색문장 재생성루프 포함
Self-RAG자기 평가 (Reflection Token)필요 시 검색 (on-demand)생성 결과 자체 평가루프 포함
Corrective RAG검색 품질 평가 + 웹 검색항상 검색웹 검색 폴백조건부 분기
Adaptive RAG쿼리 복잡도 기반 라우팅쿼리에 따라 선택Self-RAG + CRAG 통합복합 그래프
RAPTOR재귀 요약 트리 구조다층 검색없음트리 구조
Modular RAG모듈 조합 프레임워크모듈에 따라 다름모듈에 따라 다름유연한 구성
Graph RAG지식 그래프 + 커뮤니티 요약그래프 탐색커뮤니티 기반 종합조건부 분기
Multimodal RAG텍스트 + 이미지 등 다중 모달리티멀티모달 검색비전 LLM 활용선형/분기
Agentic RAG자율 에이전트에이전트가 판단도구 선택으로 해결에이전트 루프

LangGraph와 RAG

이 문서에서는 각 RAG 아키텍처의 구현에 LangGraph를 사용합니다. LangGraph는 LLM 애플리케이션을 상태 기반 그래프로 구성하는 프레임워크입니다. LangGraph가 RAG 구현에 적합한 이유는 다음과 같습니다.
  • StateGraph: 검색 결과, 생성 텍스트, 평가 결과 등을 상태로 관리합니다
  • 조건부 엣지: 검색 품질 평가, 쿼리 라우팅 등 분기 로직을 선언적으로 정의합니다
  • 루프: Self-RAG의 재생성, CRAG의 웹 검색 폴백 등 반복 구조를 자연스럽게 표현합니다
  • 도구 통합: Agentic RAG에서 검색, 웹 검색, API 호출 등을 도구로 연결합니다

아키텍처별 문서

참고 논문

논문학회/연도링크
Retrieval-Augmented Generation for Knowledge-Intensive NLP Tasks (Lewis et al.)NeurIPS 2020arXiv 2005.11401
Precise Zero-Shot Dense Retrieval without Relevance Labels - HyDE (Gao et al.)ACL 2023arXiv 2212.10496
Retrieval-Augmented Generation for Large Language Models: A Survey (Gao et al.)2023arXiv 2312.10997
Self-RAG: Learning to Retrieve, Generate, and Critique (Asai et al.)ICLR 2024arXiv 2310.11511
Corrective Retrieval Augmented Generation (Yan et al.)2024arXiv 2401.15884
Adaptive-RAG: Learning to Adapt Retrieval-Augmented LLMs (Jeong et al.)NAACL 2024arXiv 2403.14403
Modular RAG: Transforming RAG Systems into LEGO-like Reconfigurable Frameworks (Gao et al.)2024arXiv 2407.21059
From Local to Global: A Graph RAG Approach to Query-Focused Summarization (Edge et al.)2024arXiv 2404.16130
RAPTOR: Recursive Abstractive Processing for Tree-Organized Retrieval (Sarthi et al.)ICLR 2024arXiv 2401.18059
Active Retrieval Augmented Generation - FLARE (Jiang et al.)EMNLP 2023arXiv 2305.06983
Agentic Retrieval-Augmented Generation: A Survey (Singh et al.)2025arXiv 2501.09136
Ask in Any Modality: A Survey on Multimodal RAG (Abootorabi et al.)2025arXiv 2502.08826