Nvidia 지표(Nvidia Metrics)
Nvidia 지표(Nvidia Metrics)
NVIDIA에서 영감을 받은 지표들로, "LLM-as-a-Judge" 방식으로 답변 정확도·컨텍스트 관련성·응답 근거성(groundedness)을 평가해요. 두 번의 독립적인 LLM 판단을 평균 내는 이중 평가 구조로 견고함을 높였다는 특징이 있어요. 각 지표는 0/2/4 같은 작은 단위 점수를 [0,1] 척도로 환산해요.
출처: 문서
본문
답변 정확도(Answer Accuracy)
Answer Accuracy는 주어진 질문에 대한 모델의 응답과 reference(ground truth) 사이의 일치를 측정해요. 각각 0, 2, 4 중 하나의 등급을 반환하는 두 개의 서로 다른 "LLM-as-a-Judge" 프롬프트로 수행돼요. 이 지표는 이 등급들을 [0,1] 척도로 변환한 뒤 두 판정 점수의 평균을 내요. 점수가 높을수록 모델의 답변이 reference와 밀접하게 일치한다는 뜻이에요.
- 0 →
response가 부정확하거나reference와 같은 질문을 다루지 않아요. - 2 →
response가reference와 부분적으로 일치해요. - 4 →
response가reference와 정확히 일치해요.
예시(Example)
from openai import AsyncOpenAI
from ragas.llms import llm_factory
from ragas.metrics.collections import AnswerAccuracy
# Setup LLM
client = AsyncOpenAI()
llm = llm_factory("gpt-4o-mini", client=client)
# Create metric
scorer = AnswerAccuracy(llm=llm)
# Evaluate
result = await scorer.ascore(
user_input="When was Einstein born?",
response="Albert Einstein was born in 1879.",
reference="Albert Einstein was born in 1879."
)
print(f"Answer Accuracy Score: {result.value}")
출력(Output):
Answer Accuracy Score: 1.0
동기 사용법(Synchronous Usage) 동기 코드를 선호한다면
.ascore()대신.score()메서드를 쓸 수 있어요:result = scorer.score( user_input="When was Einstein born?", response="Albert Einstein was born in 1879.", reference="Albert Einstein was born in 1879." )
계산 방법(How It's Calculated)
Step 1: LLM이 견고성을 보장하기 위해 두 개의 서로 다른 템플릿으로 등급을 생성해요:
- Template 1: LLM이
response를reference와 비교해 0, 2, 4 척도로 등급을 매겨요. - Template 2: LLM이 같은 질문을 다시 평가하되, 이번에는
response와reference의 역할이 바뀌어요.
이 이중 관점 접근은 답변 정확도의 공정한 평가를 보장해요.
Step 2: 두 등급 모두 유효하면 최종 점수는 score1과 score2의 평균이고, 그렇지 않으면 유효한 쪽을 사용해요.
계산 예시:
- User Input: "When was Einstein born?"
- Response: "Albert Einstein was born in 1879."
- Reference: "Albert Einstein was born in 1879." 양쪽 템플릿 모두 4(정확 일치) 등급을 반환한다고 가정하면 변환은 다음과 같아요:
- 등급 4는 [0,1] 척도에서 1에 해당해요.
- 두 점수의 평균: (1 + 1) / 2 = 1.
따라서 최종 Answer Accuracy 점수는 1이에요.
유사한 Ragas 지표(Similar Ragas Metrics)
-
답변 정확성(Answer Correctness): 생성된 답변의 정확도를 정답과 비교해 의미적·사실적 유사성을 모두 고려해 측정해요.
-
루브릭 점수(Rubric Score): 루브릭 기반 기준 채점 지표로, 각 루브릭이 구체적인 채점 기준을 제시하는 사용자 정의 루브릭에 따른 평가를 허용해요. LLM이 이 커스터마이즈된 설명에 따라 응답을 평가해 일관되고 객관적인 평가 과정을 보장해요.
지표 비교(Comparison of Metrics)
Answer Correctness vs. Answer Accuracy
- LLM 호출: Answer Correctness는 세 번의 LLM 호출이 필요해요(두 번은 response와 reference를 독립 문장으로 분해, 한 번은 분류). 반면 Answer Accuracy는 두 번의 독립적인 LLM 판단을 사용해요.
- 토큰 사용량: Answer Correctness는 상세한 분해와 분류 과정 때문에 훨씬 많은 토큰을 소모해요.
- 설명 가능성: Answer Correctness는 사실 정확성과 의미 유사성에 대한 상세한 통찰을 제공해 설명 가능성이 높은 반면, Answer Accuracy는 단순한 원시 점수를 제공해요.
- 견고한 평가: Answer Accuracy는 이중 LLM 평가로 일관성을 보장하고, Answer Correctness는 응답의 품질을 깊게 평가해 총체적인 관점을 제공해요.
Answer Accuracy vs. Rubric Score
- LLM 호출: Answer Accuracy는 두 번(LLM 판정마다 한 번) 호출하는 반면, Rubric Score는 한 번만 필요해요.
- 토큰 사용량: Answer Accuracy는 점수만 출력하므로 최소인 반면, Rubric Score는 추론을 생성해 토큰 소모가 늘어요.
- 설명 가능성: Answer Accuracy는 정당화 없이 원시 점수를 제공하고, Rubric Score는 판정과 함께 추론을 제공해요.
- 효율성: Answer Accuracy는 가볍고 더 작은 모델에서도 매우 잘 동작해요.
레거시 지표 API(Legacy Metrics API)
다음 예시는 레거시 지표 API 패턴을 사용해요. 새 프로젝트에는 위에서 보여준 컬렉션 기반 API를 권장해요.
폐지 일정(Deprecation Timeline) 이 API는 버전 0.4에서 폐지되고 버전 1.0에서 제거될 예정이에요. 위에 보여준 컬렉션 기반 API로 마이그레이션해주세요.
SingleTurnSample과 함께하는 예시(Example with SingleTurnSample)
from ragas.dataset_schema import SingleTurnSample
from ragas.metrics import AnswerAccuracy
sample = SingleTurnSample(
user_input="When was Einstein born?",
response="Albert Einstein was born in 1879.",
reference="Albert Einstein was born in 1879."
)
scorer = AnswerAccuracy(llm=evaluator_llm) # evaluator_llm wrapped with ragas LLM Wrapper
score = await scorer.single_turn_ascore(sample)
print(score)
출력(Output):
1.0
컨텍스트 관련성(Context Relevance)
Context Relevance는 retrieved_contexts(청크 또는 구절)가 user_input에 적절한지 평가해요. 각각 0, 1, 2 척도로 관련성을 매기는 두 번의 독립적인 "LLM-as-a-Judge" 프롬프트 호출로 수행돼요. 그런 다음 등급을 [0,1] 척도로 변환해 평균을 내 최종 점수를 만들어요. 점수가 높을수록 컨텍스트가 사용자 쿼리와 더 밀접하게 정렬된다는 뜻이에요.
- 0 → 검색된 컨텍스트가 사용자 쿼리와 전혀 관련이 없어요.
- 1 → 컨텍스트가 부분적으로 관련돼요.
- 2 → 컨텍스트가 완전히 관련돼요.
예시(Example)
from openai import AsyncOpenAI
from ragas.llms import llm_factory
from ragas.metrics.collections import ContextRelevance
# Setup LLM
client = AsyncOpenAI()
llm = llm_factory("gpt-4o-mini", client=client)
# Create metric
scorer = ContextRelevance(llm=llm)
# Evaluate
result = await scorer.ascore(
user_input="When and Where Albert Einstein was born?",
retrieved_contexts=[
"Albert Einstein was born March 14, 1879.",
"Albert Einstein was born at Ulm, in Württemberg, Germany.",
]
)
print(f"Context Relevance Score: {result.value}")
출력(Output):
Context Relevance Score: 1.0
동기 사용법(Synchronous Usage) 동기 코드를 선호한다면
.ascore()대신.score()메서드를 쓸 수 있어요:result = scorer.score( user_input="When and Where Albert Einstein was born?", retrieved_contexts=[...] )
구현 참고(Implementation Note)
원 논문과의 차이: 원래 Ragas 논문은 문장 수준 추출(CR = 관련 문장 수 / 전체 문장 수)로 Context Relevance를 정의하지만, 현재 구현은 더 견고한 이산 판단 접근을 사용해요. 각 LLM은 전체 컨텍스트 관련성을 0-2 척도로 평가하도록 요청받는데, 이는 더 효율적이고 문장 경계 오류에 덜 민감해요. 이는 핵심 평가 목표를 유지하면서 신뢰성을 높이고 계산 오버헤드를 줄이려는 의도적인 설계 결정이었어요.
계산 방법(How It's Calculated)
Step 1: LLM이 두 개의 서로 다른 템플릿(template_relevance1, template_relevance2)으로 프롬프트되어 사용자 쿼리에 관한 검색 컨텍스트의 관련성을 평가해요. 각 프롬프트는 0, 1, 2의 관련성 등급을 반환해요. 두 독립 평가를 사용하면 견고함을 제공하고 개별 LLM 편향을 완화하는 데 도움을 줘요.
Step 2: 각 등급을 2로 나눠 [0,1] 척도로 정규화해요. 두 등급 모두 유효하면 최종 점수는 정규화된 값들의 평균이고, 하나만 유효하면 그 점수를 사용해요.
계산 예시:
- User Input: "When and Where Albert Einstein was born?"
- Retrieved Contexts:
- "Albert Einstein was born March 14, 1879."
- "Albert Einstein was born at Ulm, in Württemberg, Germany." 이 예시에서 두 검색 컨텍스트가 함께 사용자의 쿼리를 완전히 다루는데, Albert Einstein의 출생일과 출생지를 모두 제공하기 때문이에요. 따라서 두 프롬프트 모두 결합 컨텍스트를 2(완전 관련)로 매겨요. 각 점수를 정규화하면 1.0(2/2)이 되고, 두 결과의 평균은 최종 Context Relevance 점수를 1로 유지해요.
유사한 Ragas 지표(Similar Ragas Metrics)
-
컨텍스트 정밀도(Context Precision): 사용자 쿼리 답변에 관련된 검색 컨텍스트의 비율을 측정해요. 모든 검색 청크에 걸친 mean precision@k로 계산되며, 검색 시스템이 관련 정보를 얼마나 정확하게 순위화하는지 나타내요.
-
컨텍스트 재현율(Context Recall): 관련 정보가 성공적으로 검색된 정도를 정량화해요. 검색 결과에서 찾은 관련 claim(또는 컨텍스트) 수를 reference의 전체 관련 claim 수로 나눈 비율로 계산되며, 중요한 정보를 놓치지 않도록 해요.
-
루브릭 점수(Rubric Score): 루브릭 기반 기준 채점 지표는 커스터마이즈 가능한 채점 기준의 사용자 정의 루브릭에 따라 응답을 평가해 일관되고 객관적인 평가를 보장해요. 채점 척도는 사용자 필요에 맞춰 유연해요.
Context Precision·Context Recall vs. Context Relevance
- LLM 호출: Context Precision과 Context Recall은 각각 하나의 LLM 호출이 필요해요. 하나는 컨텍스트 유용성을 검증해 reference를 얻고(판정 "1" 또는 "0"), 다른 하나는 각 답변 문장을 귀속 가능성(이진 'Yes'(1) 또는 'No'(0))으로 분류해요. 반면 Context Relevance는 견고성을 높이기 위해 두 번의 LLM 호출을 사용해요.
- 토큰 사용량: Context Precision과 Context Recall은 훨씬 많은 토큰을 소모하는 반면, Context Relevance는 더 토큰 효율적이에요.
- 설명 가능성: Context Precision과 Context Recall은 상세한 추론으로 높은 설명 가능성을 제공하고, Context Relevance는 설명 없이 원시 점수를 제공해요.
- 견고한 평가: Context Relevance는 Context Precision과 Context Recall의 단일 호출 접근에 비해 이중 LLM 판단으로 더 견고한 평가를 제공해요.
레거시 지표 API(Legacy Metrics API)
다음 예시는 레거시 지표 API 패턴을 사용해요. 새 프로젝트에는 위에서 보여준 컬렉션 기반 API를 권장해요.
폐지 일정(Deprecation Timeline) 이 API는 버전 0.4에서 폐지되고 버전 1.0에서 제거될 예정이에요. 위에 보여준 컬렉션 기반 API로 마이그레이션해주세요.
SingleTurnSample과 함께하는 예시(Example with SingleTurnSample)
from ragas.dataset_schema import SingleTurnSample
from ragas.metrics import ContextRelevance
sample = SingleTurnSample(
user_input="When and Where Albert Einstein was born?",
retrieved_contexts=[
"Albert Einstein was born March 14, 1879.",
"Albert Einstein was born at Ulm, in Württemberg, Germany.",
]
)
scorer = ContextRelevance(llm=evaluator_llm)
score = await scorer.single_turn_ascore(sample)
print(score)
출력(Output):
1.0
응답 근거성(Response Groundedness)
Response Groundedness는 응답이 검색된 컨텍스트에 얼마나 잘 뒷받침되거나 "근거화"되는지 측정해요. 응답의 각 claim이 제공된 컨텍스트에서 전체 또는 부분적으로 찾을 수 있는지 평가해요.
- 0 → 응답이 컨텍스트에 전혀 근거하지 않아요.
- 1 → 응답이 부분적으로 근거돼요.
- 2 → 응답이 완전히 근거돼요(모든 문장이 검색 컨텍스트에서 찾거나 추론할 수 있어요).
예시(Example)
from openai import AsyncOpenAI
from ragas.llms import llm_factory
from ragas.metrics.collections import ResponseGroundedness
# Setup LLM
client = AsyncOpenAI()
llm = llm_factory("gpt-4o-mini", client=client)
# Create metric
scorer = ResponseGroundedness(llm=llm)
# Evaluate
result = await scorer.ascore(
response="Albert Einstein was born in 1879.",
retrieved_contexts=[
"Albert Einstein was born March 14, 1879.",
"Albert Einstein was born at Ulm, in Württemberg, Germany.",
]
)
print(f"Response Groundedness Score: {result.value}")
출력(Output):
Response Groundedness Score: 1.0
동기 사용법(Synchronous Usage) 동기 코드를 선호한다면
.ascore()대신.score()메서드를 쓸 수 있어요:result = scorer.score( response="Albert Einstein was born in 1879.", retrieved_contexts=[...] )
계산 방법(How It's Calculated)
Step 1: LLM이 검색된 컨텍스트에 대한 응답의 근거성을 평가하도록 두 개의 서로 다른 템플릿으로 프롬프트돼요. 각 프롬프트는 0, 1, 2의 근거성 등급을 반환해요. Step 2: 각 등급을 2로 나눠 [0,1] 척도로 정규화해요(즉 0은 0.0, 1은 0.5, 2는 1.0). 두 등급 모두 유효하면 최종 점수는 정규화된 값들의 평균이고, 하나만 유효하면 그 점수를 사용해요.
계산 예시:
- Response: "Albert Einstein was born in 1879."
- Retrieved Contexts:
- "Albert Einstein was born March 14, 1879."
- "Albert Einstein was born at Ulm, in Württemberg, Germany." 이 예시에서 검색된 컨텍스트는 Albert Einstein의 출생일과 출생지를 모두 제공해요. 응답의 claim이 컨텍스트에 의해 뒷받침되므로(날짜가 부분적으로 제공되더라도), 두 프롬프트 모두 근거성을 2(완전 근거)로 매길 가능성이 높아요. 점수 2를 정규화하면 1.0(2/2)이 되고, 두 정규화 등급의 평균은 최종 Response Groundedness 점수를 1로 유지해요.
유사한 Ragas 지표(Similar Ragas Metrics)
-
충실성(Faithfulness): 이 지표는 응답이 검색 컨텍스트와 사실적으로 얼마나 일관적인지 측정하며, 응답의 모든 claim이 제공된 정보로 뒷받침되도록 해요. Faithfulness 점수는 0에서 1 사이이며, 높을수록 일관성이 좋다는 뜻이에요.
-
루브릭 점수(Rubric Score): 사용자 정의 기준에 따라 응답을 평가하는 범용 지표로, 루브릭을 요구사항에 맞춰 정렬해 Answer Accuracy, Context Relevance 또는 Response Groundedness를 평가하도록 적용할 수 있어요.
지표 비교(Comparison of Metrics)
Faithfulness vs. Response Groundedness
- LLM 호출: Faithfulness는 상세한 claim 분해와 판정에 두 번의 호출이 필요하고, Response Groundedness는 두 번의 독립 LLM 판단을 사용해요.
- 토큰 사용량: Faithfulness는 더 많은 토큰을 소모하고, Response Groundedness는 더 토큰 효율적이에요.
- 설명 가능성: Faithfulness는 각 claim에 대한 투명한 추론을 제공하고, Response Groundedness는 원시 점수를 제공해요.
- 견고한 평가: Faithfulness는 포괄적 평가를 위해 사용자 입력을 통합하고, Response Groundedness는 이중 LLM 평가를 통해 일관성을 보장해요.
레거시 지표 API(Legacy Metrics API)
다음 예시는 레거시 지표 API 패턴을 사용해요. 새 프로젝트에는 위에서 보여준 컬렉션 기반 API를 권장해요.
폐지 일정(Deprecation Timeline) 이 API는 버전 0.4에서 폐지되고 버전 1.0에서 제거될 예정이에요. 위에 보여준 컬렉션 기반 API로 마이그레이션해주세요.
SingleTurnSample과 함께하는 예시(Example with SingleTurnSample)
from ragas.dataset_schema import SingleTurnSample
from ragas.metrics import ResponseGroundedness
sample = SingleTurnSample(
response="Albert Einstein was born in 1879.",
retrieved_contexts=[
"Albert Einstein was born March 14, 1879.",
"Albert Einstein was born at Ulm, in Württemberg, Germany.",
]
)
scorer = ResponseGroundedness(llm=evaluator_llm)
score = await scorer.single_turn_ascore(sample)
print(score)
출력(Output):
1.0