RAG 개요
RAG란?
예를 들어봅시다. 학교 선도부 관리자인 A는 "규정 모음집"대로 학생들을 관리하고 있습니다. 총 300페이지가 되는 규정모음집인데 , 학생들이 책은 안 보고 자꾸 A에게 이 항목은 규정에 위반이 되는지 안 되는지 계속 물어봐서 A는 이를 간편화하고싶어합니다. 이 때 RAG를 사용하여 규정모음집을 DB로 구성하고 챗봇을 구성하였습니다
🍈 Vector DB 구축 절차
Vector DB :대규모 텍스트 데이터 및 임베딩 벡터를 저장, 검색용
- Loader : 다양한 소스에서 문서를 불러오고 처리(데이터 변환 및 정제)하는 과정을 담당 (pdf,csv 파일 load 가능)
from langchain.document_loaders import TextLoader
# 텍스트 파일 경로 지정
file_path = "상록수.txt"
# TextLoader를 이용하여 문서 로드
loader = TextLoader(file_path)
documents = loader.load()
# 로드된 문서 출력
print(documents)
- Split : chunk 단위로 분할, Document 객체로 만들기 (LangChain에서 사용할 수 있는 문서 객체 Document)
text_splitter = CharacterTextSplitter(
chunk_size = 500,
chunk_overlap = 100,
separator = '\n', # 어떤 기준 없이 무조건 500자 단위로 나누라
)
split_texts = text_splitter.split_text(text)
# 결과 확인
for i, chunk in enumerate(split_texts[:5]): # 처음 5개 청크만 출력
print(f"청크 {i+1}, 길이 {len(chunk)}: {chunk}\n")
- 텍스트 벡터화 : text embedding
- 텍스트 데이터를 숫자로 이루어진 벡터로 변환하면서 의미적인 정보를 보존하도록 설계
from langchain.embeddings import OpenAIEmbeddings
embedding_model = OpenAIEmbeddings(model="text-embedding-ada-002")
- vector db로 저장 : vector store
from langchain.vectorstores import Chroma
# ChromaDB를 만들면서 저장
vectorstore = Chroma.from_texts(split_texts, embedding_model,
persist_directory="./chroma_db")
🍈 Vector DB와 RAG 파이프라인 구축
- Retriever 선언
retriever = vectorstore.as_retriever(search_type="similarity", search_kwargs={"k": 5})
llm =
- llm 모델 지정
llm = ChatOpenAI(model_name="gpt-4o-mini")
- 메모리 선언
memory = ConversationBufferMemory(memory_key="chat_history", return_messages=True,
output_key=“answer")
- 체인함수로 각 모듈을 연결
qa_chain = ConversationalRetrievalChain.from_llm(
llm = llm,
retriever = retriever,
memory = memory,
return_source_documents=False # 검색된 문서 출력 옵션
)
🍈 다양한 방법들
- Loader ㅡ PDF Loader
from langchain.document_loaders import PyMuPDFLoader
# PDF 파일 로드
pdf_path = "2025년 사이버 위협 전망 보고서.pdf"
pdf_loader = PyMuPDFLoader(path + pdf_path)
# 문서 로드 실행
documents_pdf = pdf_loader.load()
# 출력 확인
print(f"총 {len(documents_pdf)} 개의 페이지가 로드됨")
- Loader ㅡ CSV Loader >일반 행을 각 청크의 의미로 보고, 별도 split하지 않을 수 있다.
from langchain.document_loaders import CSVLoader
# CSV 파일 로드
csv_path = "sample.csv"
loader = CSVLoader(file_path=csv_path)
# 문서 로드 실행
documents = loader.load()
print(documents[0].page_content)
- Splitter ㅡ 지정 순서대로 순차 적 기준 적용
# 텍스트 청크 분할
text_splitter = RecursiveCharacterTextSplitter(
chunk_size=500,
chunk_overlap=100,
separators=["\n\n", "\n",". "]
)
split_docs = text_splitter.split_documents(documents_pdf)
- Embedding & Store ㅡ FAISS
from langchain.vectorstores import FAISS
vectorstore = FAISS.from_documents(split_docs, embedding_model)
vectorstore.save_local("faiss_index")
.pkl ㅡ>파이썬에서 어떤 중요한 정보가 저장되었나보다 이정도로 생각
- RAG 파이프라인에 프롬프트 템플릿 추가
LLM에게 {question}과 {context} 전달
# 프롬프트 템플릿
prompt = ChatPromptTemplate.from_messages([
("system", "너는 사이버 보안 분야 전문가야. 답변은 간결하게 해줘."),
("human", "질문: {question}\n\n관련 문서:\n{context}") ])
# 체인 구성
qa_chain = ConversationalRetrievalChain.from_llm(
llm=llm,
retriever=retriever,
memory=memory,
combine_docs_chain_kwargs={"prompt": prompt},
return_source_documents=True )
배우고 나니까 Langchain,LLM,RAG 헷갈리네요
반응형
'KT에이블스쿨' 카테고리의 다른 글
[KT AIVLE SCHOOL] KT 에이블스쿨 7기 합격후기 (1) | 2025.04.28 |
---|---|
[KT AIVLE SCHOOL] AGENT (0) | 2025.04.27 |
[KT AIVLE SCHOOL] LangChain (0) | 2025.04.21 |
[KT AIVLE SCHOOL] LLM (0) | 2025.04.18 |
[KT AIVLE SCHOOL] 1차 미니프로젝트 (1) | 2025.04.15 |