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

5-3(챗봇이란?, 문서 로더 구현) 챗봇 만들기

by Majestyblue 2024. 5. 15.

라. 챗봇 구현-1 문서 로더 설정

간단한 챗봇을 LangChain에서 아래의 레시피에 따라 만들어 보자.

  1. 문서 로더 설정
  2. 문서를 벡터 저장소에 저장
  3. 벡터 저장소에서 정보를 검색하는 챗봇 설정

이를 여러 형식으로 일반화하고 Streamlit을 통한 웹 브라우저 인터페이스를 통해 사용 가능하게 만들어 볼 것이다. 문서를 끌어다 놓고 질문을 시작할 수도 있게 해보자. 문서 로더부터 시작하자.

1. 문서 로드

import logging
import pathlib
from typing import Any
from langchain.schema import Document
from langchain.document_loaders import PyPDFLoader, TextLoader, UnstructuredWordDocumentLoader, UnstructuredEPubLoader

class EpubReader(UnstructuredEPubLoader):
    def __init__(self, file_path: str|list[str], kwargs:Any):
        super().__init__(file_path, kwargs, model="elements", strategy="fast")

class DocumentLoaderException(Exception):
    pass

class DocumentLoader(object):
    """Loads in a document with a supported extension."""
    supported_extentions = {
        ".pdf": PyPDFLoader,
        ".txt": TextLoader,
        ".epub": EpubReader,
        ".docx": UnstructuredWordDocumentLoader,
        ".doc": UnstructuredWordDocumentLoader
    }
    
def load_document(temp_filepath: str) -> list[Document]: 
    """Load a file and return it as a list of documents."""
    ext = pathlib.Path(temp_filepath).suffix 
    loader = DocumentLoader.supported_extentions.get(ext) 
    if not loader: 
        raise DocumentLoaderException(
            f"Invalid extenstion type {ext}, cannot laod this type of file"
        )
        
    loader = loader(temp_filepath) 
    docs = loader.load() 
    logging.info(docs) 
    return docs 

<핵심 코드 설명>

  • import logging : log 관리 라이브러리
  • import pathlib : 파일 시스템 경로를 객체 지향적으로 다루는 라이브러리
  • from typing import Any : 타입 힌트를 위한 Any타입(어떤 타입도 가능) 임포트
  • from langchain.schema import Document : langchain에서 입출력과 관련된 구조로 Document 형식(데이터와 메타데이터를 하나로 표현함)지정
  • class EpubReader def __init__(self, file_path: str|list[str], kwargs:Any) : 생성자 정의, file_path는 로드할 파일 경로, kwargs는 추가 인자를 위한 딕셔너리
    super().__init__(file_path, kwargs, model="elements", strategy="fast") : 상위 클래스의 생성자 호출, 로딩 전략과 모델을 설정.
  • class DocumentLoaderException(Exception) : 문서 로드 중 발생할 수 있는 예외를 처리하기 위한 클래스, 파이썬의 기본 Exception 클래스를 상속받는다.
  • class DocumentLoader(object) supported_extentions : 지원하는 파일 확장자와 해당 확장자를 처리할 로더 클래스의 매핑을 정의
  • def load_document(temp_filepath: str) -> list[Document]: 파일 경로를 받아 해당 파일을 로드하고, 로드된 문서 객체의 리스트를 반화하는 함수를 정의한다.
    ext = pathlib.Path(temp_filepath).suffix : 주어진 파일 경로에서 파일 확장자를 추출한다.
    loader = DocumentLoader.supported_extentions.get(ext) : 추출한 확장자에 해당하는 문서 로더 클래스를 찾는다.
    if not loader: 지원하지 않는 확장자일 경우 예외를 발생시킨다.
  • loader = loader(temp_filepath) : 찾은 로더 클래스의 인스턴스를 생성한다.
    docs = loader.load() : 해당 로더를 사용하여 문서를 로드한다.
    logging.info(docs) : 로드된 문서에 대한 정보를 로깅한다.
    return docs : 로드된 문서 객체의 리스트를 반환한다.

제대로 문서가 로드되는지 확인해 보자.

<출력결과>
INFO:root:[Document(page_content='DIABETES : \\nJyothi Vijayaraghavan; Judy S. Crabtree, PhD.  \\nDiabetes mellitus, or simply diabetes , ...   \\nhttp://new.dhh.louisiana.gov/index.cfm/page/1233  \\nNDIC, American Diabetes Association, CDC.  ', metadata={'source': 'E:\\\\Tuning_LLM\\\\DIABETES.pdf', 'page': 4})]
문서 로드 성공!
page_content='DIABETES : \\nJyothi Vijayaraghavan; Judy S. Crabtree, PhD.  ... nhttp://new.dhh.louisiana.gov/index.cfm/page/1233  \\nNDIC, American Diabetes Association, CDC.  ' metadata={'source': 'E:\\\\Tuning_LLM\\\\DIABETES.pdf', 'page': 4}