Today
-
Yesterday
-
Total
-
  • chatGPT가 거짓말 못하게 하는 방법, RAG에 대해 알아보기
    Python/자연어처리 2025. 7. 24. 11:36
    반응형

     

    chatGPT가 거짓말 못하게 하는 방법, RAG에 대해 알아보기


    검색 증강 생성이라고도 불리는 RAG(Retrieval-Augmented Generation)라는 기술이 있습니다. 이 기술은 대규모 언어 모델(LLM)을 사용할 때, 신뢰할 수 있는 외부 데이터를 참조해서 답변할 수 있도록 출력을 최적화하는 기술이예요. 간단하게 설명하자면, chatGPT 등의 챗봇이 거짓말을 하는 환각 현상을 효과적으로 해결할 수 있는 기술이지요. 이번에는 chatGPT와 같은 모델을 이용하기 위해 OpenAI API를 활용해서 내가 원하는 문서를 참조해 답변할 수 있는 나만의 챗봇을 만들어 보도록 하겠습니다.

     

     

    기술스택 알아보기


    이번 실습에서는 API 활용 및 RAG를 구현할건데요, 이를 위해서 🦜️🔗랭체인(Langchain) 이라는 패키지를 활용할겁니다. 랭체인은 LLM 관련 코드를 추상화해놓아서 손쉽게 관련 기술을 구현할 수 있기 때문에 추천드려요. RAG를 구현할 기술은 Faiss(Facebook AI Similarity Search)를 활용할겁니다.

     

     

    구성요소 알아보기


    챗봇 모델은 OpenAI GPT-3.5 turbo를 활용할겁니다. OpenAI API를 이용해서 해당 모델을 불러올건데요, 만약 API 키를 발급받지 않았다면 OpenAI Platform에서 API 키를 발급받아 주시면 됩니다. 만약 GPT-3.5 turbo 말고 다른 모델을 원한다면 아래 코드에서 모델 이름만 바꿔 적어 주시면 됩니다.

     

    RAG에 사용할 참조 문서는 mdn web docs에서 제공하는 HTML 기본 한국어 문서입니다. 이 문서의 텍스트를 복사해서 html_basics.txt 파일로 저장했는데요, 만약 다른 문서를 참조하도록 만들고 싶다면 다른 txt 파일을 입력하면 됩니다.

     

     

    샘플 코드


    이제 아래 코드를 실행해서 RAG 기능을 탑재한 챗봇을 구현해 봅시다.

     

     

    # Import package
    from langchain.embeddings import OpenAIEmbeddings
    from langchain.vectorstores import FAISS
    from langchain.text_splitter import CharacterTextSplitter
    from langchain.chat_models import ChatOpenAI
    from langchain.chains import RetrievalQA
    from langchain.document_loaders import TextLoader
    import os
    
    # API 키 입력
    os.environ["OPENAI_API_KEY"] = "sk-..."
    
    # 참조문서 불러오기
    loader = TextLoader("html_basics.txt", encoding='utf8')
    documents = loader.load()
    
    # 문서 나누기
    text_splitter = CharacterTextSplitter(chunk_size=500, chunk_overlap=100)
    docs = text_splitter.split_documents(documents)
    
    embeddings = OpenAIEmbeddings()
    vectorstore = FAISS.from_documents(docs, embeddings)
    
    # 챗봇 모델 정의
    retriever = vectorstore.as_retriever()
    qa_chain = RetrievalQA.from_chain_type(
        llm = ChatOpenAI(model="gpt-3.5-turbo", temperature=0.2),
        retriever=retriever,
        return_source_documents=True
    )
    Created a chunk of size 1217, which is longer than the specified 500

     

     

    위 코드에는 html_basics.txt 파일을 불러온 뒤, 적당한 크기의 문서 조각으로 나눈 다음 GPT-3.5 turbo LLM 모델에 입력하는 일련의 작업이 작성되어 있습니다. 이 코드를 활용할 때 신경써야 할 부분은 몇 가지 없으니 아래에 제시된 정도만 확인해 주세요.

     

    • TextLoader() 클래스에서는 encoding 매개변수만 신경써 주시면 됩니다. 한국어 문서의 경우, UTF-8 인코딩이 아니라 cp949 규격이 활용된 문서도 적잖이 있거든요.
    • CharacterTextSplitter() 클래스에서는 chunk_size와, chunk_overlap 매개변수를 목적에 따라 조절할 수 있습니다.
      • chunk_size: 클수록 입력된 문서의 문맥이 자연스럽지만, 토큰 소모가 많아지고 세밀한 검색을 할 수 없어요. LLM 모델에는 입력 제한이 있으니 적당히 작은 값으로 설정하는걸 권장드려요.
      • chunk_overlap: chunk 사이의 겹치는 정도를 정의합니다. 크면 조금 더 자연스러운 검색이 가능하지만 중복 처리하는 데이터가 늘어나기 때문에 너무 크면 비효율적인 동작을 할 가능성이 있습니다.
    • ChatOpenAI() 클래스는 model과 temperature 매개변수를 정의할 수 있어요. model은 이용할 모델을 문자열로 적어주면 되고, temperature는 창의성을 1 이하의 실수로 정의해요. 높을수록 창의적이지만 환각현상의 발생 위험이 커져요.

     

     

    # 챗봇 이용
    query = "html의 요소는 뭐가 있어?"
    result = qa_chain({"query": query})
    
    print("챗봇의 답변 💬:\n", result["result"])
    print("참조한 문서 조각 개수 📄:", len(result["source_documents"]))
    챗봇의 답변 💬:
     HTML의 요소는 여는 태그(Opening tag), 닫는 태그(Closing tag), 그리고 콘텐츠(Content)로 이루어져 있습니다. 요소는 속성도 가질 수 있습니다. 요소의 예시로는 이미지 요소(<img>), 제목 요소(<h1> - <h6>), 문단 요소(<p>) 등이 있습니다.
    참조한 문서 조각 개수 📄: 4

     

     

    위 코드를 이용하면 손쉽게 나만의 챗봇을 만들 수 있습니다. 단순 문서 검색용으로 활용할 수도 있고, FAQ 문서를 통째로 입력해서 FAQ 챗봇으로 활용할 수도 있지요. 적당한 수준의 프롬프트 엔지니어링을 함께 활용하면 더욱 자연스러운 답변도 기대할 수 있답니다.

    반응형

    댓글

문의: jwkang3929@naver.com