0Pricing
AI Engineering Academy · 강의

생성 지표: 충실도와 답변 관련성

RAGAS를 사용해 생성된 답변이 검색된 컨텍스트에 충실한지, 환각 없이 실제로 사용자의 질문에 답하는지 측정합니다.

생성 지표: 충실도와 답변 관련성은(는) CoddyKit의 무료 AI Engineering Academy 강의입니다. 이것은 4개 중 3번째 강의입니다. 아래에서 전체 강의를 무료로 읽을 수 있으며, 내장 코드 에디터와 24/7 AI 튜터와 함께 브라우저에서 직접 실습할 수 있습니다. 이 강의는 AI Engineering Academy 학습 경로의 일부이며, 진행 상황이 웹과 CoddyKit 앱에 동기화됩니다. AI Engineering Academy 강의에는 총 4개의 강의가 포함되어 있습니다.

생성 단계 측정하기

검색기가 완벽한 청크를 찾아도 생성 단계에서는 여전히 실패할 수 있습니다. LLM이 검색된 문맥을 무시하고 매개변수 기억에서 답하거나, 문맥의 내용을 잘못 해석하거나, 질문과 약간 다른 질문에 답할 수 있습니다. 생성 지표는 이러한 실패를 검색과 별도로 수치화하므로 각 문제를 찾아 수정할 수 있습니다. 생성의 두 가지 주요 지표는 충실도와 답변 관련성입니다.

충실도: 정의

충실도는 생성된 답변의 모든 주장을 검색된 문맥으로 직접 추적할 수 있는지 측정합니다. 충실한 답변은 문맥에 없는 정보를 추가하지 않습니다. 충실도는 주장 단위로 측정합니다. 답변을 개별적인 원자적 진술로 나눈 다음, 각각이 문맥에서 뒷받침되는지 확인합니다. 충실도 점수는 뒷받침되는 주장의 비율입니다.

# Faithfulness = supported_claims / total_claims

example_answer = (
    'Employees receive 15 vacation days per year. '
    'Remote work is allowed on Wednesdays and Fridays. '
    'The CEO is John Smith.'
)
example_context = (
    '15 vacation days are granted annually. '
    'Remote work is permitted on Wednesdays and Fridays.'
)

# Claim 1: 15 vacation days — SUPPORTED
# Claim 2: Remote work Wed+Fri — SUPPORTED
# Claim 3: CEO is John Smith — NOT IN CONTEXT (hallucinated)
# Faithfulness = 2/3 = 0.67

LLM을 평가자로 사용한 충실도 구현

대규모로 충실도를 측정하는 가장 실용적인 방법은 강력한 LLM을 평가자로 사용하는 것입니다. 평가용 LLM에 답변을 개별 주장으로 나누도록 요청한 다음, 각 주장을 문맥과 대조하게 하십시오. 평가용 LLM은 각 주장을 SUPPORTED 또는 UNSUPPORTED로 표시한 목록을 반환하며, 이 중 뒷받침되는 주장의 비율을 계산합니다. 이 방법을 사용하면 평가 한 건당 몇 센트의 비용으로 시간당 수천 건의 평가를 처리할 수 있습니다.

import json

def evaluate_faithfulness(answer, context, llm_client):
    prompt = (
        'Task: Evaluate the faithfulness of an answer against a context.\n\n'
        f'Context:\n{context}\n\n'
        f'Answer:\n{answer}\n\n'
        'Steps:\n'
        '1. Break the answer into individual atomic claims.\n'
        '2. For each claim, check if it is supported by the context.\n'
        '3. Return JSON: {"claims": [{"text": "...", "supported": true/false}], "score": 0.0-1.0}'
    )
    response = llm_client.chat.completions.create(
        model='gpt-4o',
        response_format={'type': 'json_object'},
        messages=[{'role': 'user', 'content': prompt}]
    )
    return json.loads(response.choices[0].message.content)

답변 관련성: 정의

답변 관련성은 생성된 답변이 실제로 사용자의 질문에 답하고 있는지를 측정합니다. 매우 충실한 답변이라도 핵심을 놓칠 수 있습니다. 예를 들어 사용자가 '비밀번호를 어떻게 재설정하나요?'라고 물었는데, 답변이 비밀번호 재설정 절차는 언급하지 않고 회사의 일반적인 보안 정책만 자세히 설명하는 경우입니다. 답변 관련성은 충실성과는 별개입니다. 즉, 문맥에 있는 내용만 말해 충실할 수는 있지만, 질문에 답하지 않아 관련성이 떨어질 수 있습니다.

답변 관련성 측정

RAGAS는 영리한 역생성 기법을 사용해 답변 관련성을 측정합니다. 평가자 LLM이 생성된 응답으로 답할 수 있는 가상의 질문을 여러 개 만든 다음, 임베딩 코사인 유사도를 사용해 이렇게 생성한 질문과 원래 질문이 얼마나 유사한지 측정합니다. 생성된 가상 질문과 원래 질문의 유사도가 높으면 답변 관련성도 높다는 뜻입니다.

def evaluate_answer_relevance(question, answer, llm_client, embed_fn):
    # Generate hypothetical questions for this answer
    prompt = (
        f'Given this answer: "{answer}"\n\n'
        'Generate 3 questions that this answer would be a good response to.\n'
        'Return as JSON: {"questions": ["...", "...", "..."]}'
    )
    response = llm_client.chat.completions.create(
        model='gpt-4o-mini',
        response_format={'type': 'json_object'},
        messages=[{'role': 'user', 'content': prompt}]
    )
    hyp_questions = json.loads(response.choices[0].message.content)['questions']

    # Measure similarity to original question
    orig_embedding = embed_fn(question)
    hyp_embeddings = [embed_fn(q) for q in hyp_questions]
    similarities = [cosine_similarity(orig_embedding, e) for e in hyp_embeddings]
    return sum(similarities) / len(similarities)

문맥 재현율: 충분히 검색했나요?

문맥 재현율은 검색된 문맥에 질문에 정확히 답하는 데 필요한 정보가 충분히 포함되어 있는지를 측정합니다. 정답을 문장별로 확인하여 각 문장을 검색된 청크 중 하나에 귀속할 수 있는지 검사합니다. 문맥 재현율이 높다는 것은 검색기가 필요한 내용을 모두 찾았다는 뜻입니다. 문맥 재현율이 낮다는 것은 검색된 청크에서 핵심 정보가 빠졌다는 뜻이므로, LLM이 아무리 완벽하게 생성하더라도 정확히 답할 수 없습니다.

def evaluate_context_recall(ground_truth_answer, retrieved_contexts, llm_client):
    prompt = (
        f'Ground truth answer:\n{ground_truth_answer}\n\n'
        f'Retrieved context:\n{",".join(retrieved_contexts)}\n\n'
        'For each sentence in the ground truth answer, determine if it '
        'can be attributed to the retrieved context.\n'
        'Return JSON: {"sentences": [{"text": "...", "in_context": true/false}], "recall": 0.0-1.0}'
    )
    response = llm_client.chat.completions.create(
        model='gpt-4o',
        response_format={'type': 'json_object'},
        messages=[{'role': 'user', 'content': prompt}]
    )
    return json.loads(response.choices[0].message.content)

문맥 정밀도: 검색된 청크가 관련 있나요?

문맥 정밀도는 검색된 청크가 질문에 답하는 데 실제로 유용한지를 측정합니다. 문맥 정밀도가 높으면 검색된 청크가 질문과 밀접하게 관련되어 있다는 뜻입니다. 문맥 정밀도가 낮으면 검색된 청크 중 많은 부분이 주제와 무관한 잡음이어서 LLM이 이를 읽고 버려야 하며, 혼동이 발생할 위험도 커집니다. 문맥 정밀도는 생성된 답변에서 실제로 사용되거나 참조된 검색 청크가 무엇인지 확인하여 측정합니다.

def evaluate_context_precision(question, answer, retrieved_contexts, llm_client):
    precision_scores = []
    for i, context in enumerate(retrieved_contexts, 1):
        prompt = (
            f'Question: {question}\n\n'
            f'Context chunk {i}: {context}\n\n'
            f'Answer: {answer}\n\n'
            'Was this context chunk useful in generating the answer? '
            'Return JSON: {"useful": true/false, "reason": "..."}'
        )
        response = llm_client.chat.completions.create(
            model='gpt-4o-mini',
            response_format={'type': 'json_object'},
            messages=[{'role': 'user', 'content': prompt}]
        )
        result = json.loads(response.choices[0].message.content)
        precision_scores.append(1.0 if result['useful'] else 0.0)
    return sum(precision_scores) / len(precision_scores)

모든 지표를 한 번에 RAGAS로 사용하기

RAGAS 라이브러리는 문맥 정밀도, 문맥 재현율, 충실성, 답변 관련성이라는 네 가지 핵심 RAG 지표를 하나의 프레임워크로 구현합니다. 평가자 LLM 호출도 내부적으로 처리합니다. 질문, 생성된 답변, 검색된 문맥, 정답 답변이 포함된 데이터세트를 전달하면 종합 점수 보고서를 받을 수 있습니다. RAGAS는 비동기 평가도 지원하므로 수백 개의 예시를 병렬로 평가할 수 있습니다.

from ragas import evaluate
from ragas.metrics import (
    faithfulness, answer_relevancy,
    context_precision, context_recall
)
from datasets import Dataset

# Build evaluation dataset
eval_samples = [
    {
        'question': item['question'],
        'answer': item['generated_answer'],
        'contexts': item['retrieved_texts'],
        'ground_truth': item['expected_answer']
    }
    for item in test_results
]

eval_dataset = Dataset.from_list(eval_samples)
results = evaluate(eval_dataset,
    metrics=[faithfulness, answer_relevancy, context_precision, context_recall]
)
results.to_pandas().to_csv('eval_results.csv', index=False)

지표 조합으로 문제 진단하기

지표를 조합하면 시스템의 구체적인 문제를 파악할 수 있습니다. 충실성 낮음 + 문맥 정밀도 높음 → LLM이 문맥을 무시하고 환각을 생성하고 있습니다(프롬프트를 수정해야 합니다). 문맥 재현율 낮음 + 충실성 높음 → 검색기가 핵심 청크를 놓쳤지만 LLM은 찾은 내용을 충실하게 보고하고 있습니다(청크 분할 또는 임베딩을 수정해야 합니다). 답변 관련성 낮음 + 충실성 높음 → 검색된 청크가 질문과 부분적으로만 관련되어 LLM이 이를 충실하게 설명하지만 질문에는 답하지 못하고 있습니다(검색 필터링 또는 질의 재작성을 개선해야 합니다).

# Diagnostic matrix
diagnostics = [
    {
        'condition': 'Low faithfulness + High context precision',
        'cause': 'LLM ignoring context, answering from parametric memory',
        'fix': 'Strengthen system prompt: "Answer ONLY from the provided context"'
    },
    {
        'condition': 'Low context recall + High faithfulness',
        'cause': 'Retriever missing relevant chunks',
        'fix': 'Improve chunking strategy, embedding model, or increase top-k'
    },
    {
        'condition': 'Low answer relevance + High context recall',
        'cause': 'Retrieved context is off-topic; LLM is answering wrong question',
        'fix': 'Add query rewriting or improve metadata filters'
    }
]

보정을 위한 사람 평가

LLM 평가자 지표는 사람의 판단과 상관관계가 있지만 완전히 일치하지는 않습니다. 사람 평가자 3명이 무작위로 추출한 답변 50개의 충실성과 답변 관련성을 1~5점 척도로 평가하게 하여 자동 지표를 보정하십시오. LLM 평가자의 점수와 사람 평가자 평균 점수의 일치도를 계산합니다. LLM이 사람보다 체계적으로 높거나 낮은 점수를 주면 보정 계수를 적용합니다. 보정된 자동 지표를 사용하면 점수 향상이 실제 품질 향상을 반영한다는 확신을 얻을 수 있습니다.

from scipy.stats import spearmanr

def calibrate_judge_vs_humans(samples):
    '''samples: [{"llm_score": 0.9, "human_score": 4.2}, ...]'''
    llm_scores = [s['llm_score'] for s in samples]
    human_scores = [s['human_score'] / 5.0 for s in samples]  # normalize to 0-1

    correlation, pvalue = spearmanr(llm_scores, human_scores)
    print(f'LLM-Human Spearman correlation: {correlation:.3f} (p={pvalue:.4f})')

    mean_llm = sum(llm_scores) / len(llm_scores)
    mean_human = sum(human_scores) / len(human_scores)
    bias = mean_llm - mean_human
    print(f'LLM bias vs humans: {bias:+.3f}')
    return correlation, bias

운영 환경을 위한 지표 목표 설정

RAG 시스템을 운영 환경에 배포하기 전에 시스템이 충족해야 할 최소 지표 임계값을 정의하십시오. 일반적인 운영 목표는 다음과 같습니다. 충실성 > 0.90(답변 주장 중 환각이 10% 미만), 답변 관련성 > 0.80(답변의 80% 이상이 실제로 질문에 답함), 문맥 정밀도 > 0.60(검색된 청크 대부분이 관련 있음), 문맥 재현율 > 0.75(핵심 사실 대부분을 검색된 문맥에서 이용할 수 있음). 이러한 임계값을 충족하지 못하는 시스템은 추가 개선 없이는 배포해서는 안 됩니다.

PRODUCTION_THRESHOLDS = {
    'faithfulness': 0.90,
    'answer_relevancy': 0.80,
    'context_precision': 0.60,
    'context_recall': 0.75
}

def check_production_readiness(metrics):
    ready = True
    print('Production readiness check:')
    for metric, threshold in PRODUCTION_THRESHOLDS.items():
        score = metrics.get(metric, 0)
        status = 'PASS' if score >= threshold else 'FAIL'
        print(f'  {metric}: {score:.2f} (>= {threshold}) -> {status}')
        if status == 'FAIL':
            ready = False
    print(f'Overall: {"READY" if ready else "NOT READY"}')
    return ready

빠른 확인

이 수업에서 배운 AI 엔지니어링 개념을 이해했는지 확인해 보십시오.

수업 복습

이 수업에서는 다음을 배웠습니다. 충실성은 답변의 각 진술이 검색된 문맥으로 뒷받침되는지를 확인하는 주장 수준의 지표이고, 답변 관련성은 답변이 실제 질문에 답하는지를 측정하는 지표입니다. 또한 문맥 재현율과 정밀도를 통해 생성 관점에서 검색 품질을 측정하는 방법과, 자동 다중 지표 평가를 위한 RAGAS 라이브러리를 배웠습니다. 다음으로 이 모든 지표를 변경 사항마다 실행할 수 있는 자동화된 평가 하니스로 구성해 보겠습니다.

자주 묻는 질문

“생성 지표: 충실도와 답변 관련성” 강의는 무료인가요?

네 — “생성 지표: 충실도와 답변 관련성” 전체 내용을 이 웹사이트에서 무료로 읽을 수 있습니다. 인터랙티브하게 실습하려면(내장 코드 에디터와 24/7 AI 튜터), CoddyKit PRO로 업그레이드하면 AI Engineering Academy 강의 전체를 잠금 해제할 수 있습니다. AI Engineering Academy 강의에는 총 4개의 강의가 포함되어 있습니다.

“생성 지표: 충실도와 답변 관련성”에서 뭘 배우나요?

RAGAS를 사용해 생성된 답변이 검색된 컨텍스트에 충실한지, 환각 없이 실제로 사용자의 질문에 답하는지 측정합니다. 브라우저에서 직접 실행하는 실습 코드로 AI Engineering Academy을(를) 배우며, 24/7 AI 튜터가 강의를 진행하면서 질문에 답변해줍니다.

AI Engineering Academy을(를) 시작하는 데 경험이 필요한가요?

사전 경험은 필요하지 않습니다. CoddyKit의 AI Engineering Academy은(는) 초급자부터 고급 학습자까지를 위해 구성되어 있으므로, 여기서 시작하거나 처음부터 시작할 수 있으며 자신의 속도대로 진행할 수 있습니다. 이것은 4개 중 3번째 강의입니다.

“생성 지표: 충실도와 답변 관련성” 강의는 얼마나 걸리나요?

대부분의 CoddyKit 강의는 약 5~10분이 소요됩니다. 각 강의는 간결하고 인터랙티브하여 꾸준한 진행이 가능하며, 웹과 앱에서 중단한 부분부터 바로 시작할 수 있습니다.

이 AI Engineering Academy 강의에서 코드를 작성하고 실행할 수 있나요?

네. 모든 AI Engineering Academy 강의에는 내장 코드 에디터가 포함되어 있으므로, 브라우저에서 바로 실제 코드를 작성하고 실행한 후 즉시 AI 피드백을 받을 수 있습니다 — 로컬 설정이 필요 없습니다.

이 강의의 모든 강의

  1. RAG에서 평가가 중요한 이유
  2. 검색 지표: 적중률, MRR, NDCG
  3. 생성 지표: 충실도와 답변 관련성
  4. 자동화된 평가 도구 구축
← AI Engineering Academy(으)로 돌아가기