EvaluationSep 13, 20265 min read

DeepEval: Engineering Pytest-Native Evals and G-Eval Metrics in CI/CD

Explore how DeepEval combines Pytest-native assertions, G-Eval LLM-as-a-judge metrics, and trajectory tracing to block quality regressions in CI/CD.

Documentation & analysis · 5 source links

DeepEval G-Eval Metric Execution Flow

Loading diagram…

Illustrates how DeepEval converts plain-language evaluation criteria into deterministic evaluation steps, executes LLM judging, and applies log-probability token weighting.

Key Takeaways

  • Pytest-Native Assertion Harness: DeepEval wraps LLM evaluation into familiar Pytest workflows, allowing engineering teams to run evaluation suites via deepeval test run directly inside CI/CD pipelines.
  • Research-Backed G-Eval Metrics: DeepEval implements G-Eval, an LLM-as-a-judge algorithm using Chain-of-Thought (CoT) step generation and log-probability token weighting to generate continuous quality scores (0.0 to 1.0).
  • End-to-End & Trajectory Tracing: Supports both black-box output scoring and component-level tracing across multi-step agent decisions, retrieval-augmented generation (RAG) contexts, and tool execution calls.
  • Operational Tradeoff: While LLM-as-a-judge metrics closely mirror human criteria, running LLM calls for every metric introduces API latency and cost, necessitating metric optimization and caching for large test suites.

The Problem: Preventing Silent Quality Regressions in LLM Workflows

Deploying software powered by Large Language Models introduces non-deterministic failure modes that standard unit tests cannot detect. Modifying a system prompt, swapping base models (e.g., transitioning from OpenAI to Claude), or adjusting retrieval parameters can inadvertently cause hallucination, prompt drift, or degraded agent execution steps.

Without continuous evaluation built into CI/CD, teams rely on manual spot-checking or delayed production feedback. DeepEval addresses this challenge by providing an open-source Python framework that structures LLM testing as Pytest test cases, enabling automated quality gates prior to production deployment.


Core Architecture: How G-Eval Achieves Consistent LLM-as-a-Judge Scoring

Traditional statistical metrics such as BLEU and ROUGE fail on open-ended generation tasks because they measure exact n-gram overlap rather than semantic correctness. DeepEval implements the G-Eval framework (Liu et al.), which structures subjective evaluation through a three-stage execution pattern:

  1. Auto-CoT Step Generation: The evaluation criteria (written in plain English) is first converted by an LLM into a structured list of intermediate evaluation steps.
  2. Form-Filling Judgment: The LLM judge evaluates the test case parameters (input, actual_output, expected_output, retrieval_context) against each generated step.
  3. Log-Probability Weighting: Instead of relying purely on unweighted categorical outputs, DeepEval calculates scores using token-level log probabilities to produce continuous, fine-grained metrics between 0.0 and 1.0.

According to research documented by Confident AI, G-Eval achieved a Spearman correlation of 0.514 with human judgments on text summarization tasks, outperforming baseline evaluators like BERTScore and GPTScore.

This means that for teams evaluating open-ended agent outputs or RAG pipelines, G-Eval offers substantially higher alignment with human evaluation than legacy n-gram scoring. Furthermore, developers can override probabilistic step generation by supplying explicit, hardcoded evaluation steps directly in Python, eliminating runtime randomness in metric setup.


Implementing Pytest-Native Unit Tests with DeepEval

DeepEval integrates directly with Python's standard pytest runner. Below is a documented example of defining a black-box test case using the GEval metric and enforcing a passing score threshold.

import pytest
from deepeval import assert_test
from deepeval.metrics import GEval
from deepeval.test_case import LLMTestCase, SingleTurnParams

def test_support_chatbot_correctness():
    # 1. Instantiate the research-backed G-Eval metric
    correctness_metric = GEval(
        name="Correctness",
        criteria="Determine whether the 'actual output' is factually correct based on the 'expected output'.",
        evaluation_params=[
            SingleTurnParams.ACTUAL_OUTPUT, 
            SingleTurnParams.EXPECTED_OUTPUT
        ],
        threshold=0.5
    )
    
    # 2. Define the test case container
    test_case = LLMTestCase(
        input="What if these shoes don't fit?",
        actual_output="You have 30 days to get a full refund at no extra cost.",
        expected_output="We offer a 30-day full refund at no extra costs.",
        retrieval_context=["All customers are eligible for a 30 day full refund at no extra costs."]
    )
    
    # 3. Assert metric compliance within Pytest
    assert_test(test_case, [correctness_metric])

To execute the test suite from the terminal or a GitHub Actions runner:

deepeval test run test_chatbot.py

When assert_test runs, DeepEval evaluates the test case against the configured metrics. If the calculated score falls below the threshold=0.5, the test raises an assertion failure, enabling automated CI/CD runners to halt deployment.


Agent Trajectory Tracing & Component-Level Evals

Evaluating end-to-end outputs is essential for verifying business requirements, but complex agentic systems require component-level visibility. DeepEval supports trajectory-based evaluations across multi-step execution flows using @observe() decorators or native framework integrations (e.g., LangChain, LlamaIndex, CrewAI, and OpenAI Agents).

from deepeval.tracing import observe, update_current_span
from deepeval.test_case import LLMTestCase
from deepeval.metrics import TaskCompletionMetric

@observe()
def retrieval_component(query: str):
    context = ["Doc 1: Refund policy details..."]
    update_current_span(test_case=LLMTestCase(input=query, actual_output=str(context)))
    return context

@observe()
def agent_workflow(user_input: str):
    context = retrieval_component(user_input)
    return "Agent final response"

For a team operating autonomous agents with tool calls and multi-turn routing, this architecture allows metrics like TaskCompletionMetric or ToolCorrectness to grade individual execution spans rather than treating the agent as an opaque system.


Metric-Outcome Fit (MOF) and Operational Tradeoffs

While LLM-as-a-judge evaluators align with human judgment approximately 81% of the time (Confident AI Playbook), naive adoption can introduce operational overhead:

  1. Evaluation Latency & API Cost: Running G-Eval across hundreds of test cases requires underlying LLM inference. To mitigate cost in large datasets, DeepEval supports concurrent execution, local NLP metrics (e.g., exact JSON schema match, toxicity), and result caching.
  2. Establishing Metric-Outcome Fit: Engineering teams must validate that evaluation pass rates directly correlate with production business outcomes (such as ticket resolution rates or user retention). The recommended methodology is starting with 25–50 human-labeled ground truth cases, calculating false positive and false negative rates (<5% combined target), and tuning metric criteria before scaling test sets.
  3. Platform Persistence: DeepEval operates entirely locally as an open-source library, but offers optional integration with Confident AI for cloud persistence, production observability, and web-based annotation queues.

Sources

Source-reported benchmarks

Results reported in the linked sources; compare their workloads and conditions before applying them to your deployment.

Spearman Correlation with Human Judgment (Text Summarization)0.51 correlation coefficient

G-Eval performance on text summarization benchmarks reported by Liu et al. (cited in Confident AI G-Eval Guide)

Source
Base Human Judgment Alignment Rate81 %

Reported baseline alignment rate of LLM-as-a-judge evaluators compared with human evaluators

Source

Keep exploring

Evaluation & debugging: questions, tradeoffs, and guides →

Browse all reports · Suggest a correction