LlamaIndex를 활용한 RAG 애플리케이션 구축하기

ChatGPT나 Llama와 같은 대규모 언어 모델(LLM)은 질문에 답변하는 데 뛰어나지만, 학습된 지식에만 국한됩니다. 이들은 사적인 데이터에 접근하거나 학습 종료 시점 이후의 정보를 알지 못합니다. 그렇다면 어떻게 이들의 지식을 확장할 수 있을까요?
정답은 검색 강화 생성(Retrieval-Augmented Generation, RAG)에 있습니다. 오늘은 RAG 파이프라인을 살펴보고 LlamaIndex를 사용하여 어떻게 구축하는지 알아보겠습니다.
시작해볼까요!
검색 강화 생성: 기본 개념
LLM은 오늘날 가장 진보된 NLP 모델로서 번역, 글쓰기, 일반적인 질의응답에 탁월합니다. 하지만 특정 도메인의 질문에서는 어려움을 겪으며 종종 환각(hallucination)을 생성합니다.
이런 경우, 질의당 관련 컨텍스트를 포함하는 문서는 몇 개 뿐일 수 있습니다. 이를 해결하기 위해 응답을 생성하기 전에 관련 정보를 효율적으로 검색하고 통합하는 간소화된 시스템이 필요합니다. 이것이 바로 RAG의 핵심입니다.
사전 학습된 LLM은 다음 세 가지 주요 접근 방식으로 지식을 습득하며, 각각 한계가 있습니다:
- 학습: 처음부터 LLM을 구축하려면 수조 개의 토큰으로 대규모 신경망을 훈련해야 하며, 수억 달러의 비용이 들어 대부분에게 불가능합니다.
- 미세 조정: 사전 학습된 모델을 새로운 데이터에 적응시키는 방법이지만 시간과 자원이 많이 소요됩니다. 특별한 필요가 없다면 항상 실용적이지 않습니다.
RAG는 질의 시점에 관련 문서 세그먼트를 효율적으로 처리, 저장 및 검색함으로써 이러한 한계를 극복합니다. 이를 통해 LLM은 비용이 많이 드는 재학습이나 미세 조정 없이도 더 정확하고 컨텍스트를 인식하는 응답을 생성할 수 있습니다.
RAG 파이프라인의 주요 구성 요소
RAG 시스템은 여러 필수 구성 요소로 이루어져 있습니다:

- 텍스트 분할기: 큰 문서를 LLM의 컨텍스트 창에 맞는 작은 청크로 분할합니다.
- 임베딩 모델: 텍스트를 벡터 표현으로 변환하여 효율적인 유사성 검색을 가능하게 합니다.
- 벡터 저장소: 문서 임베딩과 메타데이터를 저장하고 검색하는 특수 데이터베이스입니다.
- LLM: 검색된 정보를 기반으로 답변을 생성하는 핵심 언어 모델입니다.
이러한 각 구성 요소는 RAG 시스템의 정확성과 효율성을 높이는 데 중요한 역할을 합니다.
LlamaIndex란 무엇인가?
LlamaIndex(이전의 GPTIndex)는 LLM 기반 애플리케이션을 구축하기 위한 파이썬 프레임워크입니다. 커스텀 데이터 소스와 대규모 언어 모델 사이의 다리 역할을 하며, 데이터 수집, 인덱싱, 쿼리를 간소화합니다.
다양한 데이터 소스, 벡터 데이터베이스, 쿼리 인터페이스를 기본 지원하여 RAG 애플리케이션을 위한 올인원 솔루션으로 작동합니다. 또한 LangChain, Flask, Docker와 같은 도구와 원활하게 통합되어 실제 구현에 매우 유연합니다.
LlamaIndex로 간단한 RAG 시스템 구현하기
1단계: 환경 설정
구현에 들어가기 전에 파이썬 환경을 설정하고 필요한 종속성을 설치해야 합니다. 가상 환경을 사용하면 종속성을 효율적으로 관리할 수 있습니다:
python -m venv rag_env
source ragenv/bin/activate # Windows에서는: ragenv\Scripts\activate
이제 필요한 라이브러리를 설치할 수 있습니다. LlamaIndex, OpenAI, FAISS는 RAG 시스템 구축에 필수적입니다:
pip install llama-index openai faiss-cpu
LlamaIndex가 OpenAI 모델을 쿼리할 수 있도록 OpenAI API 키를 구성하는 것도 잊지 마세요:
import os
os.environ["OPENAIAPIKEY"] = "your-api-key-here"
2단계: 문서 로드
검색이 작동하려면 먼저 문서를 시스템에 로드해야 합니다. LlamaIndex는 이 과정을 효율적으로 처리하기 위한 SimpleDirectoryReader를 제공합니다. 이 예제에서는 LLM의 지식을 확장하기 위해 Attention Is All You Need 논문을 사용합니다.
from llama_index import SimpleDirectoryReader
디렉토리에서 텍스트 파일 로드
documents = SimpleDirectoryReader("./data").load_data()
print(f"Loaded {len(documents)} documents")
3단계: 텍스트 분할 생성
LLM은 컨텍스트 창 제한이 있어 전체 문서를 한 번에 전달할 수 없습니다. 대신 효율적인 검색을 위해 작고 구조화된 청크로 나눕니다.
from llamaindex.textsplitter import SentenceSplitter
문장 기반 텍스트 분할기 정의
textsplitter = SentenceSplitter(chunksize=512, chunk_overlap=50)
문서에 텍스트 분할 적용
nodes = textsplitter.splittext([doc.text for doc in documents])
print(f"Split into {len(nodes)} chunks")
4단계: 임베딩으로 문서 인덱싱
의미 검색을 수행하려면 문서 청크를 벡터 임베딩으로 변환하고 인덱스에 저장해야 합니다.
from llama_index import VectorStoreIndex
인덱스 생성
index = VectorStoreIndex(nodes)
인덱스 지속 (선택사항)
index.storagecontext.persist(persistdir="./storage")
5단계: RAG로 인덱스 쿼리
여기서 RAG가 실제로 작동합니다. 인덱싱된 문서를 쿼리하여 관련 정보를 검색하고 LLM 기반 응답을 생성합니다.
from llamaindex.queryengine import RetrieverQueryEngine
queryengine = RetrieverQueryEngine.fromargs(index.as_retriever())
response = query_engine.query("What is attention?")
print(response)
위 코드를 실행하면 다음과 같은 결과를 얻습니다:
Attention is a mechanism used in deep learning models to focus on relevant parts of the input sequence while processing data. In the paper 'Attention Is All You Need,' Vaswani et al. introduced the Transformer architecture, which relies entirely on self-attention mechanisms instead of recurrence or convolution. The key innovation is the self-attention mechanism, which allows the model to weigh the importance of different words in a sentence relative to each other, enabling better parallelization and long-range dependencies.
성공했습니다!
마무리
LlamaIndex를 활용한 RAG 시스템 구축은 학습 데이터를 넘어 LLM을 활용할 수 있는 흥미로운 가능성을 열어줍니다. 문서 검색, 임베딩 기반 인덱싱, 실시간 쿼리를 통합함으로써 RAG는 정확성을 높이고 환각을 줄여 도메인별 애플리케이션을 위한 강력한 솔루션이 됩니다.
이 가이드의 단계별 구현을 통해 이제 다음과 같은 여러 방식으로 확장할 수 있는 기능적인 RAG 파이프라인을 갖게 되었습니다:
- OpenAI, Cohere, Hugging Face와 같은 모델을 사용한 임베딩 커스터마이징
- 확장 가능한 검색을 위해 Pinecone, Weaviate, ChromaDB와 같은 벡터 데이터베이스 통합
- Flask, FastAPI 또는 챗봇 인터페이스를 통한 API 배포
- 검색 품질 향상을 위한 텍스트 청킹 전략 최적화
이제 여러분 차례입니다. 실험하고, 반복하며, LlamaIndex로 가능한 것의 경계를 넓혀보세요!