Skip to main content
whileai makes training and eval data for agents that call tools. Give it an agent, or just the agent’s tools and system prompt. It writes the situations the agent might meet, runs the agent through them against a fake world that fails on purpose, and hands back every conversation as a row. You grade the rows with your own judge or a verifier. The package then does the bookkeeping that is easy to skip and expensive to get wrong: pass rates with intervals, difficulty bands for RL, a check that your judge agrees with people, decontamination against your eval set, and a scan for rewards the policy can game.
Or pip install whileai. Python 3.10 to 3.13, one dependency, typed. This package used to be called zeroproof; that name still installs it.

Two ways in

You only want evals

Run whileai init-evals in your project. A pass rate with a 95% interval, a table of where the agent fails, and a test that goes red in CI when it gets worse.

You want to train

Grade the same rows, keep the ones that carry signal, export to your trainer or ours.

Sixty seconds, offline

No key, no network. seeded_agent is a stand-in agent. It answers honestly most of the time and, on a labeled fraction of rollouts, does one thing wrong on purpose: hedges, flatters, or claims success after a tool failed. Each row records what it did in seeded, so you can check that your judge catches exactly those rows before you trust it on real ones.
pass@1 is the pass rate over tasks with a bootstrap interval. pass^4 is how often all four rollouts of a task pass. Headroom is pass@4 minus pass@1, the gap an RL update could close. To use your own agent, pass any callable that takes the user message and returns {"steps": [...], "final_text": "..."}. To use a model, pass a spec string: openai:<model>, anthropic:<model>, vllm:<model>@<url>, or ollama:<model>. With no agent= at all, the run uses the Qwen we host, on your key from whileai login, and Phi-4 grades. The judge is never the model it is judging.

The loop

Where each method comes from, with numbered references, is in the README. The knob tables and every gate are in the reference. Every public call, with its signature and docstring, is under API in the sidebar; those pages are generated from the package on each release, so they cannot drift.

Worked recipes

Runnable, one folder each, offline where the method allows it: recipes/. The same paths as skills a coding agent can load are in skills/.