RAG의 과정 훑어보기

=========== RAG 구축 시작!! ==============

  1. 문서 로딩
    • JSON, 이미지, 텍스트, CSV, PDF 등 다양한 문서가 들어갈 수 있다.
  2. 문서 chunking (spliting)
    • chunking은 긴 문서를 더 작고 관리하기 쉬운 부분들로 나누는 과정
    • vectorDB(벡터 DB)에 chunk단위로 적재하게 된다.
  3. embedding
    • 문자열형태의 chunk를 벡터(숫자)로 변환하는 과정
  4. 벡터 스토어
    • 이전 단계에서 생성된 임베딩 벡터들을 효율적으로 저장하고 관리하는 저장소

   

5. 리트리버

  • 물어오기! 저장된 벡터 데이터베이스에서 사용자의 질문과 관련된 문서(context)를 검색(물어오기)하는 검색기

=========== RAG 구축 끝!! ==============


=========== 구축해 둔 RAG 챗봇 구동 시작 ==========

  1. 사용자가 질문하기 :
    • 사용자 : 우리 회사의 야근식대는 얼마야?
  2. Retrieval(검색) :
    • 리트리버가 사용자 질문에 대한 자료를 벡터 DB에서 검색해 옴
    • 질문과 연관성이 높은 청크를 검색해서 context로 리턴한다.
  3. Augment(증강) : 프롬프트 = context(벡터 DB에서 검색해 온 자료) + query(사용자 질문)
# 기본 틀
prompt = ChatPromptTemplate.from_template("""
오로지 아래의 context만을 기반으로 질문에 대답하세요:
{context}
질문:
{question}
""")

 

⬇️

 

# 질문 입력
prompt = ChatPromptTemplate.from_template("""
오로지 아래의 context만을 기반으로 질문에 대답하세요:
야근 식대는 2만원 입니다.
질문:
우리 회사의 야근 식대는 얼마입니까?
""")

 

  4. Generation(생성) : LLM에 완성된 프롬프트 집어넣고 답변받기

  • 프롬프트에는 질문에 답변할 수 있는 자료(context, 맥락)가 있으니, LLM은 이를 기반으로 환각 없이 잘 대답할 수 있다.
  • 무한상사 사규 챗봇: 우리 회사의 야근식대는 2만 원입니다.

pip install langchain_openai
pip install langchain-community
pip install pypdf
pip install faiss-cpu

 

필요해요! 설치해 주세요 😎

 

import os
from getpass import getpass

os.environ["OPENAI_API_KEY"] = getpass("OpenAI API key 입력: ")

 

OpenAI API key를 입력하고 시작합시다 😎

 

더보기
from langchain_community.vectorstores import FAISS
from langchain_community.document_loaders import WebBaseLoader
from langchain_core.output_parsers import StrOutputParser, CommaSeparatedListOutputParser
from langchain_core.runnables import RunnablePassthrough
from langchain_openai import OpenAIEmbeddings
from langchain_text_splitters import RecursiveCharacterTextSplitter
from langchain_openai import ChatOpenAI
from langchain_core.prompts import ChatPromptTemplate
from langchain.document_loaders import PyPDFLoader

####################
####### RAG 챗봇 구축
###################

# 1. LLM 모델 불러오기
llm = ChatOpenAI(model="gpt-4o-mini")

# 2. 문서 불러오기
loader = PyPDFLoader("/Users/baeminkyung/Desktop/github/UNO_BWMovie_recsys/김용수-INTP.pdf")
docs = loader.load()

# 3. 문서 chunking 하기 == 자르기
text_splitter = RecursiveCharacterTextSplitter(chunk_size=1000, chunk_overlap=200) # 연관성을 위해서 겹쳐서 200 만큼 중북하여 자름
splits = text_splitter.split_documents(docs)

# 4. 자른 chunk들을 embedding 하기 == 숫자 벡터 형태로 변환
embeddings = OpenAIEmbeddings(model="text-embedding-ada-002")

# 5. vector store 구축하기(== 저장) -> 김용수-INTP.pdf 이 파일이 숫자화 됨
# ChromaDB, FAISS 등이 있음 (플뢧폼_저장소) 
vectorstore = FAISS.from_documents(documents=splits, embedding=embeddings)

# 6. retriever 구축하기 -> 정보 물어오기
retriever = vectorstore.as_retriever()


# 7. 프롬프트 템플릿 구축하기 (물어온 데이터로)
# {context} == 벡터 DB로 구성됨
prompt = ChatPromptTemplate.from_template("""
너는 {personality}하는 성격의 안성재 셰프야. 그리고 너는 영화를 추천해주는 역할이야. \
답변을 끝낸 문장 끝에 '이 정도면 적절하게 추천해드린 것 같거덩요'를 붙여야 해. \
서술어로는 '~거덩요'로 완성해서 대답해줘. \
나의 말에 대답하도록 해. \
오로지 아래의 context만을 기반으로 질문에 대답하세요:
{context}
질문:
{question} """) # "용수 님의 mbti가 뭐야?"

personality = "대기업의 유능한 비서처럼 신경쓰길 좋아"
question = "용수님의 mbti가 뭐야?"

# 8. 1~7. 요소들을 chain으로 조합하여 RAG 구축 완료
def format_docs(docs):
    return "\n\n".join(doc.page_content for doc in docs)

rag_chain = (
    {"context": retriever | format_docs, "question": RunnablePassthrough()}
    | prompt
    | llm
    | CommaSeparatedListOutputParser()
)

####################
####### 구축한 RAG 챗봇 실행
###################

rag_chain.invoke({"question": question, "personality": personality})
rag_chain.invoke("용수님의 mbti 중 선호 분명도 지수 좀 알려줄래?")

 

제 정보가 아니라 모자이크 처리,,

 

| CommaSeparatedListOutputParser() 을 통해서 이렇게 깔끔히 결과물을 받아냈어요.

 

RAG와 LangChain을 통해서 구현해 낸 적이 처음이라, 너무 낯설고 어렵네요,, 🥲

 

인내를 가져주시고 코드 하나하나 알려주셔서 너무 감사했어요,, 많이 배워가겠습니다 🥲

 

🐾Recent posts