[RAG] RAG에 관하여

당니·2026년 1월 19일

LLM

목록 보기
3/19
post-thumbnail

안녕하세요!
시험을 볼 때 교과서를 보며 답을 쓸 수 있다면 얼마나 좋을까요?
RAG는 바로 AI에게 이런 '오픈북 시험' 능력을 부여하는 기술입니다. 머릿속 지식만으로 답하는 대신, 필요한 정보를 찾아보고 그것을 바탕으로 정확한 답변을 생성하도록 하는 것이죠.

이 간단한 아이디어가 왜 LLM의 게임 체인저가 되었는지, 그리고 우리는 이를 어떻게 활용할 수 있는지 함께 알아보겠습니다.


RAG란 무엇인가?

RAG는 대규모 언어 모델(LLM)의 한계를 극복하기 위해 등장한 기술입니다. 기본적으로 LLM은 학습 데이터에만 의존하기 때문에 최신 정보를 알지 못하고, 특정 도메인의 전문 지식이 부족하며, 때로는 잘못된 정보를 그럴듯하게 생성하는 환각(hallucination) 문제를 겪습니다.

RAG는 이러한 문제를 해결하기 위해 외부 지식 베이스에서 관련 정보를 검색(Retrieval)하여, 이를 바탕으로 LLM이 답변을 생성(Generation)하도록 하는 방식입니다. 마치 오픈북 시험처럼, 모델이 필요한 정보를 참고하면서 답변할 수 있게 하는 것이죠.


RAG의 작동 원리

RAG 시스템은 크게 세 단계로 작동합니다.

먼저 인덱싱(Indexing) 단계에서는 문서들을 작은 청크(chunk)로 분할하고, 각 청크를 벡터 임베딩으로 변환하여 벡터 데이터베이스에 저장합니다. 이 과정은 사전에 한 번만 수행되며, 시스템의 지식 베이스를 구축하는 단계입니다.

다음으로 검색(Retrieval) 단계에서는 사용자의 질문을 벡터로 변환하고, 벡터 데이터베이스에서 코사인 유사도 같은 거리 측정 방식을 통해 가장 관련성 높은 문서 청크들을 찾아냅니다. 일반적으로 상위 3~5개의 관련 청크를 선택합니다.

마지막으로 생성(Generation) 단계에서는 검색된 문서 청크들과 사용자의 질문을 함께 프롬프트로 구성하여 LLM에 전달합니다. LLM은 제공된 컨텍스트를 바탕으로 정확하고 관련성 높은 답변을 생성합니다.


실제 구현 예시

Python과 LangChain, OpenAI를 사용한 간단한 RAG 시스템 구현 예시를 살펴보겠습니다. 문서 로딩부터 벡터 저장소 생성, 그리고 질의응답까지의 전체 파이프라인을 다룹니다.

from langchain.document_loaders import TextLoader
from langchain.text_splitter import RecursiveCharacterTextSplitter
from langchain.embeddings import OpenAIEmbeddings
from langchain.vectorstores import Chroma
from langchain.chat_models import ChatOpenAI
from langchain.chains import RetrievalQA

# 1. 문서 로딩 및 분할
loader = TextLoader('documents/knowledge_base.txt')
documents = loader.load()

text_splitter = RecursiveCharacterTextSplitter(
    chunk_size=1000,
    chunk_overlap=200
)
chunks = text_splitter.split_documents(documents)

# 2. 임베딩 및 벡터 저장소 생성
embeddings = OpenAIEmbeddings()
vectorstore = Chroma.from_documents(
    documents=chunks,
    embedding=embeddings,
    persist_directory="./chroma_db"
)

# 3. RAG 체인 구성
llm = ChatOpenAI(model="gpt-4", temperature=0)
qa_chain = RetrievalQA.from_chain_type(
    llm=llm,
    chain_type="stuff",
    retriever=vectorstore.as_retriever(search_kwargs={"k": 3}),
    return_source_documents=True
)

# 4. 질의 수행
query = "RAG의 주요 장점은 무엇인가요?"
result = qa_chain({"query": query})

print(f"답변: {result['result']}")
print(f"\n참고 문서: {result['source_documents']}")

성능 최적화 전략

RAG 시스템의 성능을 최적화하기 위해서는 여러 요소를 고려해야 합니다.

  • 청크 크기 조정이 중요합니다. 너무 작으면 맥락이 부족하고, 너무 크면 불필요한 정보가 포함됩니다. 일반적으로 500~1000 토큰 정도가 적절하며, 도메인과 문서 특성에 따라 실험을 통해 최적값을 찾아야 합니다.

  • 임베딩 모델 선택도 중요한 결정사항입니다. OpenAI의 text-embedding-3-large나 오픈소스인 sentence-transformers 등 다양한 옵션이 있으며, 각각 성능과 비용 측면에서 장단점이 있습니다.

  • 하이브리드 검색을 활용하면 더 나은 결과를 얻을 수 있습니다. 벡터 검색과 키워드 기반 검색(BM25)을 결합하면, 의미적 유사성과 정확한 키워드 매칭의 장점을 모두 활용할 수 있습니다.

  • 리랭킹(Re-ranking) 단계를 추가하는 것도 효과적입니다. 초기 검색 결과를 더 정교한 모델로 재평가하여 최종적으로 가장 관련성 높은 문서만 LLM에 전달합니다.


실무에서 마주치는 과제들

RAG를 실제 프로덕션 환경에 적용할 때 몇 가지 과제에 직면하게 됩니다.

  • 문서 업데이트 관리: 실시간으로 변하는 정보를 어떻게 반영할 것인지, 증분 업데이트를 어떻게 효율적으로 처리할 것인지 고민해야 합니다.

  • 멀티모달 데이터 처리도 현실적인 과제입니다. 텍스트뿐만 아니라 이미지, 표, 차트 등 다양한 형태의 정보를 효과적으로 인덱싱하고 검색하는 방법이 필요합니다.

  • 응답 지연 시간 최적화는 사용자 경험에 직결됩니다. 벡터 검색, LLM 추론 등 각 단계의 레이턴시를 줄이기 위해 캐싱, 병렬 처리, 인덱스 최적화 등의 기법을 활용해야 합니다.

  • 비용 관리도 무시할 수 없는 요소입니다. 특히 대규모 문서 컬렉션을 다룰 때 임베딩 생성 비용과 벡터 저장소 운영 비용을 고려해야 합니다.


평가 및 모니터링

RAG 시스템의 품질을 측정하고 개선하기 위해서는 적절한 평가 지표가 필요합니다.

검색 품질Precision@K, Recall@K, MRR(Mean Reciprocal Rank) 등의 지표로 측정할 수 있습니다. 이를 통해 관련 문서를 얼마나 잘 찾아내는지 평가합니다.

생성 품질Faithfulness(검색된 문서에 충실한지), Relevance(질문과 관련된 답변인지), Coherence(논리적 일관성) 등을 기준으로 평가합니다.

실무에서는 LLM을 활용한 자동 평가와 사람의 평가를 병행하는 것이 효과적입니다. RAGAS 같은 프레임워크를 사용하면 체계적인 평가가 가능합니다.


마치며

RAG는 LLM의 실용성을 크게 높이는 핵심 기술입니다. 기업의 내부 문서 검색, 고객 지원 챗봇, 법률 문서 분석 등 다양한 분야에서 활용되고 있으며, 앞으로도 그 중요성은 더욱 커질 것입니다.

처음에는 기본적인 RAG 파이프라인으로 시작하되, 실제 사용 사례와 데이터의 특성에 맞춰 점진적으로 개선해 나가는 접근이 바람직합니다. 청크 크기, 검색 개수, 프롬프트 엔지니어링 등 다양한 하이퍼파라미터를 실험하면서 최적의 설정을 찾아가시기 바랍니다.

profile
👩🏻‍💻

0개의 댓글