Metriche di generazione: faithfulness e rilevanza della risposta
Utilizzerà RAGAS per misurare se le risposte generate siano fedeli al contesto recuperato e se rispondano realmente alla domanda dell'utente senza generare allucinazioni.
Metriche di generazione: faithfulness e rilevanza della risposta è una lezione AI Engineering Academy gratuita su CoddyKit. Questa è la lezione 3 di 4. Puoi leggere la lezione completa qui gratuitamente — poi esercitati direttamente nel browser con un editor di codice integrato e un tutor IA disponibile 24/7. Fa parte del percorso di apprendimento AI Engineering Academy, e i tuoi progressi si sincronizzano tra il web e l'app CoddyKit. Il corso AI Engineering Academy include 4 lezioni in totale.
Parti di questa lezione non sono ancora state tradotte e vengono mostrate in inglese.
Measuring the Generation Stage
Even when your retriever finds the perfect chunks, the generation stage can still fail. The LLM might ignore the retrieved context and answer from its parametric memory, misinterpret what the context says, or answer a slightly different question than what was asked. Generation metrics quantify these failures independently from retrieval so you can pinpoint and fix each problem. The two primary generation metrics are faithfulness and answer relevance.
Faithfulness: Definition
Faithfulness measures whether every claim in the generated answer can be directly traced back to the retrieved context. A faithful answer introduces no information that is not present in the context. Faithfulness is measured at the claim level: the answer is decomposed into individual atomic statements, and each is checked against the context for support. The faithfulness score is the fraction of claims that are supported.
# 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.67Implementing Faithfulness with LLM-as-Judge
The most practical way to measure faithfulness at scale is to use a powerful LLM as a judge. Prompt the judge LLM to decompose the answer into individual claims, then check each claim against the context. The judge returns a list of claims labeled SUPPORTED or UNSUPPORTED, and you compute the fraction that are supported. This approach scales to thousands of evaluations per hour at a cost of a few cents per evaluation.
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)Answer Relevance: Definition
Answer relevance measures whether the generated answer actually addresses the user's question. A highly faithful answer might still miss the point — for example, if the user asks 'How do I reset my password?' and the answer explains the company's general security policy in detail without mentioning the password reset procedure. Answer relevance is independent of faithfulness: you can be faithful (only saying things in the context) but irrelevant (not addressing what was asked).
Measuring Answer Relevance
RAGAS measures answer relevance using a clever reverse-generation technique: the judge LLM generates several hypothetical questions that would be answered by the generated response, then measures how similar these generated questions are to the original question using embedding cosine similarity. High similarity between the generated hypothetical questions and the original question indicates high answer relevance.
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)Context Recall: Did We Retrieve Enough?
Context recall measures whether the retrieved context contains sufficient information to answer the question correctly. It checks the ground truth answer sentence by sentence: can each sentence be attributed to one of the retrieved chunks? High context recall means the retriever found everything needed. Low context recall means key information was missing from the retrieved chunks, so the LLM cannot possibly answer correctly even with perfect generation.
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)Context Precision: Are Retrieved Chunks Relevant?
Context precision measures whether the retrieved chunks are actually useful for answering the question. High context precision means the retrieved chunks are tightly relevant. Low context precision means many retrieved chunks are off-topic noise that the LLM must read and discard, increasing the risk of confusion. Context precision is measured by checking which retrieved chunks were actually used or referenced in the generated answer.
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)Using RAGAS for All Metrics at Once
The RAGAS library implements all four core RAG metrics — context precision, context recall, faithfulness, and answer relevance — in a single framework. It handles the LLM judge calls internally. Pass a dataset with questions, generated answers, retrieved contexts, and ground truth answers, and receive a comprehensive score report. RAGAS also supports async evaluation so you can evaluate hundreds of examples in parallel.
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)Diagnosing with Metric Combinations
The combination of metrics reveals specific system problems. Low faithfulness + high context precision → LLM is ignoring the context and hallucinating (fix the prompt). Low context recall + high faithfulness → retriever is missing key chunks but LLM faithfully reports what it found (fix chunking or embedding). Low answer relevance + high faithfulness → retrieved chunks are tangentially related and the LLM faithfully discusses them but misses the question (improve retrieval filtering or query rewriting).
# 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'
}
]Human Evaluation for Calibration
LLM-as-judge metrics are correlated with human judgment but not perfectly aligned. Calibrate your automated metrics by having 3 human raters score a random sample of 50 outputs on faithfulness and answer relevance using a 1-5 scale. Compute agreement between the LLM judge and the average human rating. If the LLM systematically over- or under-scores relative to humans, apply a correction factor. Calibrated automated metrics give you confidence that score improvements reflect real quality improvements.
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, biasSetting Metric Targets for Production
Before deploying a RAG system to production, define minimum metric thresholds that the system must meet. Common production targets are: faithfulness > 0.90 (fewer than 10% of answer claims are hallucinated), answer relevance > 0.80 (80%+ of answers actually address the question), context precision > 0.60 (most retrieved chunks are relevant), and context recall > 0.75 (most key facts are available in retrieved context). Systems that fail these thresholds should not be deployed without further improvement.
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 readyQuick Check
Test your understanding of AI Engineering concepts from this lesson.
Lesson Recap
In this lesson you learned: faithfulness as the claim-level metric checking whether every answer statement is supported by the retrieved context, answer relevance as the metric measuring whether the answer addresses the actual question, context recall and precision for measuring retrieval quality from the generation perspective, and the RAGAS library for automated multi-metric evaluation. Next up we assemble all these metrics into an automated evaluation harness you can run on every change.
Domande Frequenti
La lezione «Metriche di generazione: faithfulness e rilevanza della risposta» è gratuita?
Sì — il testo completo di «Metriche di generazione: faithfulness e rilevanza della risposta» è gratuito qui sul web. Per esercitarvi in modo interattivo (un editor di codice integrato e un tutor IA 24/7) e sbloccare il resto del corso AI Engineering Academy, passa a CoddyKit PRO. Il corso AI Engineering Academy include 4 lezioni in totale.
Cosa imparerò in «Metriche di generazione: faithfulness e rilevanza della risposta»?
Utilizzerà RAGAS per misurare se le risposte generate siano fedeli al contesto recuperato e se rispondano realmente alla domanda dell'utente senza generare allucinazioni. Eserciti AI Engineering Academy con codice pratico che esegui direttamente nel browser, e un tutor IA 24/7 risponde alle tue domande mentre lavori sulla lezione.
Ho bisogno di esperienza per iniziare AI Engineering Academy?
Non è richiesta alcuna esperienza precedente. AI Engineering Academy su CoddyKit è strutturato per principianti e studenti avanzati, quindi puoi iniziare da qui o dall'inizio e procedere al tuo ritmo. Questa è la lezione 3 di 4.
Quanto tempo richiede la lezione «Metriche di generazione: faithfulness e rilevanza della risposta»?
La maggior parte delle lezioni CoddyKit richiede circa 5–10 minuti. Ogni lezione è breve e interattiva, quindi fai progressi costanti e riprendi esattamente da dove hai lasciato su web e app.
Posso scrivere ed eseguire codice in questa lezione AI Engineering Academy?
Sì. Ogni lezione AI Engineering Academy include un editor di codice integrato, quindi scrivi ed esegui codice reale direttamente nel tuo browser e ricevi feedback istantaneo dall'IA — nessuna configurazione locale necessaria.
Tutte le lezioni di questo corso
- Perché la valutazione è importante nel RAG
- Metriche di retrieval: hit rate, MRR e NDCG
- Metriche di generazione: faithfulness e rilevanza della risposta
- Creare un sistema automatizzato di valutazione