Tan Kim

rag

RAG (Retrieval-Augmented Generation)

외부 지식 베이스에서 관련 정보를 검색해 LLM 프롬프트에 주입하는 기법. 환각(hallucination)을 줄이고 최신 정보를 활용 가능.

기본 구조

[사용자 질문]
      ↓
  임베딩 변환
      ↓
벡터 DB 유사도 검색
      ↓
  관련 문서 청크 추출
      ↓
  프롬프트에 컨텍스트 삽입
      ↓
     LLM 생성
      ↓
    최종 답변

핵심 컴포넌트

컴포넌트 역할 예시
Embedding Model 텍스트 → 벡터 변환 text-embedding-3, BGE
Vector DB 벡터 저장 및 유사도 검색 Pinecone, Chroma, Weaviate, pgvector
Chunking 문서를 적절한 크기로 분할 고정 크기, 문장 단위, 재귀적
Retriever 쿼리와 유사한 청크 검색 시맨틱 검색, BM25, 하이브리드
LLM 검색 결과 기반 답변 생성 GPT-4, Claude

구현 예시 (LangChain)

from langchain_openai import OpenAIEmbeddings, ChatOpenAI
from langchain_chroma import Chroma
from langchain.text_splitter import RecursiveCharacterTextSplitter
from langchain.chains import RetrievalQA
 
# 1. 문서 청킹
splitter = RecursiveCharacterTextSplitter(chunk_size=500, chunk_overlap=50)
chunks = splitter.split_documents(documents)
 
# 2. 벡터 DB 생성
vectordb = Chroma.from_documents(
    chunks,
    embedding=OpenAIEmbeddings()
)
 
# 3. RAG 체인
qa = RetrievalQA.from_chain_type(
    llm=ChatOpenAI(model="gpt-4o"),
    retriever=vectordb.as_retriever(search_kwargs={"k": 4})
)
 
result = qa.invoke("질문 내용")

RAG 유형

유형 설명
Naive RAG 기본 검색 → 생성 파이프라인
Advanced RAG 쿼리 재작성, 재순위, 하이브리드 검색
Modular RAG 컴포넌트 교체 가능한 유연한 구조
GraphRAG 지식 그래프 기반 검색
Self-RAG LLM이 검색 필요 여부를 스스로 판단

청킹 전략

고정 크기 청킹      — 단순, 문맥 단절 위험
문장/단락 단위      — 문맥 보존, 크기 불균일
재귀적 청킹         — 계층적으로 분할 (권장)
시맨틱 청킹         — 의미 유사도 기반 분할

주요 벡터 DB

DB 특징
Pinecone 관리형 클라우드, 빠른 시작
Chroma 로컬/임베디드, 오픈소스
Weaviate 하이브리드 검색, 오픈소스
pgvector PostgreSQL 확장, 기존 DB 활용
Qdrant 고성능, Rust 기반
Milvus 대규모 분산 처리

RAG Evaluation (평가 지표)

RAG Evaluation은 파이프라인의 어느 단계에서 품질 문제가 발생하는지 진단하기 위해 검색 단계와 생성 단계를 분리해 측정한다.

검색 품질 지표

검색 품질은 "올바른 문서를 얼마나 잘 찾아왔는가"를 측정한다.

지표 설명 계산
Recall@k 상위 k개 결과 중 정답 문서 포함 비율 정답 문서 수 / 전체 정답 수
Precision@k 상위 k개 결과 중 관련 문서 비율 관련 문서 수 / k
MRR (Mean Reciprocal Rank) 첫 번째 정답 문서의 평균 역순위 mean(1 / rank of first hit)
NDCG@k 순위를 반영한 관련성 점수 순위 가중 DCG / 이상적 DCG
Context Relevance 검색된 컨텍스트가 쿼리와 얼마나 관련 있는가 LLM 기반 평가

생성 품질 지표

생성 품질은 "검색된 컨텍스트를 얼마나 잘 활용해 답변했는가"를 측정한다.

지표 설명
Faithfulness 답변이 컨텍스트에 근거하는 정도 (환각 탐지)
Answer Relevance 답변이 질문에 얼마나 적절히 응답하는가
Answer Correctness 정답 레이블과 비교한 정확도
RAGAS Faithfulness + Answer Relevance + Context Recall을 통합한 프레임워크

평가 프레임워크

# RAGAS 예시
from ragas import evaluate
from ragas.metrics import faithfulness, answer_relevancy, context_recall
 
result = evaluate(
    dataset,
    metrics=[faithfulness, answer_relevancy, context_recall]
)

Optimization Loop (하이퍼파라미터 최적화)

RAG 파이프라인은 여러 하이퍼파라미터가 서로 연동되어 있어 단일 파라미터만 조정하면 다른 지표가 저하될 수 있다. 평가 지표를 기준으로 반복적으로 조정한다.

Chunk Size (청크 크기)

청크 크기는 검색 정밀도와 컨텍스트 풍부함 사이의 트레이드오프를 결정한다.

청크 크기 특성 적합한 경우
소형 (128~256 토큰) 정밀한 검색, 컨텍스트 부족 위험 사실 조회, 키워드 중심 쿼리
중형 (512~1024 토큰) 균형점, 가장 많이 사용됨 일반 목적
대형 (2048+ 토큰) 풍부한 컨텍스트, 노이즈 증가 요약, 문서 전체 이해 필요 시

탐색 기준: Context Relevance가 낮으면 청크를 줄이고, Faithfulness가 낮으면 늘리는 것을 우선 시도한다.

Overlap (청크 겹침)

인접 청크 간 텍스트를 일정 토큰만큼 겹쳐 경계에서 문맥이 단절되는 것을 방지한다.

# chunk_size=512, overlap=50일 때
# Chunk 1: 토큰 0~511
# Chunk 2: 토큰 461~972  (50 토큰 겹침)
splitter = RecursiveCharacterTextSplitter(
    chunk_size=512,
    chunk_overlap=50  # 청크 크기의 5~15% 권장
)

Overlap이 클수록 청크 수가 많아지고 인덱스 크기가 커진다. 경계 문맥 손실 문제가 두드러진다면 Overlap을 늘리기 전에 Semantic Chunking도 고려한다.

Retrieval top-k

top-k는 retriever가 반환하는 후보 문서 수다. LLM 컨텍스트에 직접 넣는 최종 k와, reranker를 거치기 전 후보 풀 크기로 나눠 관리하는 것이 좋다.

retriever = vectordb.as_retriever(
    search_kwargs={
        "k": 50        # reranker 전 후보 풀
    }
)
# reranker 후 최종 컨텍스트: top-5
top-k 증가 시 효과
Recall 상승 정답 문서를 포함할 확률 증가
Precision 하락 관련 없는 문서도 많아짐
레이턴시/비용 증가 reranker 부하 증가, 컨텍스트 길이 증가

Reranker Threshold

Reranker가 계산한 관련성 점수에 임계값(threshold)을 설정해, 점수 미달 문서를 컨텍스트에서 제외한다.

def apply_reranker_threshold(candidates, reranker, threshold=0.5):
    scores = reranker.predict([(query, doc.content) for doc in candidates])
    return [doc for doc, score in zip(candidates, scores) if score >= threshold]

Threshold가 높을수록 Precision이 올라가지만 Recall이 낮아진다. 임계값이 너무 높으면 컨텍스트가 비어 LLM이 "모르겠다"고 답변하는 빈도가 높아진다. 검증셋에서 F1 또는 Answer Correctness를 최대화하는 값을 탐색한다.

Fusion Strategy

복수의 retriever를 사용할 때 결과를 어떻게 병합할지 결정한다. 전략별 특성 요약:

전략 조정 파라미터 특성
Naive Merge retriever 순서 가장 단순, 순서에 민감
Score Fusion 가중치, 정규화 방법 스코어 분포 분석 필요
Reciprocal Rank Fusion k 값 (기본 60) 강건성 높음, 튜닝 포인트 적음
Reranker-centric 후보 수, threshold 가장 높은 정밀도, 레이턴시 비용

전략 선택 기준: 레이턴시 제약이 없다면 RRF + Reranker 조합이 일반적으로 가장 안정적이다.

최적화 순서 권장안

파라미터 간 의존성이 있으므로 다음 순서로 탐색하면 효율적이다.

1. Chunk Size / Overlap 결정  →  Context Relevance 측정
2. top-k (후보 풀) 결정       →  Recall@k 측정
3. Fusion Strategy 선택       →  MRR / NDCG 측정
4. Reranker Threshold 결정   →  Precision / Faithfulness 측정
5. 최종 top-k (컨텍스트 크기) →  Answer Correctness 측정

메모