Open source · MIT · built in the open

Know your LLM feature works before your users do.

Evalstone is the plug-and-play evals layer for any LLM-based project: a Python library, a learning center, a check center, an API and an MCP server. First it teaches you what evals are. Then it runs them for you, in CI and in production.

evals/support_bot.py
import evalstone as es

suite = es.Suite(
    "support-bot",
    dataset=es.Dataset.from_jsonl("evals/golden.jsonl"),
    checks=[
        es.checks.json_schema(schema=Answer),
        es.checks.judge("helpfulness", rubric=RUBRIC),
        es.checks.rag.faithfulness(),
    ],
    gate=es.Gate(min_pass_rate=0.95),
)

run = suite.run(target=answer)   # your function
run.gate()                       # non-zero exit in CI

The problem

Shipping LLM features by vibes works until it doesn't

Every team that puts a model in front of users hits the same four walls.

"It looks fine" is not a test

You tweak a prompt, try three questions, and ship. The fourth question, the one a customer asks, is the one that broke. Non-deterministic systems need a repeatable answer to "is it better?".

Model updates move the floor

Providers retire and replace models. The same prompt gives different answers next month. Without a golden set and a baseline run you only find out from support tickets.

A judge you never measured is a guess

LLM-as-judge is powerful and cheap, and it is also biased, position-sensitive and happy to agree with itself. A judge earns trust by being calibrated against humans.

Production is the eval nobody runs

Offline suites catch regressions you anticipated. Real traffic finds the rest. Sampling and scoring live exchanges turns "we think it is fine" into a number with a trend.

Evals, in one minute

An eval is a test for a system that does not give the same answer twice

Unit tests assert equality. Evals measure quality over a dataset and decide whether the number is good enough. The loop is small, and it is the same loop whether you are grading a chatbot, a RAG pipeline, an extraction prompt or an agent.
  1. 1

    Dataset

    A set of inputs with, where possible, what a good answer looks like. Real traffic, hand-written, or synthetic.

  2. 2

    Run

    Send every input through your feature and keep the outputs. Pin the dataset version and the git commit.

  3. 3

    Check

    Score each output: deterministic rules, an LLM judge with a rubric, a human, or a comparison against another run.

  4. 4

    Gate

    Turn scores into a decision: pass rate above a threshold, no regression versus the baseline, cost under budget.

Read the full chapter

How it works

Three steps, no rewrite

  1. 1

    Describe the suite

    One YAML file: where the dataset is, what produces outputs (a function, an HTTP endpoint, a prompt), which checks to run, what the gate is.

  2. 2

    Run it anywhere

    evalstone run on your laptop, in pytest, in a GitHub Action, or from an MCP client. Cheap checks run first; judge calls are cached and priced.

  3. 3

    Keep the history

    Point it at a center, self-hosted or ours, and every run lands in PostgreSQL: baselines, diffs, labels, calibrations, monitors.

evalstone.yaml
# evalstone.yaml
project: support-bot
datasets:
  golden: evals/golden.jsonl
suites:
  nightly:
    dataset: golden
    target: { kind: http, url: http://localhost:8000/answer }
    checks: [json_schema, helpfulness, faithfulness]
    gate: { min_pass_rate: 0.95, max_regression: 0.02 }
judges:
  default_model: anthropic/claude-haiku-5-5
center:                      # optional — persists runs in PostgreSQL
  url: https://api.evalstone.com

Status

Built in the open, in this order

  1. live

    Site + learning center

  2. next

    Library + CLI on PyPI

  3. then

    MCP server · pytest · GitHub Action

  4. then

    Center: API + web, self-hosted or hosted

The roadmap, the design decisions and every commit are public. Star the repository to follow along, or open an issue with the eval problem you are stuck on; that is how the chapters get better.