AI/Langchain RAG

03. Retriever

러시안블루 크레아 의 집 2024. 8. 6. 23:52

앞서 Langchain RAG에 대해 설명하고, Document Loaders, Text Splitters, Text Embedings, Vector Store에 대해 다루었다.

  

본 chapter 에서는 Retriever 에 대해 기술 한다.

바로 본론으로 들어가자.


 


1. Retriever

Retriever는 비정형 쿼리가 주어지면 문서를 반환하는 인터페이스이다. 벡터 저장소보다 더 일반적이다. Retriever는 문서를 저장할 필요 없이 단지 반환만 할 수 있다.

쉽게 말해, Retriever는 검색을 쉽게 할 수 있도록 구성된 모듈이다다. 이를 통해 손쉽게 문서를 검색할 수 있도록 하고 이를 기반으로 LLM과 대화할 수 있도록 한다.

 

 

1) VectorIndexCreator



#############################
### VECTORSTORE RETRIEVER ###
### 1. VectorIndexCreator
#############################

from langchain.chains import RetrievalQA
from langchain.chat_models  import ChatOpenAI
from langchain.text_splitter import RecursiveCharacterTextSplitter

import os
os.environ["OPENAI_API_KEY"] = '*********************'

llm = ChatOpenAI(
    model_name='gpt-4o',
)

retriever = db3.as_retriever()
qa = RetrievalQA.from_chain_type(llm=llm, chain_type="stuff", retriever=retriever, return_source_documents = True)

def process_response(llm_response):
  print(llm_response['result'])
  print('\n\n출처:')
  for source in llm_response['source_documents']:
    print(source.metadata['source'])

 
query = "전자결재 누르고 들어가보면 결재리스트가 빨간색 글씨인데 저건 뭐가 다른거야?"
response = qa(query)
process_response(response)

 

VectorIndexCreator는 문서 분할 - 임베딩 - 벡터 저장의 3가지 단계를 한 줄로 수행가능하도록 하는 함수이다. 단순히 문서 loader를 넘겨줌으로써, 문서에 대한 질문이 가능하도록 한다.
또한 이를 통해 생성한 index 객체에 query()함수를 통해 질문하면 QA Chain이 작동하여 LLM이 답변까지 한다.

 

 

 

 

2) MultiQueryRetriever


#############################
### VECTORSTORE RETRIEVER ###
### 2. MultiQueryRetriever
#############################

from langchain.chat_models  import ChatOpenAI
from langchain.text_splitter import RecursiveCharacterTextSplitter
from langchain.vectorstores import Chroma
from langchain.retrievers.multi_query import MultiQueryRetriever
from langchain.chains import RetrievalQA
import os
os.environ["OPENAI_API_KEY"] = ' ********************* '

llm = ChatOpenAI(
    model_name='gpt-4o',
)

question="전자결재 누르고 들어가보면 결재리스트가 빨간색 글씨인데 저건 뭐가 다른거야?"
num_queries=10

from langchain.embeddings import HuggingFaceEmbeddings
model_name = "jhgan/ko-sbert-nli"
model_kwargs = {'device': 'cpu'}
encode_kwargs = {'normalize_embeddings': True}
hf = HuggingFaceEmbeddings(
    model_name=model_name,
    model_kwargs=model_kwargs,
    encode_kwargs=encode_kwargs
)

db3 = Chroma(persist_directory="/acc/AI_project/chroma_db", embedding_function=hf)
retriever_from_llm = MultiQueryRetriever.from_llm(retriever=db3.as_retriever(),llm=llm)
unique_docs = retriever_from_llm.get_relevant_documents(query=question)

text_splitter = RecursiveCharacterTextSplitter.from_tiktoken_encoder(chunk_size=1000, chunk_overlap=0)
docs = text_splitter.split_documents(unique_docs)

db3 = Chroma.from_documents(docs, hf)

retriever_from_llm = MultiQueryRetriever.from_llm(retriever=db3.as_retriever(),llm=llm)
qa = RetrievalQA.from_chain_type(llm=llm, chain_type="stuff", retriever=retriever_from_llm)

qa.run(question)

 

 

MultiQueryRetriever는 사용자의 질문과 연관된 문서를 추출하기 위해 여러 쿼리를 자동으로 생성하여 검색하는 Retriver이다. 질문의 의도는 하나지만, 표현이 여러개일 수 있는 것처럼, 연관된 문서 또한 여러 문서가 포함될 수 있다. MultiQueryRetriever는 자동으로 사용자 질문을 여러 표현으로 각색하고, 이를 통해 연관 문서를 여러개 추출한다. 그리고 그 문서들을 활용해 더욱 높은 품질의 답변을 출력할 수 있다.

 

 

 


 

 

이것으로 LangChain RAG에 대한 기술을 마치겠다.

다음엔 Fine Tuning에 대해 다뤄볼까 한다.