Mistral AI와 Phoenix로 RAG 관측 가능성(Observability)과 평가하기
Mistral AI와 Phoenix로 RAG 관측 가능성(Observability)과 평가하기
Phoenix Evals로 RAG 파이프라인을 평가하는 방법을 배우는 문서예요. LlamaIndex로 RAG를 구축하고, Phoenix Tracing으로 데이터를 캡처한 뒤, 문서 관련성(relevance)·Q&A 정확도·환각(hallucination) 평가를 수행해요.
출처: 문서
본문
이 튜토리얼에서는 RAG 파이프라인을 구축하고 Phoenix Evals로 평가하는 방법을 살펴볼 거예요. 다음 섹션으로 구성돼 있어요:
- Retrieval Augmented Generation (RAG) 이해하기
- (LlamaIndex 같은 프레임워크로) RAG 구축하기
- Phoenix Evals로 RAG 평가하기
LLM은 방대한 데이터셋으로 학습되지만, 여기에는 여러분의 특정 데이터(회사 지식 베이스나 문서 같은 것)는 포함되지 않아요. RAG(Retrieval-Augmented Generation)는 생성 과정에서 여러분의 데이터를 동적으로 컨텍스트로 통합해 이 문제를 해결해요. 이는 LLM의 학습 데이터를 바꾸는 것이 아니라, 모델이 실시간으로 데이터에 접근·활용해 더 맞춤화되고 맥락에 맞는 응답을 제공하게 하는 거예요.
RAG에서 여러분의 데이터는 로드되어 쿼리용으로 준비돼요. 이 과정을 **인덱싱(indexing)**이라고 해요. 사용자 쿼리는 이 인덱스에 작용해 데이터를 가장 관련성 높은 컨텍스트로 필터링해요. 이 컨텍스트와 쿼리는 프롬프트와 함께 LLM으로 보내지고, LLM이 응답을 제공해요.
RAG는 챗봇이나 에이전트 같은 애플리케이션을 만들 때 중요한 구성 요소이므로, 데이터를 애플리케이션에 가져오는 RAG 기법을 아는 것이 필요해요.
RAG 시스템 구축 (Build a RAG system)
RAG의 단계를 이해했으니 파이프라인을 만들어 볼게요. LlamaIndex를 RAG에, Phoenix Evals를 평가에 사용할 거예요.
!pip install -qq arize-phoenix gcsfs nest_asyncio openinference-instrumentation-llama_index
!pip install -q llama-index-embeddings-mistralai
!pip install -q llama-index-llms-mistralai
!pip install -qq "mistralai>=1.0.0"
import os
from getpass import getpass
from typing import Any, Dict
import pandas as pd
import phoenix as px
from phoenix.otel import register
from mistralai.client import Mistral
from openinference.instrumentation.llama_index import LlamaIndexInstrumentor
import nest_asyncio
nest_asyncio.apply()
import pandas as pd
from llama_index.core import SimpleDirectoryReader, VectorStoreIndex
from llama_index.core.node_parser import SimpleNodeParser
from llama_index.llms.mistralai import MistralAI
from llama_index.embeddings.mistralai import MistralAIEmbedding
pd.set_option("display.max_colwidth", None)
이 튜토리얼에서는 합성 데이터 생성과 평가에 모두 Mistral을 사용할 거예요.
if not (api_key := os.getenv("MISTRAL_API_KEY")):
api_key = getpass("🔑 Enter your Mistral AI API key: ")
os.environ["MISTRAL_API_KEY"] = api_key
client = Mistral(api_key=api_key)
이 튜토리얼에서는 Phoenix Tracing으로 RAG 파이프라인을 평가하는 데 필요한 모든 데이터를 캡처할 거예요. 이를 활성화하려면 phoenix 애플리케이션을 시작하고 LlamaIndex를 계측(instrument)하기만 하면 돼요.
session =px.launch_app()
LlamaIndexInstrumentor로 Phoenix 트레이싱을 활성화해요. Phoenix는 OpenInference 트레이스(LLM 애플리케이션 트레이스를 캡처·저장하는 오픈소스 표준으로, Phoenix 같은 LLM 관측 가능성 솔루션과 원활하게 통합되게 해줌)를 사용해요.
tracer_provider = register()
LlamaIndexInstrumentor().instrument(skip_dep_check=True, tracer_provider=tracer_provider)
RAG 파이프라인을 만들려고 Paul Graham의 에세이를 사용할 거예요.
import tempfile
from urllib.request import urlretrieve
with tempfile.NamedTemporaryFile() as tf:
urlretrieve(
"https://raw.githubusercontent.com/Arize-ai/phoenix-assets/main/data/paul_graham/paul_graham_essay.txt",
tf.name,
)
documents = SimpleDirectoryReader(input_files=[tf.name]).load_data()
데이터 로드와 인덱스 구축 (Load Data and Build an Index)
from llama_index.core import Settings
# Define an LLM
llm = MistralAI()
embed_model = MistralAIEmbedding()
Settings.llm = llm
Settings.embed_model = embed_model
# Build index with a chunk_size of 512
node_parser = SimpleNodeParser.from_defaults(chunk_size=512)
nodes = node_parser.get_nodes_from_documents(documents)
vector_index = VectorStoreIndex(nodes)
QueryEngine을 만들고 질의하기 시작해요.
query_engine = vector_index.as_query_engine()
response_vector = query_engine.query("What did the author do growing up?")
쿼리에서 받는 응답을 확인해요.
response_vector.response
Phoenix Tracing을 사용해 RAG 파이프라인을 평가하는 데 필요한 모든 데이터를 캡처하고 있다는 점을 기억하세요. 트레이스는 phoenix 애플리케이션에서 볼 수 있어요.
print("phoenix URL", session.url)
응답 평가 (Response Evaluation)
RAG 파이프라인을 구축하고 Phoenix Tracing으로 계측했어요. 이제 성능을 평가해야 해요. Phoenix의 LLM Evals로 RAG 시스템/쿼리 엔진을 평가할 수 있어요. 이러한 도구를 활용해 검색 증강 생성 시스템의 품질을 정량화하는 방법을 살펴볼게요.
RAG 시스템 평가에는 올바른 컨텍스트를 가져오고 그다음 적절한 응답을 생성할 수 있는 쿼리가 필수적이에요. 이 튜토리얼에서는 파이프라인용 질문을 수동으로 생성해 볼게요.
questions_list = [
"What did the author do growing up?",
"What was the author's major?",
"What was the author's minor?",
"What was the author's favorite class?",
"What was the author's least favorite class?",
]
for question in questions_list:
response_vector = query_engine.query(question)
쿼리를 실행했으니, RAG 시스템이 올바른 컨텍스트를 검색할 수 있었는지 검증하기 시작할 수 있어요. phoenix에 로그된 트레이스에서 모든 검색 문서를 추출해요. (phoenix 런타임에서 트레이스 데이터를 내보내는 방법에 대한 자세한 설명은 문서를 참고하세요.)
from phoenix.session.evaluation import get_retrieved_documents
retrieved_documents_df = get_retrieved_documents(px.Client())
retrieved_documents_df
이제 Phoenix의 LLM Evals로 쿼리에 대한 검색 문서의 관련성을 평가해요. 설명(explanation)을 켜서 LLM이 추론을 설명하게 했어요. 이는 디버깅과 잠재적 교정 조치를 찾는 데 유용해요.
from phoenix.evals import (
MistralAIModel,
RelevanceEvaluator,
run_evals,
)
relevance_evaluator = RelevanceEvaluator(MistralAIModel)
retrieved_documents_relevance_df = run_evals(
evaluators=[relevance_evaluator],
dataframe=retrieved_documents_df,
provide_explanation=True,
concurrency=20,
)[0]
retrieved_documents_relevance_df.head()
이제 문서와 관련성 평가를 결합해 검색 지표를 계산할 수 있어요. 이 지표들은 RAG 시스템이 얼마나 잘 수행하고 있는지 이해하게 해줘요.
documents_with_relevance_df = pd.concat(
[retrieved_documents_df, retrieved_documents_relevance_df.add_prefix("eval_")], axis=1
)
documents_with_relevance_df
검색 평가는 우리 RAG 시스템이 완벽하지 않다는 걸 보여줘요. 하지만 컨텍스트가 틀려도 LLM이 올바른 응답을 생성할 수는 있어요. LLM이 생성한 응답을 평가해 볼게요.
from phoenix.session.evaluation import get_qa_with_reference
qa_with_reference_df = get_qa_with_reference(px.Client())
qa_with_reference_df
이제 질문, 컨텍스트, 응답(input, reference, output)의 데이터셋이 있으니 LLM이 쿼리에 얼마나 잘 응답하는지 측정할 수 있어요. QA 정확도 평가에 대한 자세한 내용은 LLM Evals 문서를 참고하세요.
from phoenix.evals import (
HallucinationEvaluator,
MistralAIModel,
QAEvaluator,
run_evals,
)
qa_evaluator = QAEvaluator(MistralAIModel())
hallucination_evaluator = HallucinationEvaluator(MistralAIModel())
qa_correctness_eval_df, hallucination_eval_df = run_evals(
evaluators=[qa_evaluator, hallucination_evaluator],
dataframe=qa_with_reference_df,
provide_explanation=True,
concurrency=20,
)
qa_correctness_eval_df.head()
hallucination_eval_df.head()
RAG 시스템의 QA 성능과 환각 성능을 평가했으니, 이 평가들을 Phoenix로 보내 시각화할 수 있어요.
from phoenix.trace import SpanEvaluations, DocumentEvaluations
px.Client().log_evaluations(
SpanEvaluations(dataframe=qa_correctness_eval_df, eval_name="Q&A Correctness"),
SpanEvaluations(dataframe=hallucination_eval_df, eval_name="Hallucination"),
DocumentEvaluations(dataframe=retrieved_documents_relevance_df, eval_name="relevance"),
)
이제 모든 평가를 Phoenix로 보냈어요. Phoenix 애플리케이션으로 가서 결과를 확인해 볼게요! 모든 평가를 Phoenix로 보냈으니, 결과를 함께 분석해 열악한 검색이나 관련 없는 컨텍스트가 LLM이 올바른 응답을 생성하는 능력에 영향을 주는지 판단할 수 있어요.
결론 (Conclusion)
LlamaIndex와 Phoenix를 사용해 RAG 파이프라인을 구축하고 평가하는 방법을 살펴봤고, 특히 파이프라인 내 검색 시스템과 생성 응답 평가에 초점을 맞췄어요. Phoenix는 LLM 애플리케이션 성능을 평가하는 데 사용할 수 있는 다양한 다른 평가도 제공해요. 자세한 내용은 LLM Evals 문서를 참고하세요.