데보션앱 소개페이지 바로가기
로그인 선택

신고하기

CLOSE
신고사유 (대표 사유 1개)
상세내용 (선택)
0/200
  • 신고한 게시글은 더 이상 보이지 않습니다.
  • 이용약관과 운영정책에 따라 신고사유에 해당하는지 검토 후 조치됩니다.
  • 허위 신고인 경우, 신고자의 서비스 이용이 제한될 수 있으니 유의하시어 신중하게 신고해 주세요.
(이 회원이 작성한 모든 댓글과 커뮤니티 게시물이 보이지 않고, 알림도 오지 않습니다.)

미리보기

커뮤니티

      1,234

      badge 23.06.15

      글 등록

      카테고리를 선택해주세요.

      DEVOTEE를 활성화 시키면
      지금 작성한 커뮤니티 글에 대해 1개의 댓글을 달아줍니다.

      버튼을 누르면 글 수정 시 ChatGPT가 작성한 댓글이 수정됩니다.

      임시저장함에 저장되었습니다. 저장일시 : 2022.5.17 14:29:08

      임시저장함

      제목을 선택하시면 이어서 작성이 가능하며,
      최대 20건까지 저장합니다.
      컨텐츠 유형, 제목, 저장일시, 삭제로 이뤄진 임시저장 목록
      컨텐츠 유형 제목 저장일 삭제

      데보션 블로그 게재 요청

      CLOSE
      • *
      • *

      본인인증

      효율적인 데보션 서비스 이용 및
      고객님의 소중한 개인정보보호를 위해
      본인인증을 진행해주세요. 본인인증 미 진행 시 로그인이 제한됩니다.
      본인인증 실패

      본인인증 로그인에 실패하였습니다.
      회원이 아니시거나 본인인증 등록이
      완료되지 않은 사용자입니다.

      회원정보 연결

      LangChain LCEL과 RAGAS를 사용한 Native RAG 평가

      Injee 24.03.28
      4,475 10 3
      DEVOTEE 요약
      LangChain의 LCEL을 사용해 Native RAG를 구현하고, RAGAS 라이브러리로 평가를 진행한 내용입니다. 먼저, Azure LLM을 임포트하고 Embedding 초기화를 진행했으며, 웹 기반 로더를 통해 문서를 로딩하고 Vectorstore에 저장했습니다. 그 다음, LCEL을 사용해 RAG Chain을 구현하고, RAGAS를 사용해 문서와 생성된 응답을 평가했습니다. 이 과정을 통해 faithfulness, answer relevancy, context recall, context precision, answer correctness 등의 평가 지표를 얻을 수 있었습니다.
      DEVOTEE 추천 블로그

      LangChain LCEL을 사용해서 Native RAG를 구현하고 RAGAS library를 사용해 평가를 진행해보겠습니다.

      최근에 LangChain에 추가된 LCEL과 새로운 package 구조도 체험해보고, RAG 평가를 손쉽게 도와주는 RAGAS도 한번에 확인해보려고 합니다.

      코드 예제는 Nayak님의 Medium 글을 참고하면서, 최신 LangChain 버전에 맞게 코드를 일부 업데이트 하였습니다.


      Azure LLM 과 Embedding 초기화

      import os
      from langchain_openai import AzureChatOpenAI
      from langchain_openai import AzureOpenAIEmbeddings
      
      embeddings = AzureOpenAIEmbeddings(
          model="text-embedding-ada-002",
          openai_api_version="2024-02-15-preview",
          azure_endpoint=os.getenv("AZURE_ENDPOINT"),
          api_key=os.getenv("AZURE_OPENAI_KEY"),
      )
      
      llm = AzureChatOpenAI(
          model="gpt-4-32k",
          azure_endpoint = os.getenv("AZURE_ENDPOINT"),
          api_key=os.getenv("AZURE_OPENAI_KEY"),  
          api_version="2024-02-15-preview"
      )


      문서 로딩하고 Vectorstore에 저장하기

      from langchain_community.document_loaders import WebBaseLoader
      from langchain_text_splitters import RecursiveCharacterTextSplitter
      from langchain_community.vectorstores import Chroma
      
      loader = WebBaseLoader(
          "https://blog.langchain.dev/langchain-v0-1-0/"
      )
      documents = loader.load()
      
      text_splitter = RecursiveCharacterTextSplitter(
          chunk_size = 1250,
          chunk_overlap = 100,
          length_function = len,
          is_separator_regex = False
      )
      split_docs = text_splitter.split_documents(documents)
      vectorstore = Chroma.from_documents(
          documents=split_docs, 
          embedding=embeddings, 
          persist_directory="./Vectorstore/chromadb"
      )


      LCEL 사용해 RAG Chain 구현

      from operator import itemgetter
      
      from langchain import hub
      from langchain_core.runnables import RunnablePassthrough
      from langchain_core.output_parsers import StrOutputParser
      
      retriever = vectorstore.as_retriever()
      prompt = hub.pull("rlm/rag-prompt")
      
      def format_docs(args):
          docs = args["source_docs"]
          return "\n\n".join(doc.page_content for doc in docs)
      
      rag_chain = (
          RunnablePassthrough.assign(
              question=itemgetter("question")
          )
          | {
              "source_docs" : itemgetter("question") | retriever,
              "question": itemgetter("question"),
          }
          | {
              "source_docs": itemgetter("source_docs"), 
              "answer": {
                  "context": format_docs,
                  "question": itemgetter("question"),        
              } | prompt | llm | StrOutputParser()
          }
      )
      
      rag_chain.invoke({"question" : "What are the major changes in v 0.1.0?"})

      RAGAS 평가 시 참고한 문서도 필요하기 때문에, LangChain Retrieval LCEL 예제를 참고해

      생성된 응답("answer") 외에도 참고한 문서("source_docs")를 함께 return하도록 했습니다.

      {'source_docs': [Document(page_content='versioning policy for a little over a month now.langchain itself, however, still remained on 0.0.x versions. ... See more towards the end of this post on our plans for that.While re-architecting the', metadata={'language': 'en', 'source': 'https://blog.langchain.dev/langchain-v0-1-0/', 'title': 'LangChain v0.1.0'}),
        ... ],
       'answer': 'The major changes in v 0.1.0 include a new versioning standard where breaking changes to the public API result in a minor version bump and bug fixes or new features result in a patch version bump. Additionally, the v 0.1.0 release of langchain is the first stable version, fully backwards compatible, available in both Python and JavaScript with improved focus and documentation. Architectural changes were made such as separating langchain-core and partner packages from langchain and old, unused functionality was removed.'}


      RAGAS 사용해서 Synthetic Testset 만들기

      from ragas.testset.generator import TestsetGenerator
      from ragas.testset.evolutions import simple, reasoning, multi_context
      
      generator = TestsetGenerator.from_langchain(
          generator_llm=llm,
          critic_llm=llm,
          embeddings=embeddings
      )
      testset = generator.generate_with_langchain_docs(split_docs, test_size=10, distributions={simple: 0.5, reasoning: 0.25, multi_context: 0.25})
      
      test_df = testset.to_pandas()
      test_questions = test_df["question"].values.tolist()
      test_groundtruths = test_df["ground_truth"].values.tolist()
      test_df.head()

      image.png

      기본적으로 OpenAI를 사용하지만, from_langchain을 이용하면 위에서 설정한 Azure OpenAI API를 그대로 사용가능합니다.


      RAG Chain을 사용해 응답 생성

      from datasets import Dataset
      
      answers = []
      contexts = []
      
      for question in test_questions:
        response = rag_chain.invoke({"question": question})
        answers.append(response['answer'])
        contexts.append([context.page_content for context in response['source_docs']])
      
      response_dataset = Dataset.from_dict({
          "question" : test_questions,
          "answer" : answers,
          "contexts" : contexts,
          "ground_truth" : test_groundtruths
      })


      RAG 평가하기

      from ragas import evaluate
      from ragas.metrics import (
          faithfulness,
          answer_relevancy,
          answer_correctness,
          context_recall,
          context_precision,
      )
      
      metrics = [
          faithfulness,
          answer_relevancy,
          context_recall,
          context_precision,
          answer_correctness,
      ]
      
      naive_results = evaluate(response_dataset, metrics, raise_exceptions=False)

      평가 결과

      {
       'faithfulness': 1.0000, 
       'answer_relevancy': 0.9347, 
       'context_recall': 1.0000, 
       'context_precision': 0.8750, 
       'answer_correctness': 0.6409
      }

      이렇게 Native RAG 평가를 수행해 보았습니다.


      원본 예제에는 Native RAG 외에도 Reranker나 Contextual Compression Pipeline을 포함하는 Advanced RAG 예제도 있습니다.

      그 경우, Faithfulness와 context precision과 recall이 향상된 것을 확인할 수 있어 관심있는 분들은 참고하셔도 좋을 것 같습니다.

      댓글 0

      DEVOTEE를 활성화 시키면
      지금 작성한 댓글에 AI가 댓글을 달아줍니다.

      Injee 님의 최신 블로그

      더보기

      DEVOTEE 추천 블로그

      동영상 기고하기