0Pricing
AI Engineering Academy · Aula

Por que a avaliação é importante em RAG

Entenda os dois modos de falha independentes em sistemas RAG: falha de recuperação e falha de geração, e aprenda por que são necessárias métricas separadas para diagnosticar cada um.

Por que a avaliação é importante em RAG é uma aula grátis de AI Engineering Academy no CoddyKit. Esta é a aula 1 de 4. Você pode ler a aula completa abaixo gratuitamente — depois pratica ao vivo no navegador com um editor de código integrado e um tutor de IA 24/7. Faz parte do caminho de aprendizado de AI Engineering Academy, e seu progresso é sincronizado entre a web e o app CoddyKit. O curso de AI Engineering Academy inclui 4 aulas no total.

Partes desta aula ainda não foram traduzidas e aparecem em inglês.

You Cannot Improve What You Do Not Measure

A RAG system can feel like it is working because it returns fluent, plausible-sounding answers. But without measurement, you have no idea whether it is actually retrieving the right chunks or generating faithful answers. Teams that skip evaluation often spend months tweaking chunking strategies and prompt formats based on gut feeling, only to discover they made things worse. Rigorous evaluation is what turns RAG development from guessing into engineering.

Two Independent Failure Modes

RAG has two distinct stages that can fail independently: retrieval and generation. Retrieval fails when the relevant chunks are not ranked in the top-K results — the LLM cannot generate a good answer if the right information was never retrieved. Generation fails when the correct chunks were retrieved but the LLM ignored them, misread them, or added hallucinated information. You need separate metrics for each stage to pinpoint which component is causing the problem.

The Danger of End-to-End Evaluation Only

Measuring only the final answer quality hides where failures come from. Suppose your system gives wrong answers 30% of the time. Is that because retrieval is missing the right chunks, or because the LLM is ignoring good chunks? If you only know the final error rate, you cannot know which component to fix. Instrument both stages separately: measure retrieval quality with golden datasets and generation quality with faithfulness scores.

# Diagnosis example: which stage is failing?

# Test 1: Is retrieval finding the right chunks?
retrieval_hit_rate = evaluate_retrieval(questions, ground_truth_chunks)
print(f'Retrieval hit rate@5: {retrieval_hit_rate:.1%}')
# If this is low (< 80%), fix chunking and embedding first

# Test 2: Given perfect context, does LLM generate correct answers?
generation_faithfulness = evaluate_generation(questions, perfect_context)
print(f'Generation faithfulness: {generation_faithfulness:.1%}')
# If retrieval is fine but this is low, fix your prompts

Building a Golden Dataset

Evaluation requires a golden dataset: a set of question-answer pairs where you know the correct answer and, ideally, which document and chunk the answer comes from. For a minimum viable evaluation set, collect 50-100 questions representative of real user queries. Answer them by hand or by reading the source documents. Include diverse question types: factual lookups, comparisons, multi-hop reasoning, and out-of-domain questions the system should refuse to answer.

# Golden dataset format
golden_dataset = [
    {
        'question': 'How many vacation days do employees receive in their first year?',
        'answer': '15 days',
        'relevant_chunks': ['employee_handbook_p24', 'benefits_summary_p3'],
        'source_doc': 'employee_handbook_2025.pdf'
    },
    {
        'question': 'What is the parental leave duration for primary caregivers?',
        'answer': '16 weeks fully paid',
        'relevant_chunks': ['parental_leave_policy_p1'],
        'source_doc': 'parental_leave_policy.pdf'
    }
]

Generating Golden Datasets with LLMs

Creating 100 questions manually is tedious. Accelerate this with a data generation LLM: feed each document chunk to GPT-4o and ask it to generate 3-5 diverse questions whose answers can be found in that chunk, plus the expected answer text. Review a sample manually to catch quality issues. This approach scales to thousands of questions quickly, though it may miss edge cases that only real users would ask.

def generate_qa_pairs_for_chunk(chunk_text, llm_client):
    prompt = (
        'Given the following document excerpt, generate 3 diverse questions '
        'that can be answered using ONLY this text. '
        'For each question, provide the exact answer from the text.\n\n'
        f'Text:\n{chunk_text}\n\n'
        'Format each as JSON: {"question": ..., "answer": ...}'
    )
    response = llm_client.chat.completions.create(
        model='gpt-4o-mini',
        messages=[{'role': 'user', 'content': prompt}]
    )
    return response.choices[0].message.content

Retrieval Evaluation: Hit Rate

Hit rate@K is the fraction of questions for which at least one relevant chunk appears in the top-K retrieval results. It is the simplest and most intuitive retrieval metric. A hit rate@5 of 85% means that for 85 out of 100 questions, the relevant chunk was among the top 5 results. Track hit rate separately for different document types, query lengths, and topic categories to find where your retriever struggles most.

def compute_hit_rate(golden_dataset, retriever, top_k=5):
    hits = 0
    for item in golden_dataset:
        results = retriever.retrieve(item['question'], top_k=top_k)
        retrieved_ids = {r['id'] for r in results}
        relevant_ids = set(item['relevant_chunks'])
        if retrieved_ids & relevant_ids:  # intersection not empty
            hits += 1
    hit_rate = hits / len(golden_dataset)
    print(f'Hit rate@{top_k}: {hit_rate:.1%} ({hits}/{len(golden_dataset)})')
    return hit_rate

Generation Evaluation: Faithfulness

Faithfulness measures whether the generated answer contains only information that can be verified in the retrieved context. An unfaithful answer adds facts the context does not support — that is hallucination. Score faithfulness by having a judge LLM (or human evaluator) check each sentence in the answer against the context and flag any claims not supported by the retrieved chunks. A faithfulness score of 95%+ is the target for production systems.

def evaluate_faithfulness(answer, context, llm_client):
    prompt = (
        'Given this context and answer, evaluate faithfulness.\n\n'
        f'Context: {context}\n\n'
        f'Answer: {answer}\n\n'
        'For each sentence in the answer, determine if it is '
        'supported by the context (FAITHFUL) or not (HALLUCINATED). '
        'Return a JSON: {"score": 0.0-1.0, "issues": ["sentence..."]}.'
    )
    response = llm_client.chat.completions.create(
        model='gpt-4o',
        messages=[{'role': 'user', 'content': prompt}]
    )
    return response.choices[0].message.content

Generation Evaluation: Answer Relevance

Answer relevance measures whether the generated answer actually addresses the user's question. A highly faithful answer might still miss the point by answering a related but different question. Measure relevance separately from faithfulness. Use a judge LLM to rate whether the answer directly addresses what was asked, using a 1-5 scale. Low answer relevance often indicates a problem with the prompt structure or the retrieved context not actually containing the answer.

def evaluate_answer_relevance(question, answer, llm_client):
    prompt = (
        f'Question: {question}\n\n'
        f'Answer: {answer}\n\n'
        'Rate how well this answer addresses the question on a 1-5 scale:\n'
        '5 = fully answers the question\n'
        '3 = partially answers but misses key aspects\n'
        '1 = does not address the question at all\n\n'
        'Return JSON: {"score": 1-5, "reason": "brief explanation"}'
    )
    response = llm_client.chat.completions.create(
        model='gpt-4o',
        messages=[{'role': 'user', 'content': prompt}]
    )
    return response.choices[0].message.content

Tracking Metrics Over Time

Evaluation is most valuable when you track metrics over time as you make changes. Store evaluation results in a database or spreadsheet with timestamps and version labels (e.g., chunk_size=500, embed=3-small, k=5). When you try a new chunking strategy or embedding model, run the same evaluation and compare. This prevents regression — you might improve faithfulness but accidentally reduce hit rate. Always run the full evaluation before merging changes to production.

import json
from datetime import datetime

def save_evaluation_results(metrics, config, output_file='eval_history.jsonl'):
    record = {
        'timestamp': datetime.utcnow().isoformat(),
        'config': config,
        'metrics': metrics
    }
    with open(output_file, 'a') as f:
        f.write(json.dumps(record) + '\n')
    print(f'Saved eval result: hit_rate={metrics["hit_rate"]:.1%}, '
          f'faithfulness={metrics["faithfulness"]:.1%}')

The Evaluation Mindset

Beyond specific metrics, evaluation requires a mindset shift: treat RAG as a machine learning system with measurable performance, not a chatbot you subjectively assess by chatting with it. Define success criteria upfront (e.g., hit rate@5 > 85%, faithfulness > 95%). Establish a test set that stays frozen and is never used for development decisions. Reserve a separate dev set for iteration. This discipline separates teams that ship reliable RAG from teams that ship impressive demos that fail in production.

Test Set vs Development Set

A critical discipline in machine learning that also applies to RAG evaluation is the train-dev-test split. Your test set should be completely frozen — never used to make development decisions. Use a separate dev set for experimenting with chunking strategies, prompt changes, and embedding models. Only run the test set when you believe a change is production-ready. This separation prevents overfitting your RAG pipeline to the test set and ensures your final reported metrics reflect genuine generalization.

import json
from sklearn.model_selection import train_test_split

def split_golden_dataset(all_questions, test_ratio=0.3, seed=42):
    dev_set, test_set = train_test_split(
        all_questions,
        test_size=test_ratio,
        random_state=seed
    )
    print(f'Dev set: {len(dev_set)} questions')
    print(f'Test set: {len(test_set)} questions (FROZEN)')
    with open('eval/dev_set.json', 'w') as f:
        json.dump(dev_set, f, indent=2)
    with open('eval/test_set.json', 'w') as f:
        json.dump(test_set, f, indent=2)
    return dev_set, test_set

Quick Check

Test your understanding of AI Engineering concepts from this lesson.

Lesson Recap

In this lesson you learned: the two independent failure modes of retrieval and generation that require separate metrics, how to build a golden dataset of question-answer-chunk triples for objective evaluation, hit rate as the core retrieval metric and faithfulness and answer relevance as the core generation metrics, and the importance of tracking metrics over time to prevent regressions. Next up we implement specific retrieval metrics including MRR and NDCG.

Perguntas Frequentes

A aula “Por que a avaliação é importante em RAG” é grátis?

Sim — o texto completo de “Por que a avaliação é importante em RAG” é grátis para ler aqui na web. Para praticá-la interativamente (um editor de código integrado e um tutor de IA 24/7) e desbloquear o restante do curso de AI Engineering Academy, atualize para CoddyKit PRO. O curso de AI Engineering Academy inclui 4 aulas no total.

O que vou aprender em “Por que a avaliação é importante em RAG”?

Entenda os dois modos de falha independentes em sistemas RAG: falha de recuperação e falha de geração, e aprenda por que são necessárias métricas separadas para diagnosticar cada um. Você pratica AI Engineering Academy com código prático que executa diretamente no navegador, e um tutor de IA 24/7 responde suas dúvidas enquanto trabalha na aula.

Preciso ter experiência prévia para começar AI Engineering Academy?

Nenhuma experiência prévia é necessária. AI Engineering Academy no CoddyKit é estruturado para alunos iniciantes até avançados, então você pode começar aqui ou desde o início e aprender no seu ritmo. Esta é a aula 1 de 4.

Quanto tempo leva a aula “Por que a avaliação é importante em RAG”?

A maioria das aulas CoddyKit leva cerca de 5–10 minutos. Cada uma é compacta e interativa, então você faz progresso constante e retoma exatamente de onde parou entre web e app.

Posso escrever e executar código nesta aula de AI Engineering Academy?

Sim. Cada aula de AI Engineering Academy inclui um editor de código integrado, então você escreve e executa código real direto no navegador e recebe feedback de IA instantaneamente — nenhuma configuração local necessária.

Todas as aulas deste curso

  1. Por que a avaliação é importante em RAG
  2. Métricas de recuperação: taxa de acerto, MRR e NDCG
  3. Métricas de geração: fidelidade e relevância da resposta
  4. Criando uma estrutura automatizada de avaliação
← Voltar para AI Engineering Academy