LLM evaluation in production isn’t about finding the "best" model, it’s about finding the model that’s "good enough" for your specific, often messy, task.

Let’s see this in action. Imagine we’re building a customer support chatbot that needs to summarize incoming tickets. We’ve got a few candidate models.

Here’s a snippet of a Python script using the evaluate library to compare two summarization models on a small, representative dataset of real customer tickets:

from evaluate import load
import pandas as pd

# Load a pre-trained ROUGE scorer
rouge = load("rouge")

# Sample data: (input_text, reference_summary, model_summary_1, model_summary_2)
data = [
    ("The customer's account is locked. They can't log in and are getting error code 503. They need urgent assistance.", "Customer locked out, error 503, requires urgent help.", "User locked out of account, error 503, needs help.", "Customer cannot access account due to lockout, error 503. Immediate support required."),
    ("My order #12345 was supposed to arrive yesterday but it's still not here. I need to know where it is.", "Order #12345 delayed, customer seeking location update.", "Order 12345 not delivered as expected, customer wants status.", "Customer's order #12345 is late. Seeking delivery status."),
    ("I'm trying to reset my password but I'm not receiving the reset email. Checked spam folder too.", "Password reset email not received, even in spam.", "User attempting password reset, email not arriving. Spam checked.", "Cannot reset password, no reset email received. Verified spam folder.")
]

df = pd.DataFrame(data, columns=["ticket", "reference", "model1_summary", "model2_summary"])

# Evaluate Model 1
model1_results = rouge.compute(predictions=df["model1_summary"], references=df["reference"])
print("Model 1 ROUGE-L:", model1_results["rougeL"])

# Evaluate Model 2
model2_results = rouge.compute(predictions=df["model2_summary"], references=df["reference"])
print("Model 2 ROUGE-L:", model2_results["rougeL"])

When you run this, you’d see output like:

Model 1 ROUGE-L: 0.65
Model 2 ROUGE-L: 0.71

This tells us that, on this specific sample, Model 2’s summaries are more aligned with our human-written "reference" summaries based on the ROUGE-L metric.

But what problem does this actually solve? LLMs are powerful, but their output can be wildly inconsistent. For a production system, we need predictable, reliable performance. We can’t just deploy a model and hope for the best. We need to quantify how good it is for our specific use case.

The core idea is to map abstract LLM capabilities (like "understanding" or "generating") to concrete, measurable outcomes. We do this by:

  1. Defining Success: What does a "good" output look like for your application? This is highly contextual. For summarization, it might be capturing key entities and sentiment. For code generation, it might be passing unit tests.
  2. Selecting Metrics: Choose metrics that directly reflect your definition of success. Common ones include:
    • ROUGE (Recall-Oriented Understudy for Gisting Evaluation): Measures overlap of n-grams between generated and reference text. Good for summarization, translation.
    • BLEU (Bilingual Evaluation Understudy): Similar to ROUGE, but emphasizes precision. Common in machine translation.
    • BERTScore: Uses contextual embeddings to measure semantic similarity, often more robust than n-gram overlap.
    • Accuracy/F1 Score: For classification tasks (e.g., sentiment analysis, intent recognition).
    • Exact Match (EM): For question answering where the answer must be precisely correct.
    • Custom Metrics: Sometimes, you need to build your own. For example, checking if a generated JSON adheres to a schema, or if a code snippet compiles.
  3. Creating Benchmarks: This is your curated dataset of inputs and desired outputs (references). Crucially, this dataset must reflect the real-world data your LLM will encounter in production. A benchmark used for academic research on general knowledge might be useless for evaluating a specialized medical chatbot.
  4. Automated Evaluation: Run your LLM against the benchmark and compute the chosen metrics. This gives you a quantitative score.
  5. Human Evaluation (The Ground Truth): Automated metrics are proxies. For critical applications, human review of a subset of outputs is essential to validate metric scores and catch nuances the automated metrics miss.

The levers you control are primarily the benchmark dataset and the chosen metrics. A richer, more diverse benchmark will give you a more accurate picture. Selecting metrics that align perfectly with your business objective is paramount. For example, if your chatbot needs to reduce customer frustration, a metric that captures negative sentiment in the generated response might be more important than pure factual accuracy.

The real power of LLM evaluation in production isn’t about chasing a perfect score on a generic benchmark like MMLU. It’s about building a targeted evaluation suite that tells you, with high confidence, if the model is doing its job reliably for your users, on your data, right now. A model might score 95% on a general QA benchmark but fail spectacularly when asked a question about your company’s specific product catalog if that domain wasn’t represented in its training or your evaluation.

What many teams miss is the feedback loop. You don’t just evaluate once and forget. Production data is dynamic. Customer queries evolve, your product changes. You need to continuously monitor model performance on live data, identify drift, and retrain or re-evaluate your chosen model regularly. The evaluation suite becomes a living part of your MLOps pipeline.

The next step after establishing robust evaluation is understanding how to actively improve performance based on those evaluation results, often through targeted fine-tuning or prompt engineering.

Want structured learning?

Take the full Llm course →