| |

How to Evaluate LLM Outputs with DeepEval: A Complete Guide

Evaluate LLM outputs with DeepEval metrics, test cases, and thresholds

Most teams ship LLM features the way I used to ship UI tests ten years ago: a human eyeballs the output, says “looks fine,” and moves on. That approach does not survive contact with a real user base. If you want to evaluate LLM outputs with any rigor, you need a framework that turns “looks fine” into a number, a threshold, and a CI gate. This guide walks you through doing exactly that with DeepEval, the open-source evaluation framework that has quietly become the default for QA engineers moving into AI testing.

Table of Contents

Contents

Why “It Looks Good to Me” Doesn’t Scale

Here is the exact failure pattern I see across the teams I talk to. Someone ships a RAG chatbot or a summarizer. For the first week, the founder or a senior engineer manually reads 20 outputs, tweaks the prompt twice, and declares the feature working. Then a customer asks a slightly different question and the model confidently returns a wrong answer. Nobody caught it, because “looks fine” is not a test.

Manual review fails on three fronts:

  • It doesn’t run continuously. You change the model, the embedding index, or the system prompt, and no one re-checks the old cases.
  • It doesn’t scale. Fifty test cases is a chore. Five thousand is impossible.
  • It isn’t consistent. Two reviewers disagree on what “good” means, so the same output passes on Tuesday and fails on Thursday.

LLM outputs are probabilistic. The same prompt can return a correct answer, a hallucination, and a refusal across three runs. You cannot regression-test that with assertions on exact strings. You need a different tool: an evaluation metric that scores output quality on a scale, and a threshold that decides pass or fail. That is the whole job of a framework like DeepEval, and the rest of this article shows you how to use it.

One more reason to care now: the cost of a miss is asymmetric. A UI bug in a login form annoys a user. A hallucinated refund amount in a support bot creates a customer-service incident and a compliance headache. When the downside is that high, “a human read twenty samples last month” is not a quality process, it is a hope.

What Is DeepEval?

DeepEval is an open-source LLM evaluation framework built by Confident AI. It is Apache 2.0 licensed, Python first, and it plugs straight into Pytest, so a QA engineer who already writes Pytest suites can be productive in an afternoon. As of this writing the GitHub repository sits at roughly 17,500 stars and has been in active development since August 2023, with a TypeScript port now in public beta.

Three design decisions explain why I recommend it over rolling your own evaluation script:

  1. It is metric-driven, not prompt-driven. You don’t hand-write a grading prompt per test. You pick from 50+ ready-to-use metrics and attach a threshold.
  2. Every metric returns a score between 0 and 1 plus reasoning text, so a failing test tells you why it failed, not just that it failed.
  3. It is local-first. Evals run in your own environment and CI. You only touch the Confident AI cloud if you want shared dashboards and regression tracking later.

Under the hood, most built-in metrics use LLM-as-a-judge, meaning a model scores another model’s output using techniques like G-Eval, QAG (question-answer-generation), and DAG (directed acyclic graph) judging. You can read the full architecture in the official DeepEval introduction. The important part for you: you write a test case, pick a metric, set a threshold, and the framework produces a verdict. If you prefer to have your coding agent scaffold the suite for you, DeepEval also ships a vibe-coder quickstart for Cursor, Claude Code, Codex, and Windsurf, but I still recommend understanding the building blocks by hand first, because you will be the one debugging why a metric flips red.

Setting Up DeepEval in 5 Minutes

Create a fresh virtual environment and install the package. DeepEval supports Python 3.9 and above.

python -m venv .venv
source .venv/bin/activate
pip install -U deepeval

The latest release on PyPI is 4.1.8, following 4.1.7, which shipped on 29 July 2026 with the headline feature I cover later: a flaky flag for test cases and metrics. DeepEval plugs into Pytest, so running your eval files is the same as running tests:

deepeval test run

One setup decision you need to make early: which model does the judging. By default DeepEval uses OpenAI models for LLM-as-a-judge metrics, so set your key as an environment variable if you use that path. If you are offline or self-hosting, you can point the judge to a local model through Ollama or a custom LLM class. The docs cover the full matrix of judge configurations, and it matters because your metric is only as good as the model scoring it.

The Metrics That Matter When You Evaluate LLM Outputs

You don’t need all 50+ metrics on day one. For most teams moving into AI QA, four categories cover the majority of real work.

Correctness and relevance

  • Answer Relevancy measures whether the output actually addresses the question instead of drifting into padding.
  • G-Eval is the general-purpose judge: you define the criteria in plain English and it scores against them.

Hallucination and faithfulness

  • Faithfulness checks whether every claim in the output is supported by the context you supplied, flagging invented facts.
  • Hallucination does the inverse explicitly, scoring how much of the output contradicts the given context.

RAG quality

  • Contextual Relevancy, Contextual Precision, and Contextual Recall score the retrieval side: did you pull the right chunks, in the right order, without missing anything?

Safety and red teaming

  • Toxicity, Bias, and PII metrics catch content that should never ship, which is the part most “AI testing” tutorials skip.

The full list is on the metrics documentation page. My rule of thumb: start with Answer Relevancy plus Faithfulness for any text output, add the three contextual RAG metrics if retrieval is involved, and add one safety metric before anything touches production. You should also plan to add at least one custom metric, because your product has specific correctness rules no generic metric knows about.

Your First Passing Eval: Test Case, Metric, Threshold

A DeepEval test has three building blocks: the test case (what you are measuring), the metric (the ruler), and the threshold (the pass line). Here is a minimal, runnable example.

from deepeval import assert_test
from deepeval.metrics import AnswerRelevancyMetric, FaithfulnessMetric
from deepeval.test_case import LLMTestCase

test_case = LLMTestCase(
    input="What is the capital of France?",
    actual_output="The capital of France is Paris.",
    expected_output="Paris",
    retrieval_context=["Paris is the capital of France."],
)

assert_test(
    test_case,
    [
        AnswerRelevancyMetric(threshold=0.7),
        FaithfulnessMetric(threshold=0.7),
    ],
)

Three things happen when this runs. The metrics score the output on a 0 to 1 scale, the assertion passes only if every score meets or beats its threshold, and the test integrates with Pytest so it shows up in your normal test report. That last part matters more than it looks: it means your LLM evals live in the same pipeline as your API and UI tests, not in some separate notebook.

Thresholds and the New Flaky Flag in 4.1.7

Thresholds are where I see teams go wrong in both directions. Set a threshold too high and every minor phrasing change fails the suite. Set it too low and you ship garbage with a green checkmark. DeepEval defaults every metric to a 0.5 threshold, but for Faithfulness on customer-facing output I start at 0.8 and adjust from there. The threshold is a product decision, not a library default.

Version 4.1.7, released on 29 July 2026 under the title “Flaky tests? Skip the failures!”, added a flaky flag to both test cases and metrics. This is a direct response to the reality that LLM-as-a-judge scores are noisy: a case sitting right at the boundary can flip between pass and fail across runs for no reason related to your code. You can read the release notes on GitHub.

from deepeval.test_case import LLMTestCase

# Borderline case: keep tracking it, but don't let it block deploys.
test_case = LLMTestCase(
    input="Summarize this support ticket.",
    actual_output="Your account was charged for a duplicate order...",
    expected_output="Customer was double-charged; issue a refund.",
    flaky=True,
)

Here is the behavior you need to know. A flaky test case still gets scored and recorded, but when it fails, assert_test() prints a warning instead of raising an AssertionError, so it no longer blocks your pipeline. The flaky status is also logged to Confident AI so you can track how often those noisy cases actually fail. You can mark individual metrics as flaky too, and a flaky metric’s failure never decides the test case’s pass or fail status. The framework requires at least one non-flaky metric with a threshold per evaluation for exactly this reason.

The practical takeaway: use flaky=True on cases you know are noisy, not as a blanket excuse to hide real regressions. If a case is flaky often enough that you are ignoring it, that is a signal to fix the prompt or the test, not to silence it forever.

Custom Metrics with G-Eval

Generic metrics get you 80% of the way. The last 20% is your product’s specific definition of “correct,” and that is where G-Eval comes in. G-Eval lets you define a metric in plain English and have the judge model score against your criteria.

from deepeval.metrics import GEval
from deepeval.test_case import LLMTestCaseParams

correctness = GEval(
    name="Correctness",
    criteria="Determine whether the actual output is factually correct "
             "given the expected output, including numeric values and units.",
    evaluation_params=[
        LLMTestCaseParams.ACTUAL_OUTPUT,
        LLMTestCaseParams.EXPECTED_OUTPUT,
    ],
    threshold=0.6,
)

assert_test(test_case, [correctness])

G-Eval uses chain-of-thought reasoning to produce the score, which makes it more reliable than a naive “is this right?” prompt, at the cost of more tokens per evaluation. For a QA team that means: use G-Eval where correctness is nuanced and worth the spend, and lean on the cheaper built-in metrics everywhere else. If you need a fully deterministic check, you can also write a 100% self-coded metric and plug in BLEU or ROUGE, which the docs show how to do.

How to Evaluate LLM Outputs from RAG and AI Agents

Two workloads make up most of what QA teams now own: retrieval-augmented generation pipelines and agentic workflows. DeepEval handles both, but the test case shape changes.

For RAG, you supply the retrieval_context (what the retriever actually returned) and the context (the gold-standard chunks), then attach the contextual metrics. A failing Contextual Recall score means your retriever missed relevant documents. A failing Faithfulness score means the generator invented something. Separating those two lets you debug which half of the pipeline broke, which is the difference between a useful test and a red herring.

For agents, DeepEval uses trajectory-based metrics that score the complete ordered trace of the agent’s steps, tool calls, and outputs, rather than a single final answer. That matters because an agent can reach the right final answer through the wrong tools, and you want to catch that. The docs group these under agentic and multi-turn metrics, including task completion and tool correctness, and they pair with the tracing view in Confident AI when you need to diagnose why an agent drifted.

Two supporting features round out the framework for serious teams. First, synthetic data generation: the Golden Synthesizer and Conversation Simulator can create edge-case and multi-turn test datasets from your existing examples, which solves the classic “we only have five golden cases” problem. Second, benchmarks: DeepEval ships a set of standardized benchmarks like HellaSwag and MMLU, which are more useful for comparing models than for gating a specific product feature. For regression work on your own app, spend your energy on the golden dataset, not on benchmark leaderboards.

If you are coming from browser and API automation, think of it this way: a trajectory metric is to an agent what a full user journey test is to a single endpoint check. You need both, but the journey is where the real bugs live.

Running LLM Evals in CI/CD

An eval that only runs on a developer laptop is a nice demo. An eval that runs in CI is a regression suite. Because DeepEval plugs into Pytest, wiring it into your pipeline is mostly a matter of adding one step.

# In a GitHub Actions workflow
- name: Run LLM evals
  env:
    OPENAI_API_KEY: ${{ secrets.OPENAI_API_KEY }}
  run: deepeval test run

Two things make this worth doing properly. First, pin your judge model version in CI, because an unversioned judge can change scores between runs and create the very flakiness the 4.1.7 flag was built to manage. Second, treat your eval suite like any other test suite: keep it fast enough to run on every pull request, and fail the build when a non-flaky metric drops below threshold. A team that gates an LLM release on evals the way it gates a UI release on Playwright specs is a team that stops shipping regressions silently. The pattern is the same one you already know from functional automation: shift the check left, run it on every change, and make failure visible in the same dashboard the rest of the team already watches.

If you want to see how this thinking extends to the rest of the AI testing surface, I wrote a separate guide on triaging AI test failures in Playwright teams, and another on prompt injection testing for AI features.

The Traps I See Teams Hit

After watching a few dozen teams adopt LLM evals, these are the mistakes that show up on repeat.

  1. Judging with the same model that generated the output. A weak judge rubber-stamps its own mistakes. Use a stronger or independent judge for the metric.
  2. No gold dataset. Evals without curated expected outputs just measure vibes. Invest the time in a small, high-quality golden set.
  3. Thresholds copied from a tutorial. The 0.5 default is a starting point, not your product’s standard. Tune it against cases your team has already reviewed.
  4. Only testing the happy path. Add adversarial and out-of-scope inputs. Real users ask weird questions.
  5. Silencing flaky cases instead of fixing them. The flaky flag is for borderline noise, not for known-broken behavior you have given up on.

What This Means for QA Careers in India

I run The Testing Academy and talk to hiring managers across Bengaluru, Pune, and Hyderabad every week. The shift is already visible: job descriptions for SDET roles at product companies now list “LLM evaluation” and tools like DeepEval or PromptFoo next to Playwright and Selenium. Companies are not hiring a separate “AI tester.” They are hiring testers who can write a metric, set a threshold, and wire an eval into CI.

For a mid-level QA engineer in India, that is a concrete, low-cost skill to add. DeepEval is free, open source, and Python, which you likely already know if you have touched automation. An engineer who can show a GitHub repo with a working eval suite for a small RAG or agent project stands out from the crowd that only has “prompt engineering” on their resume. The salary angle is real too: AI-augmented SDET roles in product companies are routinely posting at the upper end of the automation pay band, in the range where a strong automation engineer with LLM evaluation experience can push past the 30 LPA mark in a way that pure manual or pure UI automation rarely does. The real advantage is owning quality for the features the company is actually betting on.

Key Takeaways

  • To evaluate LLM outputs properly, you turn “looks fine” into a score, a threshold, and a CI gate, not hand-reading a handful of responses.
  • DeepEval is a free, Apache 2.0, Python framework with 50+ metrics that plugs into Pytest and runs locally.
  • A test has three parts: test case, metric, and threshold. Every metric scores 0 to 1 and explains its reasoning.
  • Start with Answer Relevancy and Faithfulness, add contextual RAG metrics and one safety metric before production.
  • Version 4.1.7 added a flaky flag so noisy cases stop blocking CI while staying tracked.
  • Use G-Eval for your product’s specific correctness rules, and run the whole suite in CI like any regression suite.

FAQ

Is DeepEval free to use?

Yes. The core framework is open source under the Apache 2.0 license. The paid Confident AI platform is optional and only needed for shared dashboards, tracing, and production monitoring.

Do I need an OpenAI key to use DeepEval?

For the default LLM-as-a-judge metrics, yes, you need a judge model. You can use OpenAI, or point DeepEval at a self-hosted model through Ollama or a custom LLM class. Deterministic self-coded metrics do not need a judge at all.

How is DeepEval different from PromptFoo?

Both are evaluation frameworks. DeepEval is Python and Pytest native with a strong focus on metric thresholds and agent trajectory evals. PromptFoo is often favored for declarative, YAML-defined test cases. I compared the broader space in DeepEval vs Ragas, which is a good companion read.

What threshold should I start with?

Start with the 0.5 default, then tune against cases your own team has reviewed. For customer-facing faithfulness and correctness, I typically land between 0.7 and 0.85.

Can I run evals without a test framework?

You can run single evals in a script, but the whole point is regression protection, so wire it into Pytest and your CI pipeline from the start.

Similar Posts

Leave a Reply

Your email address will not be published. Required fields are marked *

This site uses Akismet to reduce spam. Learn how your comment data is processed.