RAG (Retrieval-Augmented Generation)

업데이트:

개념

RAG란 무엇인가?

RAG (Retrieval-Augmented Generation)는 대규모 언어 모델(LLM)의 성능을 향상시키기 위해 검색(Retrieval) 단계를 생성(Generation) 단계 이전에 추가하는 방식입니다.

핵심 특징

  • 검색 기반: 외부 지식 베이스에서 관련 문서를 검색하여 활용
  • 생성 기반: 검색된 정보를 바탕으로 텍스트 생성
  • 정보 신뢰성 향상: 최신 정보와 도메인 특화 정보 활용 가능
  • 할루시네이션 감소: 검색된 문서 기반으로 생성하여 거짓 정보 생성 감소

RAG의 필요성

일반적인 LLM의 문제점을 해결합니다:

  • 오래된 정보: 학습 데이터 기준 이후의 정보 부재
  • 도메인 지식 부족: 특화된 분야 정보 제한
  • 할루시네이션: LLM이 존재하지 않는 정보 생성
  • 투명성 부족: 답변의 출처를 알 수 없음

메커니즘

RAG의 작동 원리

RAG는 크게 3가지 단계로 동작합니다:

1. 검색 단계 (Retrieval)

사용자의 질문(쿼리)을 받으면:

사용자 질문 → 쿼리 임베딩 → 유사도 검색 → 관련 문서 추출

과정:

  • 쿼리를 벡터로 변환 (Embedding)
  • 벡터 데이터베이스에서 유사한 문서 검색
  • 상위 K개 문서 선택

2. 증강 단계 (Augmentation)

검색된 문서를 쿼리와 함께 프롬프트에 추가합니다:

프롬프트 = "다음 문서를 참고하여 질문에 답변하세요.\n문서: [검색 결과]\n질문: [사용자 질문]"

3. 생성 단계 (Generation)

LLM이 증강된 프롬프트를 입력받아 답변을 생성합니다:

LLM(증강된 프롬프트) → 생성된 답변

내부 구조

RAG 시스템의 구성 요소

┌─────────────────────────────────────────────────────┐
│                  사용자 질문 입력                     │
└────────────────────┬────────────────────────────────┘
                     │
                     ▼
        ┌────────────────────────┐
        │  쿼리 임베딩 변환        │
        │ (Query Embedding)      │
        └────────┬───────────────┘
                 │
                 ▼
     ┌──────────────────────────┐
     │   벡터 데이터베이스         │
     │ (Vector Database)        │
     │ [문서1] [문서2] [문서3]    │
     └────────┬─────────────────┘
              │
              ▼
  ┌────────────────────────────┐
  │  유사 문서 검색 및 추출       │
  │ (Semantic Search)          │
  └────────┬───────────────────┘
           │
           ▼
┌──────────────────────────────────┐
│  프롬프트 증강                     │
│ (Context + Query)                │
└────────┬─────────────────────────┘
         │
         ▼
  ┌──────────────────────────┐
  │    LLM (언어 모델)        │
  │  (GPT, Claude 등)        │
  └────────┬─────────────────┘
           │
           ▼
┌──────────────────────────────────┐
│     생성된 답변 (최종 결과)         │
└──────────────────────────────────┘

주요 컴포넌트

컴포넌트 설명 예시
문서 저장소 검색할 원본 문서 저장소 PDF, 웹 페이지, DB
임베딩 모델 텍스트를 벡터로 변환 sentence-transformers, OpenAI API
벡터 DB 임베딩된 벡터 저장 및 검색 Pinecone, Weaviate, Milvus
검색 엔진 유사도 기반 문서 검색 BM25, 코사인 유사도
LLM 최종 답변 생성 GPT-4, Claude, Llama

주요 제품

상용 솔루션

1. LangChain

  • 특징: RAG 구현을 위한 프레임워크
  • 장점: 다양한 LLM 및 벡터 DB 지원, 풍부한 문서
  • 링크: LangChain

2. LlamaIndex

  • 특징: 데이터 인덱싱 및 쿼리 최적화
  • 장점: 다양한 데이터 소스 지원, 구조화된 인덱싱
  • 링크: LlamaIndex

3. Pinecone

  • 특징: 완전 관리형 벡터 데이터베이스
  • 장점: 확장성, 낮은 지연시간, 간편한 API
  • 링크: Pinecone

4. Weaviate

  • 특징: 오픈소스 벡터 데이터베이스
  • 장점: 자체 호스팅 가능, GraphQL API, 좋은 스케일링
  • 링크: Weaviate

5. Milvus

  • 특징: 오픈소스 벡터 데이터베이스
  • 장점: 고성능, 다양한 인덱스 지원, 커뮤니티 지원
  • 링크: Milvus

6. Haystack

  • 특징: 오픈소스 검색 엔진 프레임워크
  • 장점: 유연한 파이프라인, 다양한 검색 방식 지원
  • 링크: Haystack

활용 샘플

사용 사례

1. 기술 문서 질의응답 (Q&A)

  • 나만의 API 문서 기반 답변 시스템
  • 회사 내부 문서 검색 시스템

2. 고객 지원 (Customer Support)

  • FAQ 기반 자동 답변
  • 제품 매뉴얼 기반 지원

3. 법률 및 의료 관련

  • 의료 기록 기반 진단 지원
  • 법률 문서 검색 및 분석

4. 뉴스 및 연구

  • 최신 뉴스 기반 요약
  • 학술 논문 기반 분석

주요 코드

1. LangChain을 이용한 기본 RAG 구현

from langchain.document_loaders import PyPDFLoader
from langchain.text_splitter import CharacterTextSplitter
from langchain.embeddings import OpenAIEmbeddings
from langchain.vectorstores import FAISS
from langchain.chains import RetrievalQA
from langchain.llms import OpenAI

# 1. 문서 로드
loader = PyPDFLoader("document.pdf")
documents = loader.load()

# 2. 문서 분할
text_splitter = CharacterTextSplitter(chunk_size=1000, chunk_overlap=200)
splits = text_splitter.split_documents(documents)

# 3. 임베딩 및 벡터 DB 생성
embeddings = OpenAIEmbeddings()
vectorstore = FAISS.from_documents(splits, embeddings)

# 4. 검색 및 생성
llm = OpenAI()
qa_chain = RetrievalQA.from_chain_type(
    llm=llm,
    chain_type="stuff",
    retriever=vectorstore.as_retriever()
)

# 5. 질의
result = qa_chain.run("문서에 대해 설명해주세요")
print(result)

2. LlamaIndex를 이용한 RAG

from llama_index import SimpleDirectoryReader, GPTVectorStoreIndex, ServiceContext
from llama_index.llms import OpenAI

# 1. 문서 로드
documents = SimpleDirectoryReader("./data").load_data()

# 2. 인덱스 생성
service_context = ServiceContext.from_defaults(llm=OpenAI(model="gpt-4"))
index = GPTVectorStoreIndex.from_documents(
    documents,
    service_context=service_context
)

# 3. 쿼리 엔진 생성
query_engine = index.as_query_engine()

# 4. 질의
response = query_engine.query("제 질문은 무엇입니까?")
print(response)

3. 간단한 Python 예제 (로컬 임베딩 사용)

from sentence_transformers import SentenceTransformer
from sklearn.metrics.pairwise import cosine_similarity
import numpy as np

# 1. 임베딩 모델 로드
model = SentenceTransformer('all-MiniLM-L6-v2')

# 2. 문서 준비
documents = [
    "RAG는 검색 기반 생성 방식입니다.",
    "벡터 데이터베이스는 임베딩을 저장합니다.",
    "LLM은 대규모 언어 모델입니다."
]

# 3. 문서 임베딩
doc_embeddings = model.encode(documents)

# 4. 쿼리 임베딩
query = "RAG의 개념은 무엇인가?"
query_embedding = model.encode([query])

# 5. 유사도 계산
similarities = cosine_similarity(query_embedding, doc_embeddings)[0]

# 6. 상위 문서 선택
top_idx = np.argsort(similarities)[-1]
print(f"가장 유사한 문서: {documents[top_idx]}")
print(f"유사도 점수: {similarities[top_idx]:.4f}")

4. Pinecone을 이용한 벡터 DB 관리

import pinecone
from langchain.embeddings.openai import OpenAIEmbeddings
from langchain.vectorstores import Pinecone
from langchain.chat_models import ChatOpenAI
from langchain.chains import RetrievalQA

# 1. Pinecone 초기화
pinecone.init(api_key="YOUR_API_KEY", environment="us-west1-gcp")

# 2. 인덱스 생성
pinecone.create_index("rag-index", dimension=1536)

# 3. 임베딩 및 벡터 저장
embeddings = OpenAIEmbeddings()
vectorstore = Pinecone.from_documents(
    documents,
    embeddings,
    index_name="rag-index"
)

# 4. RAG 체인 구성
llm = ChatOpenAI(model_name="gpt-4")
qa = RetrievalQA.from_chain_type(
    llm=llm,
    chain_type="stuff",
    retriever=vectorstore.as_retriever()
)

# 5. 질의
answer = qa.run("당신의 질문")
print(answer)

동작 흐름 예제

질문에서 답변까지의 전체 과정

질문: “RAG의 장점은 무엇인가요?”

Step 1: 임베딩

"RAG의 장점은 무엇인가요?" 
→ [0.234, -0.123, 0.456, ...] (벡터)

Step 2: 검색

유사도 점수:
- 문서 1: "RAG는 최신 정보를 활용합니다." (점수: 0.92)
- 문서 2: "할루시네이션 감소에 효과적입니다." (점수: 0.88)
- 문서 3: "벡터 DB는 임베딩을 저장합니다." (점수: 0.65)

Step 3: 증강

프롬프트:
"다음 문서를 참고하여 질문에 답변하세요.

문서:
1. RAG는 최신 정보를 활용합니다.
2. 할루시네이션 감소에 효과적입니다.

질문: RAG의 장점은 무엇인가요?"

Step 4: 생성

답변: "RAG의 주요 장점은 다음과 같습니다:
1. 최신 정보 활용: 검색을 통해 최신 정보 제공
2. 할루시네이션 감소: 검색된 문서 기반으로 답변
3. 투명성 향상: 답변의 출처 제시 가능
..."

구현 시 고려사항

최적화 팁

1. 문서 분할 (Chunking)

  • 너무 작음: 충분한 컨텍스트 부족
  • 너무 큼: 무관한 정보 포함
  • 권장: 512~1024 토큰 범위

2. 검색 결과 개수

  • 적게: 필요한 정보 부족
  • 많게: 비용 증가, 생성 속도 저하
  • 권장: 3~5개 문서

3. 임베딩 모델 선택

  • 경량: 빠르지만 정확도 낮음
  • 대규모: 정확하지만 비용 높음
  • 권장: 도메인에 맞는 모델 선택

4. 하이브리드 검색

# BM25 + 의미적 유사도 결합
hybrid_results = bm25_search(query, top_k=5) + semantic_search(query, top_k=5)

참조

공식 문서

학술 자료

커뮤니티 자료

관련 기술

댓글남기기