Skip to main content
The whole design converges here: a pipeline step that runs your evals against real models and fails when quality drops below the baseline.

The two shapes

Pest-shaped — evals live in your test suite, CI adds the flag:
.github/workflows/evals.yml
CLI-shaped — no Pest in the pipeline, JSON artifact out:
The eval step
--baseline is doing real work here. Unlike the Pest surface, the CLI never promotes a baseline on its own — without it there is nothing for --compare=baseline to resolve, and every run reports “No reference run found for —compare=baseline” forever. With it, each gate-passing run becomes the reference for the next.
Exit codes do the gating: 0 clean, 1 regression/gate failure, 2 harness failure. See CLI.

Baselines in CI

Baselines are established differently on each surface — in Pest the first gate-passing run auto-baselines its suite; from the CLI you ask for it with --baseline. Either way, the CI question is where the baseline lives: comparison needs a database with history. Two workable setups:
  • Shared eval database (recommended): point CI’s DB_* at a small persistent database (the same one your dashboard reads). Every CI run lands in history, baselines persist, and the dashboard shows your CI runs’ trends for free.
  • Ephemeral DB, artifact-driven: run with a throwaway database and treat the JSON report as the record. You lose --compare (no history to compare against) but keep absolute gates (--min-score, --min-pass-rate).
Vizra Cloud is the third option, and the reason it exists: CI reports its runs to a hosted history, so an ephemeral CI database costs you nothing and the same trend line covers your laptop, your branch and main. Set VIZRA_CLOUD_KEY as a CI secret.
Trigger evals deliberately, not on every push: path filters (only when agents/prompts/datasets change), a nightly schedule, or a PR label. They cost real tokens and real minutes.

Controlling cost

  • samples(2–3) is usually enough signal for CI; save samples(10) for investigations.
  • Gates skip judges on broken samples automatically — your worst PRs are your cheapest.
  • Set min: thresholds only on calibrated judges; a miscalibrated judge burns tokens and trust.
  • The JSON report includes total and judge cost per run — chart it; eval spend that drifts up usually means a dataset quietly grew.

Keys and safety rails

Provider keys come from CI secrets, judge configuration via EVALS_JUDGE_PROVIDER / EVALS_JUDGE_MODEL. And keep a wiring check in the normal test lane so breakage surfaces before the expensive lane runs:
Cheap lane (every push)