Model-backed judges¶
A model-backed judge asks one model to score another output. It can make review cheaper and repeatable, but it does not turn a subjective model response into ground truth.
The repository contains two separate judge systems:
| System | Location | Purpose |
|---|---|---|
Runtime LLMJudge |
agentic_v2/scoring/judge.py |
Score a workflow result against anchored criteria |
| Evaluation-package evaluators | agentic_v2_eval/evaluators/ |
Score choices, quality dimensions, prompts, and named reasoning patterns |
The agentic-v2-eval evaluate CLI does not call these judges. That command
applies a numeric YAML rubric to values already present in a JSON file.
Runtime judge¶
LLMJudge accepts:
- a candidate output;
- an optional expected output;
- one or more criteria with names, definitions, and 1–5 anchors; and
- an optional second candidate for an order-consistency check.
It requires a configured runtime model client or an injected
response_provider.
from agentic_v2.scoring.judge import LLMJudge
def fixed_response(**_):
return {
"criteria": [
{
"name": "correctness",
"score": 4,
"evidence": "The required behavior is present.",
}
]
}
judge = LLMJudge(
model="test:fixed",
model_version="fixed-1",
response_provider=fixed_response,
)
result = judge.evaluate(
candidate_output="The implementation returns a sorted copy.",
expected_output="Return a sorted copy without changing the input.",
criteria=[
{
"name": "correctness",
"definition": "Does the output meet the requirement?",
"scale": {
"1": "Does not meet it",
"3": "Partly meets it",
"5": "Fully meets it",
},
}
],
)
print(result.normalized_score)
The judge:
- shuffles criterion order from a stable seed;
- requests strict JSON;
- rejects missing, duplicate, unexpected, or out-of-range criterion results;
- normalizes 1–5 scores to
0.0–1.0; and - returns the mean normalized score.
When pairwise_reference_output is supplied, the judge evaluates both
presentation orders. It reports criteria whose raw scores differ by more than
the configured consistency tolerance. This checks order sensitivity; it does
not prove either candidate is correct.
The result records the judge model, model version, prompt version, temperature, criterion evidence, and pairwise consistency fields.
Evaluation-package judges¶
All evaluation-package judges receive an injected client that implements
generate_text(...). Provider setup stays outside the package.
LLMEvaluator¶
LLMEvaluator maps a judge response to caller-defined choices:
from agentic_v2_eval.evaluators import (
LLMEvaluator,
STANDARD_CHOICES,
)
class FixedClient:
def generate_text(self, **_):
return "4"
evaluator = LLMEvaluator(
model_id="test:fixed",
system_prompt="Score the response from 1 to 5.",
prompt_template="Response:\n{{completion}}\n\nScore:",
choices=STANDARD_CHOICES,
llm_client=FixedClient(),
seed=0,
)
result = evaluator.evaluate("A complete response")
print(result["score"]) # 0.75
The built-in choices map 1, 2, 3, 4, and 5 to 0.0, 0.25,
0.5, 0.75, and 1.0. Choice matching checks the last lines of the
response. Write prompts that require only the choice label on the final line.
QualityEvaluator¶
QualityEvaluator loads five definitions from quality.yaml:
COHERENCEFLUENCYRELEVANCEGROUNDEDNESSSIMILARITY
Call evaluate(definition, inputs, output, model_override=None). It returns a
single normalized float. A provider or parse failure returns 0.0, so preserve
logs if you need to distinguish a failed judge call from a low score.
StandardEvaluator¶
StandardEvaluator.score_prompt() evaluates prompt clarity, effectiveness,
structure, specificity, and completeness. It returns StandardScore on a
0–10 scale.
score = evaluator.score_prompt(
prompt_name="reviewer",
prompt_content=prompt_text,
model="gh:gpt-4o",
runs=1,
temperature=0.1,
)
The default is one run. When runs is greater than one, the evaluator takes
the median for each dimension.
PatternEvaluator¶
PatternEvaluator.score_pattern() checks one of the patterns defined in
prompt_pattern.yaml: react, cove, reflexion, or rag.
It returns a PatternScore containing universal scores, pattern-specific
scores, hard-gate results, parse success counts, and judge metadata. The
default is one run.
Using judge scores responsibly¶
- Keep the judge prompt and model version with the result.
- Calibrate against human-scored examples from the intended domain.
- Use more than one run when score variance matters.
- Test position, verbosity, and style bias.
- Treat parse failures and provider failures separately from low-quality answers.
- Do not use a judge score as the only approval for a high-impact action.
- Do not claim the judge exposes or audits a model's private reasoning.
The runtime server exposes recorded evaluation data at
GET /api/runs/{filename}/evaluation. See production
gating for how runtime scores become pass or fail decisions.