AI/LLM

RAG (Retrieval-Augmented Generation)

growdai1y 2025. 1. 23. 18:11

RAG는 대규모 언어 모델(LLM)을 보완하기 위해 설계된 기술입니다. 이는 외부 데이터베이스의 검색 기능과 언어 생성 모델을 통합하여 신뢰성 있는 정보를 기반으로 높은 품질의 답변을 생성합니다.
기존 언어 모델은 학습 데이터에 의존해 고정된 정보를 생성하는 데 반해, RAG는 실시간으로 외부 데이터를 검색하여 최신 정보와 풍부한 맥락을 반영합니다. 예를 들어, 특정 제품의 기술 문서를 요약하거나 최근 뉴스에 대해 설명하는 데 RAG는 기존 접근법을 능가하는 결과를 제공합니다.


작동 원리: RAG의 두 축

검색기(Retriever):
사용자의 질문을 기반으로 벡터 데이터베이스에서 관련 문서를 검색합니다. 검색기는 입력 질문을 벡터로 변환하고, 유사성을 비교하여 적합한 데이터를 탐색합니다. 이 과정에서 빠른 검색을 위해 FAISS, Pinecone 등 최신 벡터 데이터베이스 기술이 활용됩니다.

생성기(Generator):
검색된 문서를 바탕으로 GPT-4와 같은 언어 모델이 자연스러운 답변을 생성합니다. 생성 모델은 검색된 정보를 보완하거나 요약하여 사용자 요구에 맞춘 출력을 제공합니다.


사전 준비 단계

RAG 사전 준비 단계
RAG 사전 준비 단계

문서 로드(Document Loader):
외부 데이터 소스에서 문서를 가져옵니다.

import os

def load_documents(directory):
    documents = []
    for filename in os.listdir(directory):
        if filename.endswith('.txt'):
            with open(os.path.join(directory, filename), 'r') as file:
                documents.append(file.read())
    return documents

docs = load_documents("/path/to/documents")

 
텍스트 분할(Text Splitter):
큰 문서를 처리 가능한 작은 단위로 나눕니다.

def split_text(documents, chunk_size=500):
    chunks = []
    for doc in documents:
        for i in range(0, len(doc), chunk_size):
            chunks.append(doc[i:i+chunk_size])
    return chunks

text_chunks = split_text(docs)

 
임베딩 생성(Embedding):
문서를 벡터 형식으로 변환하여 데이터의 의미를 수치화합니다.

from sentence_transformers import SentenceTransformer

model = SentenceTransformer('all-MiniLM-L6-v2')
embeddings = model.encode(text_chunks)

 
벡터 저장(Vector Store):
임베딩된 데이터를 벡터 데이터베이스에 저장합니다.

import faiss

dimension = embeddings.shape[1]
index = faiss.IndexFlatL2(dimension)
index.add(embeddings)

런타임 동작 단계

RAG 런터임 동작 단계
RAG 런터임 동작 단계

 
검색기 작동(Retriever):
질문 벡터와 유사한 문서를 벡터 데이터베이스에서 검색합니다.

question = "What is RAG?"
question_embedding = model.encode([question])
distances, indices = index.search(question_embedding, k=5)
relevant_chunks = [text_chunks[i] for i in indices[0]]

 
프롬프트 구성(Prompt):
검색 데이터를 바탕으로 질문을 구체화합니다.

prompt = "\n".join(relevant_chunks) + f"\nAnswer the question: {question}"

 
응답 생성(LLM):
검색된 문서를 바탕으로 언어 모델이 답변을 생성합니다.

from openai import Completion

response = Completion.create(
    model="gpt-4",
    prompt=prompt,
    max_tokens=200
)
print(response['choices'][0]['text'])

 
체인 생성(Chain):
위 과정을 하나의 파이프라인으로 연결하여 자동화합니다.

def rag_pipeline(question, model, index, text_chunks):
    question_embedding = model.encode([question])
    distances, indices = index.search(question_embedding, k=5)
    relevant_chunks = [text_chunks[i] for i in indices[0]]
    prompt = "\n".join(relevant_chunks) + f"\nAnswer the question: {question}"
    response = Completion.create(
        model="gpt-4",
        prompt=prompt,
        max_tokens=200
    )
    return response['choices'][0]['text']

answer = rag_pipeline("What is RAG?", model, index, text_chunks)
print(answer)

RAG의 장점

최신성: 실시간 데이터 검색을 통해 최신 정보를 반영합니다.

정확성: 신뢰할 수 있는 외부 데이터를 활용하여 답변의 품질을 높입니다.

확장성: 벡터 데이터베이스를 쉽게 업데이트할 수 있어 새로운 데이터를 통합하기 용이합니다.


RAG의 한계

데이터 품질: 검색된 데이터가 부정확하면 출력 품질이 저하됩니다. 신뢰할 수 있는 데이터 소스를 사용하는 것이 중요합니다.

응답 지연: 검색과 생성을 결합하면서 처리 속도가 느려질 수 있습니다. 이를 극복하기 위해 고속 검색 기술과 최적화된 LLM을 사용해야 합니다.

복잡성: RAG 시스템 구축은 초기 설계와 구현이 까다로울 수 있지만, 적절한 도구와 워크플로를 활용하면 해결할 수 있습니다.


결론

RAG는 검색과 생성을 결합해 정교한 결과를 제공합니다. 개인적으로는 RAG는 레거시 소프트웨어의 문서화를 효과적으로 지원하는 시스템 구축에 유용한 도구가 될 수 있을 것 같습니다. 기존의 문서화 도구로 항상 실패했던 문제를 RAG는 극복할 가능성을 보여주는 것 같습니다. RAG를 통해 개발자는 프롬프트 기반으로 문서를 효율적으로 활용하고, 응답 결과가 부실할 경우 개발자가 문서를 자연스럽게 업데이트하도록 유도할 수 있습니다. RAG를 도입해 레거시 SW 문서화 작업을 한 번 시도해 봐야 겠습니다. 
 
 

반응형