RAG (Retrieval-Augmented Generation) 구축 가이드

Source: rag-langchain-implementation-datacamp Type: Article (DataCamp) Valid as of: 2026-04-26

핵심 Takeaway

상세 요약

RAG가 필요한 이유

문제 1: LLM의 Hallucination

Q: "Claude 3.5 Sonnet의 훈련 데이터는 언제까지인가?"
LLM: "2024년 4월까지의 데이터로 훈련되었습니다" ❌
(사실: 정확한 cutoff date는 다를 수 있음)

문제 2: 최신 정보 미반영

Q: "2026년 4월의 암호화폐 가격은?"
LLM: "죄송하지만, 2023년 이후의 정보는 없습니다" ❌

해결책: RAG

LLM + 검색 엔진 + 벡터 데이터베이스 = 정확하고 최신의 답변

사용자 질문
    ↓
[검색] 벡터 DB에서 유관 문서 검색 (상위 3개)
    ↓
[강화] 검색 결과 + 질문을 LLM에 전달
    ↓
[생성] LLM이 문맥을 기반으로 답변 생성
    ↓
정확하고 최신의 답변 ✓

RAG의 3단계 아키텍처

단계 1: Indexing (색인화)

1-1. 문서 로드

from langchain.document_loaders import PyPDFLoader
import pandas as pd
 
# PDF 로드
loader = PyPDFLoader("your_document.pdf")
documents = loader.load()
 
# CSV 로드
df = pd.read_csv("data.csv")
# → LangChain Document로 변환

1-2. 문서 분할 (Chunking)

문제: 전체 문서를 벡터화하면 토큰 제한 초과

해결책: 문서를 작은 청크로 분할

from langchain.text_splitter import CharacterTextSplitter
 
splitter = CharacterTextSplitter(
    chunk_size=1000,        # 1,000자 청크
    chunk_overlap=200       # 200자 중복 (맥락 보존)
)
 
chunks = splitter.split_documents(documents)
 
# 청크 크기 선택 기준
# - 500자 (너무 작음): 정보 손실
# - 1000-2000자 (적절): 문맥 보존 + 검색 정확도
# - 5000자 (너무 큼): 토큰 낭비

1-3. 임베딩 생성 (Embedding)

각 청크를 벡터로 변환 → 의미론적 검색 가능

from langchain.embeddings import OpenAIEmbeddings
from langchain.embeddings import HuggingFaceEmbeddings
 
embeddings = OpenAIEmbeddings(model="text-embedding-3-small")
 
# 각 청크 → 1,536차원 벡터로 변환
# "AI 기술은 혁명적입니다" → [0.023, -0.145, 0.078, ..., 0.456]

임베딩의 의미:

의미론적으로 유사한 텍스트 → 유사한 벡터
  "AI는 인공지능입니다" → [0.1, 0.2, 0.3, ...]
  "AI는 자동화된 학습입니다" → [0.11, 0.19, 0.31, ...]  ← 유사
  
의미론적으로 다른 텍스트 → 다른 벡터
  "고양이는 동물입니다" → [0.8, 0.05, 0.9, ...]  ← 거리 먼

1-4. 벡터 데이터베이스에 저장

from langchain.vectorstores import Chroma  # 로컬
# 또는
from langchain.vectorstores import Pinecone, FAISS, Weaviate
 
vector_db = Chroma.from_documents(
    documents=chunks,
    embedding=embeddings,
    persist_directory="./chroma_db"
)
 
# 저장되는 데이터:
# Chunk 1: "AI는..." → [벡터]
# Chunk 2: "머신러닝은..." → [벡터]
# ...

벡터 DB 선택 기준:

DB특징용도
Chroma로컬, 경량프로토타입, 소규모
Pinecone클라우드, 관리형프로덕션, 대규모
FAISS로컬, 고속오프라인, 배치 검색
Weaviate분산, 스케일 가능엔터프라이즈

단계 2: Retrieval (검색)

사용자 질문과 가장 유사한 청크 검색

2-1. 유사도 검색 (Similarity Search)

query = "AI의 장점은 무엇인가?"
 
# 쿼리도 임베딩으로 변환
query_embedding = embeddings.embed_query(query)
 
# 벡터 DB에서 가장 가까운 청크 검색 (Cosine Similarity)
similar_chunks = vector_db.similarity_search(query, k=3)
 
# 결과 (상위 3개):
# 1. "AI는 반복적인 작업을 자동화합니다..."
#    유사도: 0.92 ← 매우 높음
# 2. "AI는 인간 지능을 보강합니다..."
#    유사도: 0.87
# 3. "머신러닝 알고리즘은 데이터에서 패턴을 학습합니다..."
#    유사도: 0.81

고급 검색 기법:

2-2. MMR (Maximal Marginal Relevance)

문제: 상위 3개 청크가 모두 비슷한 내용 → 정보 다양성 없음

해결책: 관련성 + 다양성을 모두 고려

similar_chunks = vector_db.max_marginal_relevance_search(
    query, 
    k=3,
    fetch_k=10  # 먼저 상위 10개를 가져온 후 다양성 고려
)
 
# 결과:
# 1. "AI의 정의와 역사..." (관련성: 0.92)
# 2. "AI의 윤리적 문제..." (관련성: 0.75, 다양성 보강)
# 3. "AI 산업의 미래..." (관련성: 0.78, 추가 다양성)

2-3. 메타데이터 필터

# 저장 시 메타데이터 추가
chunks_with_meta = [
    {
        "content": "AI는...",
        "metadata": {"source": "ai_overview.pdf", "page": 1, "date": "2024"}
    },
]
 
# 검색 시 필터 적용
filtered_chunks = vector_db.similarity_search(
    query,
    k=3,
    filter={"date": {"$gte": "2024-01-01"}}  # 2024년 이후만
)

단계 3: Generation (생성)

검색된 청크를 컨텍스트로 LLM에 전달 → 답변 생성

from langchain.chat_models import ChatOpenAI
from langchain.chains import RetrievalQA
 
llm = ChatOpenAI(model="gpt-4", temperature=0)
 
# RAG 체인 구성
rag_chain = RetrievalQA.from_chain_type(
    llm=llm,
    chain_type="stuff",  # 검색 결과를 프롬프트에 직접 포함
    retriever=vector_db.as_retriever(search_kwargs={"k": 3})
)
 
# 질문
query = "AI의 주요 응용 분야는 무엇인가?"
 
# RAG 실행
result = rag_chain.run(query)
 
# 결과:
# "AI의 주요 응용 분야는:
#  1. 헬스케어 - 질병 진단, 신약 개발
#  2. 금융 - 사기 탐지, 투자 자동화
#  3. 제조 - 품질 관리, 생산 최적화"

내부 동작 (프롬프트 구조):

System: 당신은 전문가 AI 어시스턴트입니다.

User: 다음 문맥을 기반으로 질문에 답하세요:

[검색 결과 1]
"AI는 헬스케어 산업에서 질병 진단에 사용됩니다..."

[검색 결과 2]
"의료 AI는 영상 분석에 특히 효과적합니다..."

[검색 결과 3]
"AI 기술은 신약 개발 시간을 50% 단축했습니다..."

질문: AI의 주요 응용 분야는 무엇인가?

실제 사용 예시

기업 문서 Q&A 시스템

아키텍처:

사용자 쿼리 (UI)
    ↓
[Retriever] 벡터 DB에서 관련 PDF/CSV 검색
    ↓
[LLM with RetrievalQA] 검색 결과 + 쿼리 처리
    ↓
JSON 응답 (FastAPI)

RAG의 장점

  1. 정확성: 기존 지식 기반 + 검색된 최신 정보 합성
  2. 신뢰성: 출처 추적 가능 (메타데이터)
  3. 확장성: 새로운 문서 추가 = 자동 학습 (재학습 불필요)
  4. 비용 효율: 작은 모델 + RAG > 큰 모델만 사용

연결되는 위키 페이지