Contents

Chapter 1

LLM Evaluation Methodology Guide

Why Evaluation Matters

Deploying an LLM without systematic evaluation is like shipping software without

tests. It might work fine today, but you have no way to know when it breaks.

Models degrade silently — a prompt template change, a version bump, or new

training data can shift behavior in ways that aggregate accuracy numbers miss.

This guide walks through evaluation methodology: what to measure, how to

measure it, and how to set up continuous evaluation that catches regressions

before users do.


Choosing the Right Metrics

Decision Framework

Your TaskPrimary MetricsSecondary Metrics
Factual QAexact_match, token_f1rouge_1, bleu
Open-ended generationLLM-as-judge, human evalrouge_l, format_compliance
Summarizationrouge_l, rouge_1, faithfulnessbleu, conciseness
Code generationexecution pass rate, exact_matchbleu, structural
Classificationexact_match, token_f1
Translationbleu, rouge_lsemantic_similarity

Lexical vs Semantic vs LLM-Judge

Lexical metrics (BLEU, ROUGE, exact match) compare tokens. They're fast,

deterministic, and free. But they miss paraphrases: "Paris is the capital of

France" and "The French capital is Paris" score poorly against each other despite

being equivalent.

Semantic metrics (embedding similarity) capture meaning but require

embedding models, adding cost and a dependency. They're good for catching

paraphrases but can't distinguish factually correct from incorrect text

that happens to be semantically similar.

LLM-as-Judge captures nuance — coherence, helpfulness, safety — that

automated metrics miss. The tradeoff: cost (you pay for judge calls),

latency (seconds per evaluation), and reliability (judges have biases,

especially position bias and verbosity bias).

Recommendation: Use lexical metrics for CI/CD gate checks (fast, cheap),

LLM-judge for periodic deep evaluation, and human evaluation for launch

decisions.


Building an Evaluation Dataset

Dataset Size Guidelines

  • Quick sanity check: 20-50 samples. Enough to catch catastrophic failures.
  • Development iteration: 100-300 samples. Enough for meaningful metric

differences.

  • Release decision: 500+ samples. Enough for statistical significance

per category.

Dataset Composition

A good evaluation dataset has:

1. Category coverage: Include all task types your model will handle.

If 30% of production traffic is code generation but your eval dataset is

100% factual QA, you won't catch code generation regressions.

2. Difficulty spread: Include easy, medium, and hard samples. A model that

scores 95% on easy samples but 20% on hard ones has a very different risk

profile than one scoring 70% across the board.

3. Edge cases: Deliberately include tricky inputs — ambiguous questions,

adversarial prompts, multi-step reasoning, long context.

4. Reference quality: Reference answers should be carefully vetted.

A bad reference makes every metric noisy.

Avoiding Data Contamination

Data contamination — where eval samples appear in training data — is the

most common source of inflated benchmark scores. Use the

train_test_overlap_check() function in dataset_runner.py to check for

exact-match overlap between your eval and training datasets.


Evaluation Patterns

Pattern 1: CI/CD Gate Check

Run on every model change (prompt update, version bump):

python
from src.eval_harness import EvalHarness

harness = EvalHarness(
    model_fn=your_model,
    metrics=["exact_match", "token_f1", "rouge_l"],
)
result = harness.run_dataset("datasets/qa_sample.jsonl")

# Fail the build if accuracy drops below threshold
assert result.aggregate_metrics["exact_match"] > 0.70, (
    f"Accuracy too low: {result.aggregate_metrics['exact_match']}"
)

Pattern 2: Regression Detection

Compare two model versions before promoting to production:

python
from src.regression_tester import RegressionTester

tester = RegressionTester()
result = tester.compare("results/v1.json", "results/v2.json")

if not result.passed:
    print("Regressions detected:")
    for alert in result.alerts:
        if alert.severity == "error":
            print(f"  {alert.message}")

Pattern 3: Periodic Deep Evaluation

Run weekly with LLM-as-judge for subjective quality:

python
from src.llm_judge import LLMJudge, HELPFULNESS_RUBRIC

judge = LLMJudge(
    judge_fn=your_judge_model,
    rubric=HELPFULNESS_RUBRIC,
)
result = judge.evaluate(
    instruction="Explain quantum computing",
    prediction=model_response,
    reference=expert_answer,
)
print(f"Overall: {result.overall_score}")
for criterion, score in result.scores.items():
    print(f"  {criterion}: {score}")

Pattern 4: A/B Testing with Human Feedback

For launch decisions, collect human preferences:

python
from src.human_feedback import AnnotationSession, Annotation

session = AnnotationSession("model_comparison_v2_vs_v3")

# In your annotation UI:
session.add_annotation(Annotation.create_preference(
    sample_id="sample_42",
    annotator_id="reviewer_1",
    preference="A",  # Model A was better
    duration_seconds=23.5,
))

Setting Thresholds

How to Choose Metric Thresholds

1. Baseline first: Run your current production model on the eval dataset.

This is your baseline.

2. Set warning at 5% below baseline: Small drops might be noise or

acceptable tradeoffs.

3. Set error at 10% below baseline: Drops this large almost always indicate

a real problem.

4. Per-category thresholds: Critical categories (e.g., safety-related

questions) should have tighter thresholds than nice-to-have categories.

Statistical Significance

With small eval datasets, score differences are often just noise. Rules of

thumb:

  • < 50 samples: Differences under 10% are probably not significant.
  • 100-300 samples: Differences over 5% are likely significant.
  • 500+ samples: Differences over 2-3% are likely significant.

If you need rigorous significance testing, bootstrap the metric (resample

with replacement 1000 times, compute 95% confidence intervals).


Common Pitfalls

1. Evaluating Only on Easy Samples

Your eval dataset should include the hardest 20% of realistic queries. A model

that scores 95% on easy factual questions might score 30% on multi-hop reasoning.

2. Using BLEU for Everything

BLEU was designed for machine translation and penalizes valid paraphrases.

For open-ended generation, ROUGE-L or LLM-as-judge are better choices.

3. Ignoring Latency

A model that scores 5% higher but takes 3x longer might not be an improvement

in production. Always track latency alongside quality metrics.

4. Optimizing for the Eval Set

If you tune prompts specifically to maximize eval scores, you're overfitting

to the eval set. Keep a held-out "canary" set that you never optimize against.

5. One-Time Evaluation

Evaluation should be continuous, not a one-time event. Set up automated eval

runs on every model change and review reports weekly.


                    ┌─────────────────┐
                    │  Model Change   │
                    │  (prompt/version)│
                    └────────┬────────┘
                             │
                    ┌────────▼────────┐
                    │   CI Gate Check  │  ← Fast lexical metrics
                    │  (auto, <1 min)  │     Pass/fail threshold
                    └────────┬────────┘
                             │ pass
                    ┌────────▼────────┐
                    │ Regression Test  │  ← Compare to baseline
                    │  (auto, <5 min)  │     Per-category analysis
                    └────────┬────────┘
                             │ pass
                    ┌────────▼────────┐
                    │  LLM Judge Eval  │  ← Weekly deep eval
                    │  (scheduled)     │     Multi-criteria rubric
                    └────────┬────────┘
                             │
                    ┌────────▼────────┐
                    │  Human Review    │  ← Before major releases
                    │  (manual)        │     Pairwise preferences
                    └────────┬────────┘
                             │
                    ┌────────▼────────┐
                    │    Deploy        │
                    └─────────────────┘

Further Reading

evaluation of language models

benchmark with LLM judges

Open-source evaluation framework for few-shot tasks

LLM Evaluation Framework v1.0.0 — Free Preview