23.06.15
DEVOTEE를 활성화 시키면
지금 작성한 커뮤니티 글에 대해 1개의 댓글을 달아줍니다.
버튼을 누르면 글 수정 시 ChatGPT가 작성한 댓글이 수정됩니다.
| 컨텐츠 유형 | 제목 | 저장일 | 삭제 |
|---|
본인인증 로그인에 실패하였습니다.
회원이 아니시거나 본인인증 등록이
완료되지 않은 사용자입니다.
LangChain LCEL을 사용해서 Native RAG를 구현하고 RAGAS library를 사용해 평가를 진행해보겠습니다.
최근에 LangChain에 추가된 LCEL과 새로운 package 구조도 체험해보고, RAG 평가를 손쉽게 도와주는 RAGAS도 한번에 확인해보려고 합니다.
코드 예제는 Nayak님의 Medium 글을 참고하면서, 최신 LangChain 버전에 맞게 코드를 일부 업데이트 하였습니다.
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"
)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"
)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.'}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()기본적으로 OpenAI를 사용하지만, from_langchain을 이용하면 위에서 설정한 Azure OpenAI API를 그대로 사용가능합니다.
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
})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이 향상된 것을 확인할 수 있어 관심있는 분들은 참고하셔도 좋을 것 같습니다.
DEVOTEE를 활성화 시키면
지금 작성한 댓글에 AI가 댓글을 달아줍니다.