RAGAS Context Precision
RAGAS Context Precision (컨텍스트 정밀도)
RAG 시스템에서 검색기(retriever)가 관련 청크를 얼마나 잘 상위에 올려주는지는 답변 품질을 좌우하는 핵심이에요. 관련 정보가 아래쪽에 묻혀 있으면 모델이 그걸 놓칠 확률이 커지죠. Ragas의 Context Precision 메트릭은 바로 이 '정렬 능력'을 수치화해 줘요. 검색된 컨텍스트에서 관련 청크를 무관한 청크보다 더 높은 순위에 두는 정도를 평가해요.
Context Precision이란
Context Precision은 주어진 질문(query)에 대해 검색기(retriever)가 관련 청크를 무관한 것보다 높은 순위로 배치하는 능력을 평가하는 메트릭이에요. 구체적으로는 검색된 컨텍스트에서 관련 청크가 순위의 상위에 놓여 있는 정도를 측정해요.
컨텍스트 안 각 청크의 precision@k 값을 평균 내어 계산해요. precision@k란 순위 k에서 관련 청크 수를 순위 k까지의 전체 청크 수로 나눈 값이에요.
[ \text{Context Precision@K} = \frac{\sum_{k=1}^{K} \left( \text{Precision@k} \times v_k \right)}{\text{Total number of relevant items in the top } K \text{ results}} ]
[ \text{Precision@k} = {\text{true positives@k} \over (\text{true positives@k} + \text{false positives@k})} ]
여기서 (K)는 retrieved_contexts에 있는 전체 청크 수이고, (v_k \in {0, 1})는 순위 (k)에서의 관련성 지표(relevance indicator)예요.
사용 예시
컬렉션 기반 API로 ContextPrecision 메트릭을 만들어 평가해 볼게요. 참조 답변(reference answer)이 있을 때, 각 컨텍스트를 참조 답변과 비교해 그 질문에 답하는 데 유용한지 판단해요.
from openai import AsyncOpenAI
from ragas.llms import llm_factory
from ragas.metrics.collections import ContextPrecision
# Setup LLM
client = AsyncOpenAI()
llm = llm_factory("gpt-4o-mini", client=client)
# Create metric
scorer = ContextPrecision(llm=llm)
# Evaluate
result = await scorer.ascore(
user_input="Where is the Eiffel Tower located?",
reference="The Eiffel Tower is located in Paris.",
retrieved_contexts=[
"The Eiffel Tower is located in Paris.",
"The Brandenburg Gate is located in Berlin."
]
)
print(f"Context Precision Score: {result.value}")
출력은 Context Precision Score: 0.9999999999처럼 나와요. 여기서 흥미로운 점은, 무관한 청크가 두 번째 위치에 있을 때는 점수가 그대로지만 그 무관한 청크가 첫 번째 위치에 오면 점수가 내려간다는 거예요. 순위가 점수에 직접 반영되기 때문이죠.
동기(synchronous) 코드를 선호한다면 ascore 대신 .score() 메서드를 쓰면 돼요.
Context Utilization
ContextUtilization 메트릭은 참조 답변 없이 '생성된 응답(response)'과 각 컨텍스트를 비교해 유용성을 평가해요. 참조 답변은 없지만 실제로 생성된 응답은 있을 때 사용해요. ContextPrecision과 비슷하지만 비교 대상이 참조 답변이 아니라 생성된 답변이라는 차이가 있어요.
from ragas.metrics.collections import ContextUtilization
scorer = ContextUtilization(llm=llm)
result = await scorer.ascore(
user_input="Where is the Eiffel Tower located?",
response="The Eiffel Tower is located in Paris.",
retrieved_contexts=[
"The Eiffel Tower is located in Paris.",
"The Brandenburg Gate is located in Berlin."
]
)
Legacy Metrics API
레거시 API도 존재해요. SingleTurnSample을 만들고 LLMContextPrecisionWithoutReference(참조 답변 없이 응답과 비교)나 LLMContextPrecisionWithReference(참조 답변과 비교)를 single_turn_ascore로 평가하는 방식이에요. 새 프로젝트라면 컬렉션 기반 API를 권장하고, 이 레거시 API는 버전 0.4에서 deprecated, 버전 1.0에서 제거될 예정이에요.
Non LLM 기반 Context Precision
LLM 없이도 가능해요. 예를 들어 NonLLMContextPrecisionWithReference는 retrieved_contexts와 reference_contexts를 모두 받아, 검색된 각 청크를 참조 컨텍스트의 모든 항목과 Levenshtein distance 같은 비(非)LLM 유사도로 비교해 관련성을 판단해요. 이 메트릭을 쓰려면 pip install rapidfuzz로 rapidfuzz 패키지가 필요해요.
ID 기반 Context Precision
IDBasedContextPrecision은 문서에 고유 ID 체계가 있을 때, 내용을 비교하는 대신 ID로 검색 성능을 측정하는 방식이에요. retrieved_context_ids와 reference_context_ids를 비교해 정밀도를 계산하고, 값은 0에서 1 사이예요. 문자열·정수 ID 모두 지원해요.
[ \text{ID-Based Context Precision} = \frac{\text{Number of retrieved context IDs found in reference context IDs}}{\text{Total number of retrieved context IDs}} ]
예를 들어 검색된 ID 4개(doc_1, doc_2, doc_3, doc_4) 중 참조 ID에 포함된 게 2개(doc_1, doc_4)라면 정밀도는 0.5(50%)가 돼요.