💥 Introducing JevEval: Jev-as-a-Judge for LLM evaluation. Read the post →
Others

Prompt Alignment

LLM-as-a-judge
Jev-as-a-judge
Single-turn
Referenceless
Multimodal

The prompt alignment metric uses LLM-as-a-judge to measure whether your LLM application is able to generate actual_outputs that aligns with any instructions specified in your prompt template. deepeval's prompt alignment metric is a self-explaining LLM-Eval, meaning it outputs a reason for its metric score.

Required Arguments

To use the PromptAlignmentMetric, you'll have to provide the following arguments when creating an LLMTestCase:

  • input
  • actual_output

Read the How Is It Calculated section below to learn how test case parameters are used for metric calculation.

Usage

First, set the eval mode:

deepeval set-eval-mode llm         # LLM-as-a-judge (default)
deepeval set-eval-mode hybrid      # LLM extracts, Jev decides
deepeval set-eval-mode system_one  # Jev-as-a-judge, no LLM

The PromptAlignmentMetric() can be used for end-to-end evaluation:

from deepeval.metrics import PromptAlignmentMetric
from deepeval.test_case import LLMTestCase
from deepeval import evaluate

metric = PromptAlignmentMetric(
    prompt_instructions=["Reply in all uppercase"],
    model="gpt-4",
    include_reason=True
)
test_case = LLMTestCase(
    input="What if these shoes don't fit?",
    # Replace this with the actual output from your LLM application
    actual_output="We offer a 30-day full refund at no extra cost."
)

# To run metric as a standalone
# metric.measure(test_case)
# print(metric.score, metric.reason)

evaluate(test_cases=[test_case], metrics=[metric])

There are ONE mandatory and NINE optional parameters when creating an PromptAlignmentMetric:

  • prompt_instructions: a list of strings specifying the instructions you want followed in your prompt template.
  • [Optional] threshold: a number representing the minimum passing threshold. Can also be set to None to run the metric in score-only mode. Defaulted to 0.5.
  • [Optional] model: a string specifying which of OpenAI's GPT models to use, OR any custom LLM model of type DeepEvalBaseLLM. Defaulted to gpt-5.4.
  • [Optional] include_reason: a boolean which when set to True, will include a reason for its evaluation score. Defaulted to True.
  • [Optional] strict_mode: a boolean which when set to True, enforces a binary metric score: 1 for perfection, 0 otherwise. It also overrides the current threshold and sets it to 1. Defaulted to False.
  • [Optional] async_mode: a boolean which when set to True, enables concurrent execution within the measure() method. Defaulted to True.

  • [Optional] verbose_mode: a boolean which when set to True, prints the intermediate steps used to calculate said metric to the console, as outlined in the How Is It Calculated section. Defaulted to False.
  • [Optional] flaky: a boolean which when set to True, marks the metric as flaky. Defaulted to False.
  • [Optional] system_one_model: the Jev model to use, as a string or a DeepEvalBaseSystemOneModel. Only used under hybrid or system_one eval_mode. Defaulted to jev-latest.
  • [Optional] eval_mode: llm, hybrid or system_one, choosing whether an LLM, Jev, or both judge. Defaulted to the configured eval mode (llm unless set).

Within components

You can also run the PromptAlignmentMetric within nested components for component-level evaluation.

from deepeval.dataset import EvaluationDataset, Golden
from deepeval.tracing import observe, update_current_span
...

@observe(metrics=[metric])
def inner_component():
    # Set test case at runtime
    test_case = LLMTestCase(input="...", actual_output="...")
    update_current_span(test_case=test_case)
    return

@observe
def llm_app(input: str):
    # Component can be anything from an LLM call, retrieval, agent, tool use, etc.
    inner_component()
    return

dataset = EvaluationDataset(goldens=[Golden(input="Hi!")])
for golden in dataset.evals_iterator():
    llm_app(golden.input)

As a standalone

You can also run the PromptAlignmentMetric on a single test case as a standalone, one-off execution.

...

metric.measure(test_case)
print(metric.score, metric.reason)

How Is It Calculated?

You can change how the PromptAlignmentMetric is calculated by setting the eval mode.

LLM-as-a-judge

The PromptAlignmentMetric score is calculated according to the following equation:

Prompt Alignment=Number of Instructions FollowedTotal Number of Instructions\text{Prompt Alignment} = \frac{\text{Number of Instructions Followed}}{\text{Total Number of Instructions}}

The PromptAlignmentMetric uses an LLM to classify whether each prompt instruction is followed in the actual_output using additional context from the input.

Hybrid

Under the hybrid eval mode, the classification is answered by Jev, a System One model, instead: one yes/no question per instruction, with P(yes) >= 0.5 counted as followed. The equation and the reason are unchanged. If a Jev call fails, the LLM makes that decision instead.

Jev-as-a-judge

Under the system_one eval mode, Jev judges the whole metric in one request. It is sent the raw input and actual_output and asked one question per entry in prompt_instructions, so the score is the share of instructions followed, weighted by how confidently each holds:

QuestionTypeWeight
actual_output completely follows this prompt instruction when responding to input: <instruction>Noul1

One row per instruction; each instruction's text is written into its question.

Each answer becomes a value in [0,1][0, 1] and the score is their weighted mean. No LLM is called: the reason lists each answer with its probability, and metric.confidence reports how decisive Jev was.

FAQs

Why do I pass prompt instructions separately instead of the full prompt template?
A full template mixes instructions with examples and formatting, making the judge less reliable. Listing only the prompt_instructions you want obeyed lets the metric score each one cleanly and pinpoint which was followed or ignored.
How do I find out which specific instruction was violated?
Keep include_reason=True (default) for a reason naming the failed instructions, or set verbose_mode=True for the per-instruction classification. Splitting bundled instructions into separate entries isolates the offender.
Should each prompt instruction be a single rule or can I bundle several?
One atomic rule per entry. Each item in prompt_instructions is classified as followed or not, so bundling (e.g. "uppercase and under 20 words") forces an all-or-nothing verdict and hides which half failed.
What does a score of 1.0 actually mean here?
Every instruction in prompt_instructions was followed in the actual_output — but only the ones you listed are evaluated. strict_mode forces this same binary 1-or-0 outcome and sets the threshold to 1.

On this page