Skip to main content
evalr: judges that give typed verdicts, trained on people's feedback and measured against it.

Docs Nightly Python 3.12, 3.13 and 3.14 Coverage: 100% Typed: pyright strict License: MIT

evalr is a Python library for typed evaluation of agent systems. An evaluator judges an input (a chat thread, a workflow run, an artifact version) and returns a verdict: an instance of a Pydantic type, typically one of the feedback types people also give. Because people and evaluators produce the same types, evaluators can be trained on people's feedback and measured against it.

Status: pre-release. v0.1 is built, as planned in RFC-0001, and not yet released. The API may still change before 1.0.

Why

People judge an agent's work in feedback, but only a fraction of it, and only after it has shipped. To know whether a new prompt or model is better before people see it, and how the agent does on the traffic nobody rates, you need evaluators that judge the way people do, and a way to check that they do. evalr's evaluators give the same typed verdicts as people's feedback, so they are trained on it, measured against it field by field, and versioned so that verdicts from different evaluators never mix.

Install

Python 3.12 or newer. Until evalr is on PyPI, install it from its directory in lattice, the repository every package lives in:

uv add "evalr[all] @ git+https://github.com/alexnodeland/lattice#subdirectory=packages/evalr"

The core needs only pydantic and the OpenTelemetry API. Extras: dspy (DSPy judges and GEPA), jev (decision evaluators on TypeSafe's Jev, through pydantic-ai), langfuse (datasets, scores and experiments in Langfuse), hf (Hugging Face datasets), and all.

Example

People rated support replies. A DSPy judge is trained on their verdicts with GEPA, a decision model goes in front of it, and the pair is measured on examples they were not trained on:

import asyncio
from typing import Annotated

import dspy
from pydantic import BaseModel, Field

from evalr import Fallback, measure, optimize
from evalr.decision import DecisionEvaluator
from evalr.dspy import DspyJudge, Gepa
from evalr.jsonl import JsonlDatasetStore


class Thread(BaseModel):
    request: str = Field(description="What the person asked for")
    reply: str = Field(description="The agent's reply")


class Helpfulness(BaseModel):  # the feedback people give, and the evaluators' verdict
    """Whether the reply helped the person."""

    rating: Annotated[int, Field(ge=1, le=5, description="How much the reply helped")]
    resolved: bool = Field(description="The request was fully addressed")
    reason: str | None = Field(default=None, description="Why, in a sentence")


async def main() -> None:
    feedback = await JsonlDatasetStore("datasets").load(  # threads with people's verdicts
        "helpfulness", input_type=Thread, verdict_type=Helpfulness
    )
    train, validate = feedback.split(0.2)

    judge = DspyJudge(Helpfulness, inputs=Thread, lm=dspy.LM("openai/gpt-5-mini"))
    trained = await optimize(  # GEPA learns from people's verdicts, and their reasons
        judge,
        train=train,
        validate=validate,
        optimizer=Gepa(reflection_lm=dspy.LM("openai/gpt-5")),
    )

    decider = DecisionEvaluator(Helpfulness, inputs=Thread, min_confidence=0.7)  # Jev
    evaluator = Fallback(decider, trained)  # the judge answers only where Jev is unsure

    measurement = await measure(evaluator, validate)
    print(measurement.agreement.score)  # agreement with people, from 0 to 1
    for stats in measurement.stats:
        print(stats.evaluator, stats.n, stats.p95_latency, stats.total_cost)


asyncio.run(main())

It needs OPENAI_API_KEY (or another provider's, with the models renamed) and TYPESAFE_API_KEY. It prints how far the pair agrees with people, then how many threads each evaluator judged, how fast and at what cost.

What you get

  • Typed verdicts over any Pydantic model. A field's type decides how it is judged, measured and scored.
  • Two kinds of evaluator, as equals. DSPy judges with signatures derived from their types, trained with GEPA on people's verdicts and reasons; and decision models such as TypeSafe's Jev, through pydantic-ai, with calibrated confidence and thresholds fitted to people. Fallback composes them; function evaluators cover what can be computed.
  • Measured against people. Agreement per field, calibration of confidence, and latency and cost per evaluator version.
  • Datasets that stay put. Content-hashed, split by a hash of each example's id, and kept at every revision in memory, as JSON Lines files, in Langfuse or on the Hugging Face Hub.
  • Experiments and online evaluation. Compare systems on a dataset in memory or in Langfuse; judge live traffic sampled by key, within a budget, with scores in Langfuse or as OpenTelemetry events.
  • End-to-end measures. Task completion, drop-off and rewrites, defined in terms any application's log can be put in.
  • Built to be tested. Ports and adapters, in-memory adapters of every port, and contract suites every adapter passes, with 100% branch coverage and pyright strict.

Documentation

The documentation is evalr's section of lattice's site, at https://lattice.alexnodeland.com/evalr/. It is built from docs/evalr/ and published from main on every push; run moon run lattice:docs-serve to read it locally at http://localhost:8000.

  • Getting started, concepts and the guides: verdicts, evaluators, DSPy judges, decision evaluators, calibration, datasets, feedback sources, scores, experiments, metrics, workflow measures, online evaluation and testing.
  • Architecture: concepts, packages and how each part works.
  • Architecture decision records: why each part is the way it is.
  • RFCs: proposals and the v0.1 build plan.
  • Brand: the mark, colours and type.

lattice

evalr is one of the packages in lattice: artifactr and reflexr, which record typed feedback from people and depend on evalr through their [evals] extras; relayr, the bridge planned between them; and stackr, the infrastructure they run on. evalr imports none of them.

Contributing

See CONTRIBUTING.md for setup, the trunk-based workflow, and the RFC and ADR process.

License

MIT

Metadata

Release files for evalr 0.1.0

For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.

Source distribution (sdist)

Source distribution for evalr 0.1.0
File Size Uploaded
evalr-0.1.0.tar.gz 71.4 kB Details

Built distribution (wheel)

Table of built distributions (wheels) for evalr 0.1.0
File Interpreter ABI Platform
evalr-0.1.0-py3-none-any.whl Python 3 none any Details

Total release size: 170.2 kB

Release files / evalr-0.1.0.tar.gz

Download URL evalr-0.1.0.tar.gz
Size 71.4 kB
Tags Source
SHA-256 checksum
How to use checksums
05c3a1c13c1e7fd0dc14f6c18f907398d39c201c4b8b1bfbc6f1c5dab1666c03
BLAKE2b-256 checksum
How to use checksums
1294d9e54ec92839ff809f3949eb83d611da187387491d964ae9f5333dfca25e
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via twine/7.0.0 CPython/3.13.14

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

PyPI Publish Attestation

PyPI verified that this artifact, at this checksum, originated from the publisher listed below.

Signed by GitHub Actions, verified by PyPI on Oct 17, 2026.

Transparency log

Release files / evalr-0.1.0-py3-none-any.whl

Download URL evalr-0.1.0-py3-none-any.whl
Size 98.9 kB
Tags Python 3
SHA-256 checksum
How to use checksums
90b5a2081a8ea8740c2e7e49e1acb1380d833489801a9e87a7b63354540bb75a
BLAKE2b-256 checksum
How to use checksums
16d7584a596027ea45169a41514eb48d195ee3274705c5f8309f94b4708d7ee6
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via twine/7.0.0 CPython/3.13.14

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

PyPI Publish Attestation

PyPI verified that this artifact, at this checksum, originated from the publisher listed below.

Signed by GitHub Actions, verified by PyPI on Oct 17, 2026.

Transparency log

Release history Release notifications | RSS feed

This release

0.1.0 This release

2 release files

Anthropic, PBC Visionary sponsor Bloomberg Visionary sponsor Hudson River Trading Visionary sponsor Meta Visionary sponsor NVIDIA Visionary sponsor Microsoft Sustainability sponsor Depot Continuous Integration AWS Cloud computing and Security Sponsor Datadog Monitoring Fastly CDN Google Download Analytics Sentry Error logging StatusPage Status page