안녕하세요.
이번 글에서는 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 생성 과정이 필요합니다.
이에 대한 상세한 방법은 아래의 포스팅을 참고해주세요.
또한, 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 종류에 대한 공식 문서:
이제, 가져온 문서를 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() 부분에서 인자로 조절할 수 있는데요.
이에 대한 상세한 내용은 다음 문서를 참고해보시면 도움을 받을 수 있습니다.
대화 히스토리를 기반으로 하는 RAG 등 관련된
더 심화된 내용들은 다음 번에 기회가 되면 작성해보도록 하겠습니다.
이 글의 코드는 상당 부분 아래 링크의 유데미 강의
https://www.udemy.com/course/langchain-korean/
의 도움을 받아 작성되었습니다.
이 과정이 LangChain을 활용하여 RAG를 손쉽게 구현하는 과정에 도움이 되셨기를 바랍니다.
잘 봐주셔서 감사드립니다.
'Python > NLP Code' 카테고리의 다른 글
LangChain이란? / 설치 방법 및 기본 코드 예제 (2) | 2025.01.05 |
---|---|
파이썬 챗봇 개발 라이브러리 Llama Index 예제 및 장점 정리 (0) | 2024.12.17 |
ChatGPT 모델 fine-tuning 진행하는 방법 파이썬 코드 예제 (2) | 2024.11.10 |