The scripts are in the repository, not in the installed package. Clone it,
then
cd recipes/01-simulate/verifiers before running the commands below. Browse this recipe on GitHub.data.grade(judge=...),
evaluate, optimize and a gated push exactly where an LLM judge would.
From the repo root:
optimize and a gated push unchanged. The script shows math (MathEqual),
an answer-and-format gate (All([...])), code execution against hidden tests
(CodeExec), a JSON-schema check (JSONSchema), and then hands the math rows
to wai.optimize(mode="rl") and wai.training_rows to show where the answer
key stops travelling.
The pieces
- Where the answer comes from. The candidate is the rollout’s
final_text(or the last assistant turn). The gold is read from the row’sprivileged.reference— which the training export never projects, so the answer key cannot leak into a training file — with flat fields (answer,target,solution, …) as a fallback. Point any verifier at another column withfield=. - Compose.
Allneeds every check to pass (right answer and right format),Anyneeds one,Weightedis a graded rubric in [0, 1]. - Your own.
@verifier def f(candidate, reference, row): ...returns a bool or a score, or a(score, reason)pair.
In the loop
The gold travels with the task, not the spec:simulate() writes prompts,
rollouts and world state, never an answer key, so a verifiable task set is
rows you bring that already carry privileged.reference (or
privileged.tests for CodeExec). Score them with the verifier, run the
RL gates (reward band, unanimous groups, duplicates), push:
SimulationData the same step is data.grade(judge=MathEqual()). The
optimized rows still carry privileged (they are SDK rows, and a verifier
has to be able to re-score them); wai.training_rows(rows) is the export
that never projects it, which is what run.py prints at the end.
Code execution safety
CodeExec runs the candidate in a fresh subprocess with isolated mode, a
private temp directory, a wall-clock timeout, and CPU/memory caps on POSIX.
That stops runaway loops and accidents. It is not a security boundary
against hostile code — for untrusted policies, run the verifier inside a
container or the hosted sandbox.
References
- Lambert, N. et al. Tülu 3: Pushing Frontiers in Open Language Model Post-Training. arXiv:2411.15124, 2024.