본문 바로가기
📚도서 공부/LangChain으로 구현하는 LLM

5-3(챗봇이란?, 로딩 및 검색) 챗봇 만들기

by Majestyblue 2024. 5. 11.

다. LangChain에서의 로딩 및 검색

LangChain은 검색 시스템을 구축하기 위한 여러 구성 요소의 도구 체인을 구현한다.

먼저 데이터 로더를 통해 문서를 로드한다 → 문서를 변환하고 임베딩으로 사용할 수 있도록 벡터 저장소에 전달 → 벡터 저장소와 관련된 검색기(retriever)를 쿼리

1) 문서 로더

문서 로더는 데이터를 소스에서 document 객체러 로드하는데 사용된다. Document 객체는 텍스트와 관련된 메타데이터로 구성된다.

txt 파일을 로드하는 TextLoader, 웹 페이지 텍스트를 로드하는 WebBaseLoader, Arxiv에서 기사를 로드하는 ArxivLoader, 유튜브 대본을 로드하는 YoutubeLoader 등이 있다. 웹 페이지의 경우 Diffbot 통합을 사용하면 내용을 깔끔하게 추출할 수 있으며 ImageCaptionLoader와 같이 이미지에 대한 캡션을 제공하는 이미지와 관련된 다른 통합도 있다.

문서 로더에는 load() 메서드를 이용해 데이터를 로드하고 문서로 반환할 수 있으며 필요할 때 메모리로 데이터를 로드하기 위해 lazy_load() 메서드를 사용할 수 있다.

2) LangChain에서의 검색기(retriever)

벡터 저장소를 벡엔드로 사용해 주어진 인덱스에서 정보를 탐색하고 검색할 때 사용되는 구성 요소 유형이다. 임베딩을 인덱싱하고 검색하는데 사용된다. 검색기는 문서에 대한 질문에 답할 때 중요한 역할을 한다.

아래는 몇 가지 검색기의 예시이다.

  • BM25 검색기: BM25 알고리즘을 사용해 주어진 쿼리와의 관련성에 따라 문서를 순위화한다. 단어 빈도와 문서 길이를 고려하는 인기 있는 정보 검색 알고리즘이다.
  • TF-IDF 검색기: Term Frequency Inverse Document Frequency, 단어 빈도-역문서 빈도 알고리즘을 사용해 문서 모음 내에서 용어의 중요성에 따라 문서를 순위화한다. 이는 모음에서 희귀한 용어에 더 높은 가중치를 할당하지만 특정 문서에서 자줄 발생하는 용어에는 낮은 가중치를 할당한다.
  • Dense 검색기: 밀집 임베딩을 사용해 문서를 검색한다. 문서와 쿼리를 밀집 벡터로 인코딩하고 코사인 유사도나 다른 거리 측도를 사용해 그들 간의 유사도를 계산 한다.
  • kNN 검색기: k-최근접 이웃 알고리즘을 활용해 주어진 쿼리와의 유사도에 따라 관련된 문서를 검색한다.

(1) kNN 검색기

간단한 kNN 검색기 사용 예시

from langchain_community.embeddings import HuggingFaceEmbeddings
from langchain.retrievers import KNNRetriever

embeddings_model = HuggingFaceEmbeddings(
    model_name='jinaai/jina-embeddings-v2-small-en',
    model_kwargs={'device':'cpu'},
    encode_kwargs={'normalize_embeddings':True},
)

words = ["cat", "dog", "computer", "animal"]
retriever = KNNRetriever.from_texts(words, embeddings_model)
result = retriever.get_relevant_documents("dog")
print(result)

<출력결과>
[Document(page_content='dog'), 
 Document(page_content='cat'), 
 Document(page_content='animal'), 
 Document(page_content='computer')]

 

(2) PubMed 검색기

PubMed 검색기는 생체 의학 문헌 검색을 언어 모델 애플리케이션에 통합하는데 도움을 주며 다양한 출처의 생체 의학 문헌에 대한 수백만 건의 인용을 포함하고 있다.

PubMedRetriever 클래스의 get_relevant_documents() 메서드를 사용하여 쿼리를 입력 받아 PubMed에서 관련 문서의 목록을 반환한다. 아래는 PubMed를 검색기를 사용하는 예시로 get_relevant_documents() 에서 쿼리(”COVID”)와 관련된 문서를 검색하고 목록으로 반환한다.

pip install xmltodict

from langchain.retrievers import PubMedRetriever
retriever = PubMedRetriever()
documents = retriever.get_relevant_documents("COVID")
for document in documents:
    print(document.metadata["Title"])
    
<출력결과>
Comprehensive Analysis of Omicron Subvariants: EG.5 Rise, Vaccination Strategies, and Global Impact.
Biological Potential and Therapeutic Effectiveness of Phytoproduct 'Fargesin' in Medicine: Focus on the Potential of an Active Phytochemical of Magnolia fargesii.
Impact of COVID-19 pandemic on physical health amongst children: Difference-in-differences analyses of nationwide school health checkup database.
오미크론 하위 변이의 종합적 분석: EG.5 상승, 예방접종 전략 및 글로벌 영향.
의학에서 식물성 제품 '파르게신'의 생물학적 잠재력과 치료 효과: 목련 파르게시의 활성 식물화학의 잠재력에 주목합니다.
코로나19 범유행이 아동의 신체건강에 미치는 영향: 전국 학교건강검진 데이터베이스의 이중차분 분석.

 

(3) 맞춤형 검색기

BaseRetriever 추상 클래스를 상속받은 클래스를 생성하여 사용자 정의 검색기를 구현할 수 있다. get_relevant_documents() 메서드를 구현해야 하며 이 메서드는 쿼리 문자열을 입력으로 받아 관련 문서 목록을 반환한다.

from langchain.schema import Document, BaseRetriever

class MyRetriever(BaseRetriever):
    def get_relevant_documents(self, query: str, kwargs) -> list[Document]:
        # 여기에 본인의 검색 로직을 구현한다.
        # 퀴리에 기반한 문서 검색과 프로세스
        # 연관된 문서의 르스트 반환

        relevant_documents = []

        return relevant_documents