Python/NLP Code

LangChain으로 RAG를 구현하는 방법 기본 예제

jimmy_AI 2025. 1. 9. 00:39
반응형

안녕하세요.

이번 글에서는 LangChain에서 챗봇의 기본이 되는 RAG 시스템을 구현하는

기초적인 예제를 다루어보면서 방법을 이해해보도록 하겠습니다.

 

 

Step 1. LangChain 및 Pinecone 벡터 DB 세팅

먼저, LangChain 모듈 활용을 위한 준비가 되어있어야 합니다.

모듈 설치가 되어있지 않다면 다음과 같은 명령어로 설치를 진행해줍니다.

$pip install langchain
$pip install langchain-openai
$pip install langchain-community
$pip install langchain-pinecone

 

참고로, 이 글의 예제에서는 LLM은 openai의 GPT 모델을,

벡터 DB로는 Pinecone을 사용할 예정인데

다른 조합 사용을 원하신다면 이에 맞는 모듈 설치를 진행해주시면 됩니다.

 

파인콘 벡터 DB 활용을 위하여 API Key 발급과 index 생성 과정이 필요합니다.

이에 대한 상세한 방법은 아래의 포스팅을 참고해주세요.

 

벡터 데이터베이스 파인콘 맛보기 (Vector Database Pinecone)

▶ ChatGPT 국제학술지 '네이처(Nature)'에서 올 한 해 과학계에 큰 화제를 불러일으킨 10명의 인물을 선정하는 '네이처 10(Nature's 10)'을 발표했는데, 역대 최초로 인간이 아닌 생성형 인공지능(AI) 챗봇

www.whatwant.com

 

또한, OpenAI 모델 활용 시에는 OpenAI에서 발급받은 API Key도 필요합니다.

 

이제 환경 변수로 다음과 같은 값들을 추가해서 넣어주셔야 합니다.

.env 파일을 만들고, 다음과 같은 변수들을 추가해주도록 하겠습니다.

PINECONE_API_KEY="파인콘 사이트에서 받은 API Key"
INDEX_NAME="파인콘 사이트에서 만든 인덱스 이름"
OPENAI_API_KEY="openai에서 발급받은 API Key"

 

환경 변수는 다음과 같이 load_dotenv로 가져오는 것이 편리합니다.

from dotenv import load_dotenv

load_dotenv()

 

 

Step 2. 문서 인덱스 저장

이제 원하는 문서들을 인덱스 벡터로 저장해보도록 하겠습니다.

 

먼저, 문서를 가져와 load하는 과정이 필요한데요.

원하는 문서가 txt 파일이라고 가정한 경우 load 과정 코드 스니펫은 다음과 같습니다.

from langchain_community.document_loaders import TextLoader

loader = TextLoader("my_docs.txt", encoding="utf-8")
document = loader.load()

 

참고로, pdf, csv, json, html 등 다양한 문서도 Loader만 그에 맞게 선언해주면

사용법은 동일하며, 디렉토리 전체 내의 문서들을 한 번에 가져오는 것도 가능합니다.

 

다양한 Loader 종류에 대한 공식 문서:

 

How-to guides | 🦜️🔗 LangChain

Here you’ll find answers to “How do I….?” types of questions.

python.langchain.com

 

이제, 가져온 문서를 chunk 단위로 잘라서 보관해야 합니다.

이 과정은 다음과 같은 코드로 진행해주시면 됩니다.

from langchain_text_splitters import CharacterTextSplitter

# 각 청크 사이즈는 1000자, 청크 간에는 200자씩 겹치는 상황 가정
text_splitter = CharacterTextSplitter(
    chunk_size=1000,
    chunk_overlap=200,
    length_function=len,
)
texts = text_splitter.split_documents(document)

 

이후 각 chunk를 대상으로 임베딩을 진행하고,

이 결과를 파인콘 벡터 DB에 저장하는 과정을 진행해야 합니다.

 

다음과 같은 코드로 간단하게 진행할 수 있으나,

임베딩 모델을 벡터 DB에서 정했던 모델과 반드시 같은 종류로 지정해야 합니다.

import os
from langchain_openai import OpenAIEmbeddings
from langchain_pinecone import PineconeVectorStore

# 임베딩 모델 종류는 파인콘 DB의 모델과 동일해야 함
embeddings = OpenAIEmbeddings(model="text-embedding-ada-002")
PineconeVectorStore.from_documents(texts, embeddings, index_name=os.environ['INDEX_NAME'])

 

 

Step 3. RAG 구현

본격적으로 RAG 시스템을 구현하기 위하여

먼저 임베딩 및 LLM 모델을 선언하겠습니다.

from langchain_openai import OpenAIEmbeddings, ChatOpenAI

# 임베딩 모델 종류는 파인콘 DB의 모델과 동일해야 함
embeddings = OpenAIEmbeddings(model="text-embedding-ada-002")
llm = ChatOpenAI(model="gpt-4o-mini")

 

이후, Step 2에서 저장한 벡터스토어 정보는 다음과 같이 불러올 수 있습니다.

import os
from langchain_pinecone import PineconeVectorStore

vectorstore = PineconeVectorStore(
    index_name=os.environ["INDEX_NAME"], embedding=embeddings
)

 

이제, 질문을 직접 시도해볼 수 있습니다.

이 과정에 대한 예시 코드 스니펫은 다음과 같습니다.

from langchain import hub
from langchain.chains.combine_documents import create_stuff_documents_chain
from langchain.chains.retrieval import create_retrieval_chain

# RAG를 위한 프롬프트 불러오기(langchain hub에서)
retrieval_qa_chat_prompt = hub.pull("langchain-ai/retrieval-qa-chat")

# 여러 문서를 입력받아 체인으로 생성하기 위한 준비
combine_docs_chain = create_stuff_documents_chain(llm, retrieval_qa_chat_prompt)

# 질문에 알맞는 문서를 검색하고 넘겨주기 위한 준비
retrival_chain = create_retrieval_chain(
    retriever=vectorstore.as_retriever(), combine_docs_chain=combine_docs_chain
)

# 실제 질문 코드
query = "지미뉴트론 개발일기의 저자의 이름은?"
result = retrival_chain.invoke(input={"input": query})

# 질문, 답변, source document 정보 등이 포함된 딕셔너리 형태
print(result)

 

참고로, 문서를 검색하는 과정에서 반환할 문서 수나

similarity_score_threshold 등을 .as_retriever() 부분에서 인자로 조절할 수 있는데요.

 

이에 대한 상세한 내용은 다음 문서를 참고해보시면 도움을 받을 수 있습니다.

 

How to use a vectorstore as a retriever | 🦜️🔗 LangChain

A vector store retriever is a retriever that uses a vector store to retrieve documents. It is a lightweight wrapper around the vector store class to make it conform to the retriever interface.

python.langchain.com

 

대화 히스토리를 기반으로 하는 RAG 등 관련된

더 심화된 내용들은 다음 번에 기회가 되면 작성해보도록 하겠습니다.

 

이 글의 코드는 상당 부분 아래 링크의 유데미 강의

https://www.udemy.com/course/langchain-korean/

의 도움을 받아 작성되었습니다.

 

이 과정이 LangChain을 활용하여 RAG를 손쉽게 구현하는 과정에 도움이 되셨기를 바랍니다.

잘 봐주셔서 감사드립니다.