evalstone
The plug-and-play evals layer for LLM-based projects, as a Python library.
Status: 0.1.0. Docs: evalstone.com/docs/evalstone/library. Source and samples: github.com/marceloribeiro/evalstone.
The library computes; it owns no database. A run lives in memory, prints a table and writes a JSON report. Persistence happens through the Evalstone center (PostgreSQL) when one is configured.
Develop
just install # venv + editable install with dev extras
just check # ruff + pytest
just console # REPL with `es` loaded
Quick start
pip install evalstone
evalstone init my-evals # evalstone.yaml + a golden set + recorded outputs + a check
cd my-evals
evalstone run nightly # table + evalstone-report.json
evalstone gate nightly # exit 1 when the gate fails (CI)
A fuller example — a small retrieval bot with a gated suite — lives in the
repository under samples/rag-bot (git clone it, then evalstone run nightly
inside the sample).
Judges and prompt targets need a provider key in the environment
(ANTHROPIC_API_KEY, OPENAI_API_KEY, GEMINI_API_KEY, or any
OpenAI-compatible base URL such as OpenRouter or Ollama via providers:).
Without one, judge results are errors, never passes, and the gate fails.
Human labels
evalstone run nightly --report r.json
evalstone label r.json --out evals/labels.jsonl # p/f per output, or --scale 5
Labels are keyed by sample id and a hash of the output, so a changed answer
never inherits an old grade; outputs whose target errored are not offered for
grading. --scale N passes at N-1 (a 2-point scale at 2), as judges do. A
human check ({type: human, labels: evals/labels.jsonl}, path relative to
evalstone.yaml) scores from them; an unlabelled output is an error, never a
pass. Labels are also the ground truth judges get calibrated against (center).
pytest
from evalstone.pytest_plugin import suite
@suite("nightly") # runs the suite; a failing gate fails the test
def test_support_bot(run): # optional body sees the Run
assert run.summary.cost_usd < 1.0
Fixtures evalstone_run / evalstone_gate / evalstone_config; options
--evalstone-config, --evalstone-baseline (a report, or a directory of them).
Each suite writes evalstone-report.<suite>.json beside the config; paths are
relative to the config's directory. A suite without a gate: fails the gated
forms. Works on test methods too. The plugin registers itself when evalstone is
installed, imports nothing of evalstone until a fixture runs, and pytest is not
a runtime dependency of the library.
MCP server
pip install "evalstone[mcp]"
claude mcp add evalstone -- evalstone mcp # run from the project directory
Tools: list_suites, run_suite, judge_output, record_sample, compare_runs,
get_run. The agent edits your prompt, runs the suite, reads the failures, and
compares runs — the gate stays yours. Report paths are relative to the directory
holding evalstone.yaml (pass --config to serve a project from elsewhere).
Concepts
Sample → Dataset (content-hashed, so every run pins an exact version) ·
Check → Score (0..1 + pass/fail + reason; an error is never a pass) ·
Suite → Run → Gate. See the docs for the full vocabulary.
Metadata
Release files for evalstone 0.1.1
For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.
Source distribution (sdist)
| File | Size | Uploaded | |
|---|---|---|---|
| evalstone-0.1.1.tar.gz | 88.5 kB | Details |
Built distribution (wheel)
| File | Interpreter | ABI | Platform | Reset |
|---|---|---|---|---|
| evalstone-0.1.1-py3-none-any.whl | Python 3 | none | any | Details |
Total release size: 156.2 kB
Release files / evalstone-0.1.1.tar.gz
| Download URL | evalstone-0.1.1.tar.gz |
|---|---|
| Size | 88.5 kB |
| Tags | Source |
|
SHA-256 checksum How to use checksums |
c637757e3706a651230031ec82f1fe7e3abd117537d97367579ba8c1a43c21f7
|
|
BLAKE2b-256 checksum How to use checksums |
ac97f6e5c38b5a3de02998e98c2fa344741a6f6e9d5d6269b18095ee6dfa8f0e
|
| 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 13, 2026.
Transparency logRelease files / evalstone-0.1.1-py3-none-any.whl
| Download URL | evalstone-0.1.1-py3-none-any.whl |
|---|---|
| Size | 67.8 kB |
| Tags | Python 3 |
|
SHA-256 checksum How to use checksums |
45d39ab7dc38550b42f4d8f7996094c85721e251de23c91e151cf865d99aee1d
|
|
BLAKE2b-256 checksum How to use checksums |
d24c3dcbbe65b9063356e9bcf5be570acd3eee362cc4e219fcb48b2423a3589e
|
| 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 13, 2026.
Transparency log