Scorers¶
scorers
¶
Scorers: pluggable pass/fail checks.
Ships ResultSetEquivalence, ExpectationSuiteScorer, SemanticEquivalence, and the
LLM-as-judge LlmJudge, plus the FirstDecisive combinator and the equivalence-preset
compositions it powers.
Scorer
¶
Bases: Protocol
Produces a ScoreResult from a case, its solver output, and the execution result.
score
¶
score(
case: EvalCase,
output: SolverOutput,
result: ExecutionResult,
*,
context: ScoreContext,
) -> ScoreResult
Decide pass/fail with diagnostics for case given output, result, and context.
FirstDecisive
¶
FirstDecisive(scorers: Sequence[Scorer])
Runs member scorers in order; the first that decides wins, else the last result stands.
The combinator continues only while a member is inconclusive; the first member to return a
decisive verdict (pass or fail) is returned immediately, so a later member cannot override
an earlier one's decision. If every member is inconclusive, the last member's result is
returned, so its diagnostics (e.g. a diff) surface.
Bind the combinator to an ordered list of member scorers.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
scorers
|
Sequence[Scorer]
|
The member scorers, in priority order. |
required |
Raises:
| Type | Description |
|---|---|
ValueError
|
If |
score
¶
score(
case: EvalCase,
output: SolverOutput,
result: ExecutionResult,
*,
context: ScoreContext,
) -> ScoreResult
Run members in order, returning the first decisive result (later members not consulted), else the last.
The returned result carries a metadata["first_decisive"] trail of
{"scorer", "passed", "verdict"} for each member that actually ran.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
case
|
EvalCase
|
The eval case, forwarded to each member. |
required |
output
|
SolverOutput
|
The solver output, forwarded to each member. |
required |
result
|
ExecutionResult
|
The executed model result, forwarded to each member. |
required |
context
|
ScoreContext
|
The score context, forwarded to each member. |
required |
Returns:
| Type | Description |
|---|---|
ScoreResult
|
The first decisive member's |
ScoreResult
|
member's result when every member is |
ScoreResult
|
merged into its metadata. |
ScoreContext
dataclass
¶
ScoreContext(queries: QueryRunner)
Per-case capabilities injected into Scorer.score.
Attributes:
| Name | Type | Description |
|---|---|---|
queries |
QueryRunner
|
The budget-aware runner for derived SQL against the case's platform. |
ExecutionAccuracy
¶
ExecutionAccuracy(
*,
row_order: Literal[
"when_ordered", "ignore"
] = "when_ordered",
multiplicity: Literal["multiset", "set"] = "multiset",
column_alignment: Literal[
"by_position", "by_value"
] = "by_position",
)
Scores a case by execution accuracy: does the model's SQL return the gold query's rows?
Configure the comparison semantics.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
row_order
|
Literal['when_ordered', 'ignore']
|
|
'when_ordered'
|
multiplicity
|
Literal['multiset', 'set']
|
|
'multiset'
|
column_alignment
|
Literal['by_position', 'by_value']
|
|
'by_position'
|
score
¶
score(
case: EvalCase,
output: SolverOutput,
result: ExecutionResult,
*,
context: ScoreContext,
) -> ScoreResult
Compare the model result against the gold query's executed rows.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
case
|
EvalCase
|
The eval case; its |
required |
output
|
SolverOutput
|
The solver output (part of the |
required |
result
|
ExecutionResult
|
The executed model result to score. |
required |
context
|
ScoreContext
|
The score context, carrying the budget-aware |
required |
Returns:
| Type | Description |
|---|---|
ScoreResult
|
A passing |
ScoreResult
|
configured semantics, else a failing one carrying a |
ScoreResult
|
query, or a failed gold query ( |
ScoreResult
|
result with an explanation. |
Raises:
| Type | Description |
|---|---|
TypeError
|
If |
ExpectationSuiteScorer
¶
Scores a case by checking its executed result against each Expectation in its suite.
score
¶
score(
case: EvalCase,
output: SolverOutput,
result: ExecutionResult,
*,
context: ScoreContext,
) -> ScoreResult
Evaluate every expectation in the suite; pass iff all hold.
Row-level checks (row_count, not_null, unique) are pushed into the platform as
SQL over the model's query via context.queries; only counts and bounded failing-row
samples are read back. Schema checks (column_presence, column_type) read the
result's schema metadata and run no query.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
case
|
EvalCase
|
The eval case, carrying the |
required |
output
|
SolverOutput
|
The solver output (part of the |
required |
result
|
ExecutionResult
|
The executed result; its schema is used by the schema checks. |
required |
context
|
ScoreContext
|
The score context, carrying the budget-aware |
required |
Returns:
| Type | Description |
|---|---|
ScoreResult
|
A |
ScoreResult
|
|
ScoreResult
|
|
ScoreResult
|
model query yields a failing result with an explanation and no outcomes; a failed |
ScoreResult
|
derived query fails only its own expectation's outcome. |
Raises:
| Type | Description |
|---|---|
TypeError
|
If |
JudgeExample
¶
Bases: BaseModel
A few-shot anchor: a graded output and the score it should receive.
input and expected_output are optional context; only the fields that are present are
rendered into the prompt.
LlmJudge
¶
LlmJudge(
*,
model: str | Llm,
criteria: str,
steps: Sequence[str] | None = None,
examples: Sequence[JudgeExample] | None = None,
rubric: Sequence[RubricBand] | None = None,
threshold: float = 0.5,
temperature: float | None = 0.0,
timeout: float | None = None,
show: Sequence[JudgeField] | None = None,
)
LLM-as-judge Scorer: a grader model scores the case against authored criteria.
The grader's 0-1 score is compared to a threshold for the pass/fail verdict; the score and rationale are recorded. A provider failure or a malformed reply yields an inconclusive result.
Configure the judge.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
model
|
str | Llm
|
A litellm grader-model identifier (separate from any solver model), or an
|
required |
criteria
|
str
|
The natural-language standard the grader scores the case against. |
required |
steps
|
Sequence[str] | None
|
Ordered evaluation steps the grader should work through, rendered as a numbered block. Omitted from the prompt when absent. |
None
|
examples
|
Sequence[JudgeExample] | None
|
Few-shot anchors mapping graded outputs to scores. Omitted from the prompt when absent. |
None
|
rubric
|
Sequence[RubricBand] | None
|
Scoring bands that describe what each score range means. Omitted from the prompt when absent. |
None
|
threshold
|
float
|
The minimum score (inclusive) for a passing verdict. Defaults to |
0.5
|
temperature
|
float | None
|
Sampling temperature; |
0.0
|
timeout
|
float | None
|
Per-request timeout in seconds. |
None
|
show
|
Sequence[JudgeField] | None
|
The case fields to offer the grader, each included only when available.
Defaults to all of |
None
|
score
¶
score(
case: EvalCase,
output: SolverOutput,
result: ExecutionResult,
*,
context: ScoreContext,
) -> ScoreResult
Grade case with the grader model and return a graded ScoreResult.
Builds a prompt from the criteria and the selected available fields, calls the grader, and maps its score to a verdict against the threshold.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
case
|
EvalCase
|
The eval case, supplying the input and (optionally) the expected output. |
required |
output
|
SolverOutput
|
The solver output (part of the |
required |
result
|
ExecutionResult
|
The executed model result (part of the |
required |
context
|
ScoreContext
|
The score context, supplying the model's SQL. |
required |
Returns:
| Type | Description |
|---|---|
ScoreResult
|
A |
ScoreResult
|
or inconclusive when no verdict could be reached. |
RubricBand
¶
Bases: BaseModel
A scoring band: a [min_score, max_score] range and what it describes.
QueryRunner
¶
QueryRunner(
adapter: PlatformAdapter,
model_sql: Sql,
dialect: Dialect,
budget: float | None,
)
Runs derived SQL against a case's platform, drawing on a shared cost budget.
Holds a live adapter, the model's SQL, the case dialect, and a remaining-time pool
seeded from the case budget. Each completed query decrements the pool by its
latency_seconds; once the pool is exhausted, further runs short-circuit to an
ExecutionResult carrying an error without touching the adapter. A None budget means
the pool is unbounded.
Bind the runner to a platform and seed its budget pool.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
adapter
|
PlatformAdapter
|
The platform adapter derived queries execute against. |
required |
model_sql
|
Sql
|
The model's SQL. |
required |
dialect
|
Dialect
|
The SQLGlot dialect derived queries are built and rendered in. |
required |
budget
|
float | None
|
The shared remaining-time pool in seconds, or |
required |
run
¶
run(sql: Sql) -> ExecutionResult
Run sql within the remaining budget, decrementing the pool by its latency.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
sql
|
Sql
|
The SQL statement to execute. |
required |
Returns:
| Type | Description |
|---|---|
ExecutionResult
|
The adapter's |
ExecutionResult
|
the budget pool is already exhausted (the adapter is not invoked in that case). |
scalar
¶
scalar(sql: Sql) -> ScalarResult
Run sql and read back its single cell, or an error.
Delegates to run, so the budget pool is drawn exactly as for any derived query.
An underlying error is propagated; a result that is not exactly one row by one
column is itself an error.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
sql
|
Sql
|
The SQL statement to execute; expected to return one row and one column. |
required |
Returns:
| Type | Description |
|---|---|
ScalarResult
|
A |
resolved_schema
¶
resolved_schema(
base: TypedSchema, sql: Sql
) -> TypedSchema | ExecutionError
Return base with its column types resolved to the platform's precise types.
Backends that already report precise types return base unchanged; otherwise the
adapter's type probe runs through this runner (drawing on the same budget) and its
types align to base's columns by position, preserving names and nullability.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
base
|
TypedSchema
|
The schema whose column types to resolve, as |
required |
sql
|
Sql
|
The statement that produced |
required |
Returns:
| Type | Description |
|---|---|
TypedSchema | ExecutionError
|
|
ScalarResult
dataclass
¶
ScalarResult(
value: Any | None,
error: ExecutionError | None,
latency_seconds: float,
)
The single cell returned by a derived query, or an error.
Attributes:
| Name | Type | Description |
|---|---|---|
value |
Any | None
|
The single cell value, or |
error |
ExecutionError | None
|
The failure, or |
latency_seconds |
float
|
Wall-clock time the underlying query took. |
ResultSetEquivalence
¶
Scores a case by diffing its executed result set against its expected result set in SQL.
score
¶
score(
case: EvalCase,
output: SolverOutput,
result: ExecutionResult,
*,
context: ScoreContext,
) -> ScoreResult
Compare result against case.expected; pass iff the engine finds them equivalent.
Column reconciliation and type comparison run in Python; row equivalence is pushed
into the platform. For authored rows the expected side is materialised as typed
literals; for a GoldQuery it is the reference query embedded as a subquery, whose
schema is discovered with a zero-row execution and whose rows never reach Python.
With an empty match_key, two EXCEPT ALL diffs compute the bag difference (and
null_equality="distinct" is rejected). With a non-empty match_key, a
FULL OUTER JOIN aligns rows on the key and compares per column — supporting
null_equality="distinct", an exact tolerance band, and per-column mismatch counts.
Only mismatch counts and bounded samples are read back.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
case
|
EvalCase
|
The eval case, carrying the expected result set, comparison config, and platform. |
required |
output
|
SolverOutput
|
The solver output (part of the |
required |
result
|
ExecutionResult
|
The executed result to compare against the expectation. |
required |
context
|
ScoreContext
|
The score context, carrying the budget-aware |
required |
Returns:
| Type | Description |
|---|---|
ScoreResult
|
A |
ScoreResult
|
model query, a failed gold query, a failed derived query, a non-unique or absent |
ScoreResult
|
|
ScoreResult
|
with an explanation. |
Raises:
| Type | Description |
|---|---|
TypeError
|
If |
AstEquivalence
¶
Confirms equivalence when both queries normalize to the same SQLGlot syntax tree.
Matching normalized trees yield "equivalent"; anything else (trees differ, a parse
failure, or input that is not exactly one statement) yields "unknown", never a
refutation. The normalization is schema-free: it fully reassociates commutative
arithmetic (+/*), boolean/bitwise chains, and IN-list order; other unhandled
equivalences fall through as "unknown".
judge
¶
judge(
case: EvalCase,
output: SolverOutput,
result: ExecutionResult,
*,
context: ScoreContext,
) -> SemanticVerdict
Compare the model and gold queries' normalized syntax trees.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
case
|
EvalCase
|
The eval case; |
required |
output
|
SolverOutput
|
The solver output (unused). |
required |
result
|
ExecutionResult
|
The executed model result (unused; this check touches no data). |
required |
context
|
ScoreContext
|
The score context, supplying the model SQL and dialect. |
required |
Returns:
| Type | Description |
|---|---|
SemanticVerdict
|
|
EquivalenceCheck
¶
Bases: Protocol
One way of confirming equivalence by comparing the queries, not their results; never raises.
A check confirms equivalence ("equivalent") or returns "unknown"; it never refutes, so
it cannot falsely reject a correct query.
judge
¶
judge(
case: EvalCase,
output: SolverOutput,
result: ExecutionResult,
*,
context: ScoreContext,
) -> SemanticVerdict
Judge whether the model's query is equivalent to the case's gold query.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
case
|
EvalCase
|
The eval case, whose |
required |
output
|
SolverOutput
|
The solver output. |
required |
result
|
ExecutionResult
|
The already-executed model result (reused by execution-based checks). |
required |
context
|
ScoreContext
|
The score context, carrying the model SQL, dialect, and query runner. |
required |
Returns:
| Type | Description |
|---|---|
SemanticVerdict
|
A |
SemanticEquivalence
¶
SemanticEquivalence(
checks: Sequence[EquivalenceCheck] | None = None,
)
Scores a gold-query case with checks that compare the queries themselves.
It never runs a query and never refutes, so it confirms equivalence or is undecided. The first check that confirms yields a passing result; if none confirm, the result is inconclusive.
Bind the scorer to an ordered list of checks.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
checks
|
Sequence[EquivalenceCheck] | None
|
The checks to run, in priority order; the first that confirms wins.
Defaults to |
None
|
score
¶
score(
case: EvalCase,
output: SolverOutput,
result: ExecutionResult,
*,
context: ScoreContext,
) -> ScoreResult
Run the checks in order, stopping at the first that confirms equivalence.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
case
|
EvalCase
|
The eval case; |
required |
output
|
SolverOutput
|
The solver output, passed through to each check. |
required |
result
|
ExecutionResult
|
The executed model result, passed through to each check. |
required |
context
|
ScoreContext
|
The score context, carrying the model SQL, dialect, and query runner. |
required |
Returns:
| Type | Description |
|---|---|
ScoreResult
|
A passing |
ScoreResult
|
result (no check could confirm). |
Raises:
| Type | Description |
|---|---|
TypeError
|
If |
judged_equivalence
¶
judged_equivalence(model: str | Llm) -> FirstDecisive
The query-vs-query check that confirms by structure, else asks an LLM judge.
The case's expected must be a GoldQuery.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
model
|
str | Llm
|
A litellm grader-model identifier, or an |
required |
Returns:
| Type | Description |
|---|---|
FirstDecisive
|
A |
FirstDecisive
|
equivalence first; when it cannot, the SQL-equivalence judge decides without running |
FirstDecisive
|
either query. |
observed_equivalence
¶
observed_equivalence() -> FirstDecisive
The query-vs-query check that confirms by structure, else by running both queries.
The case's expected must be a GoldQuery.
Returns:
| Type | Description |
|---|---|
FirstDecisive
|
A |
FirstDecisive
|
equivalence first; when it cannot, |
FirstDecisive
|
by diffing their results. |
sql_equivalence_judge
¶
An LlmJudge pre-configured to grade whether two SQL queries are equivalent.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
model
|
str | Llm
|
A litellm grader-model identifier, or an |
required |
Returns:
| Type | Description |
|---|---|
LlmJudge
|
An |
default_equivalence_checks
¶
default_equivalence_checks() -> list[EquivalenceCheck]
The default checks, cheapest and most portable first.
Returns:
| Type | Description |
|---|---|
list[EquivalenceCheck]
|
A fresh list of the default |