[랭체인] PDF 문서 기반 QA챗봇 구현steemCreated with Sketch.

in #kr-dev14 days ago (edited)

안녕하세요! 오늘은 LangChain과 OpenAI를 활용하여 PDF 문서에서 정보를 추출하고 질문에 답변하는 RAG(Retrieval-Augmented Generation) 시스템을 만드는 방법에 대해 알아보겠습니다. 이 시스템은 특히 대용량 문서에서 정보를 빠르게 찾아 답변하는 데 유용합니다.

1. 환경 설정

먼저, 필요한 라이브러리를 설치합니다:

!pip install -Uq pypdf langchain langchain_core langchain_openai langchain_chroma langchain-community langchainhub

그리고 OpenAI API 키를 환경 변수로 설정합니다:

import os
from google.colab import userdata
os.environ["OPENAI_API_KEY"] = userdata.get('OPENAI_API_KEY')

참고: 이 부분은 Google Colab에서 작업할 때 필요한 단계입니다. 로컬 환경에서는 API 키를 직접 설정해주세요.

2. PDF 문서 로드 및 처리

이제 PDF 문서를 로드하고 처리합니다:

from langchain.document_loaders import PyPDFLoader
from langchain.text_splitter import CharacterTextSplitter
from langchain_openai import OpenAIEmbeddings
from langchain_chroma import Chroma

# PDF 파일이 저장된 폴더 경로를 설정합니다.
folder_path = './pdfs/'  

# 텍스트를 저장할 리스트를 초기화합니다.
texts = []

# 텍스트를 분할할 때 사용할 CharacterTextSplitter 객체를 생성합니다.
text_splitter = CharacterTextSplitter(
    separator = "\n", # 텍스트를 분할할 때 사용할 구분자
    chunk_size = 1000, # 각 분할된 텍스트의 최대 길이
    chunk_overlap = 50) # 분할된 텍스트 간의 중첩 길이

# 지정된 폴더 내의 모든 파일을 순회합니다.
for filename in os.listdir(folder_path):
    # 파일이 PDF 형식인 경우에만 처리합니다.
    if filename.endswith(".pdf"): 
        # PDF 파일을 로드하여 raw_documents에 저장합니다.
        raw_documents = PyPDFLoader(folder_path + '/' + filename).load()
        # 로드된 문서를 분할하여 documents에 저장합니다.
        documents = text_splitter.split_documents(raw_documents)
        # 분할된 문서를 texts 리스트에 추가합니다.
        texts.extend(documents)

# 분할된 텍스트를 Embeddings로 변환하여 Chroma 데이터베이스에 저장합니다.
db = Chroma.from_documents(texts, OpenAIEmbeddings())

# 데이터베이스에서 검색을 수행할 수 있는 retriever 객체를 생성합니다.
# search_kwargs: 검색 시 사용할 추가 매개변수 (여기서는 상위 10개의 결과를 반환)
retriever = db.as_retriever(search_kwargs={"k": 10})

이 코드는 PDF 파일을 로드하고, 텍스트를 청크로 나누어 벡터 데이터베이스에 저장합니다.

3. RAG 체인 구성

다음으로, RAG 체인을 구성합니다:

from langchain_core.runnables import RunnablePassthrough
from langchain_core.prompts import ChatPromptTemplate
from langchain_openai import ChatOpenAI
from langchain_core.output_parsers import StrOutputParser

prompt_template = ChatPromptTemplate.from_template("당신은 질문 답변 작업의 어시스턴트입니다. 다음 문맥을 사용하여 질문에 답하세요. 답을 모른다면 모른다고 말하세요. 답변은 최대 세 문장으로 작성하고 메타데이터 정보를 포함하여 간결하게 작성하세요. 한국어로 작성합니다. \ns\n질문: {question} \n문맥: {context} \n답변:")

chain = (
    {"context": retriever, "question": RunnablePassthrough()}
    | prompt_template
    | ChatOpenAI()
    | StrOutputParser()
)

이 체인은 사용자의 질문을 받아 관련 문맥을 검색하고, 이를 바탕으로 답변을 생성합니다.

4. 대화형 인터페이스 구현

마지막으로, 간단한 대화형 인터페이스를 만듭니다:

def chat_with_user(user_message):
    ai_message = chain.invoke(user_message)
    return ai_message

while True:
    user_message = input("USER > ")
    if user_message.lower() == "quit":
        break
    ai_message = chat_with_user(user_message)
    print(f" A I > {ai_message}")

이제 사용자는 질문을 입력하고 시스템은 PDF 문서에서 관련 정보를 찾아 답변을 제공합니다.

결론

이 RAG 시스템은 대량의 문서에서 정보를 효율적으로 추출하고 질문에 답변할 수 있습니다. 기업 문서, 매뉴얼, 학술 논문 등 다양한 분야에서 활용될 수 있으며, 사용자의 정보 접근성을 크게 향상시킬 수 있습니다.

더 나아가 이 시스템을 개선하려면, 다양한 형식의 문서 지원, 다국어 지원, 사용자 인터페이스 개선 등을 고려해볼 수 있겠네요. 여러분도 이 예제를 바탕으로 자신만의 RAG 시스템을 만들어보는 것은 어떨까요?

PDF 문서를 스마트하게 활용하는 이 방법이 여러분의 업무나 학습에 도움이 되길 바랍니다. 질문이나 의견이 있으시면 언제든 댓글로 남겨주세요!

#LangChain

Posted using Obsidian Steemit plugin

Sort:  

[광고] STEEM 개발자 커뮤니티에 참여 하시면, 다양한 혜택을 받을 수 있습니다.

Congratulations, your post has been upvoted by @upex with a 0.22% upvote. We invite you to continue producing quality content and join our Discord community here. Visit https://botsteem.com to utilize usefull and productive automations #bottosteem #upex

조만간 챗GPT를 유료결재를 해제하고, 구글 코랩을 유료결재 해서 한번 따라 해봐야겠습니다. 좋은 정보 감사합니다.

저는 구글 코랩을 무료로 사용하고 있습니다. 구글은 아직 유료 결제를 할 필요성을 느끼지 못하고 있어요. ㅎㅎ
그리고 챗GPT 플러스는 지난달까지 유료로 사용하다가, 지금은 필요한 AI API를 직접 연동해서 사용하고 있습니다.
개발할 때는 cloud-3.5-sonnet를 자주 사용하고 있어요.

Coin Marketplace

STEEM 0.20
TRX 0.13
JST 0.029
BTC 67095.54
ETH 3462.62
USDT 1.00
SBD 2.71