zeroproof-simulations
Generate diverse training conversations for any agent, grounded in its tools and system prompt.
The SDK inspects the agent, simulates a world consistent with those tools (objects, results, failures), and samples scenarios across that space. The same model writes the user and plays the agent. Default explore: one unique situation per row.
Overview
simulate() is a pipeline.
- Read the agent. Tools and system prompt. That is the spec of the world.
- Build a fake world from those tools. Objects, plausible results, and faults (timeout, deny, junk).
- Write users. A separate writer (same hosted model, different prompt, no agent policy) samples situations across tools, stance, history, and so on.
- Pick the diverse ones. Embeddings plus a bit of noise so the batch is not 200 copies of same prompy.
- Play the agent. It talks, calls tools, gets results, talks again. All of that is stored: user text, agent text, tool calls, tool results,
final_text. - Grade. Deterministic conduct score by default. Attach an LLM if you want. Or pass your own
grade=.
Stop when the row cap or the clock hits.
How to use
uv sync
export VLLM_API_KEY=...
ZeroProof hosts Qwen for simulation: it powers the default user writer and rollout agent.
Ask us for a VLLM_API_KEY to try it. The endpoint is shared and rate limited.
From another project:
pip install zeroproof-simulations # or: uv add zeroproof-simulations
Zero runtime dependencies, Python 3.10+. Installing from PyPI rather than a
path or a git URL matters if you build a Prime Intellect environment on this:
the Environments Hub installs a pushed env with plain pip, so a [tool.uv.sources]
git pin resolves locally and then fails on their runtime with a
ModuleNotFoundError.
uv run pytest after uv sync --extra dev.
import zeroproof_simulations as zps
data = zps.simulate(tools=my_tools, system_prompt=my_system_prompt, output="rollout.jsonl")
data = zps.simulate(agent=my_agent)
Pass spec= if you have a local tools-and-system-prompt folder. The generated datasets are on Hugging Face, organized by agent type instead of stored in this repo.
| Knob | Default | |
|---|---|---|
agent / spec |
hosted Qwen | Callable, URL, or tools + system prompt |
budget / time_budget |
1000 / 60 |
Stop when either hits. 0 or None turns the clock off |
requests_per_situation |
from mode | Phrasings: ways to ask one situation. Alias phrasings= |
rollouts_per_request |
from mode | Repeats: reruns of one phrasing. Alias repeats= |
fault_rate |
0.5 |
Broken tools. 0 off |
grade |
True |
Conduct score, or pass your own callable |
llm_grade |
False |
Extra LLM judge. Needs OPENAI_API_KEY |
output |
JSONL path |
What to run
Depends on the use case. How each scenario is built is in The recipe.
| You want | Mode | What happens |
|---|---|---|
| Many distinct situations | explore (default) |
New situation every row |
| Same situation, different wording | sft |
Multiple phrasings: tone, intent, personality |
| Same request, different agent behavior | rl |
Multiple repeats of one phrasing |
| A mix, until coverage plateaus | adaptive |
New situations, phrasings, and repeats. Best with until="saturation" |
zps.simulate(tools=my_tools, system_prompt=my_system_prompt) # explore
zps.simulate(tools=my_tools, system_prompt=my_system_prompt, mode="sft")
zps.simulate(tools=my_tools, system_prompt=my_system_prompt, mode="rl")
zps.simulate(tools=my_tools, system_prompt=my_system_prompt, mode="adaptive", until="saturation")
Speed
Two-minute airline runs using ZeroProof-hosted Qwen. Results were measured on the hosted GPU with warm replicas and burst under load.
| Mode | Rows | Rate | Unique openers |
|---|---|---|---|
explore |
240 | 120/min | 240 |
sft |
278 | 139/min | 278 |
rl |
625 | 296/min | 209 |
Parameter reference
| Parameter | Default | Meaning |
|---|---|---|
agent |
hosted Qwen | Rollout model |
spec |
Local tools and system prompt path | |
tools, system_prompt |
from spec or agent | Tool list and agent system prompt |
situations |
Distinct situations (N) | |
requests_per_situation |
from mode | Phrasings per situation (n). Alias phrasings= / n= |
rollouts_per_request |
from mode | Repeats per phrasing (k). Alias repeats= |
unique_situations |
on in explore |
Unique situations only |
mode |
"explore" |
explore, sft, rl, adaptive |
budget |
1000 |
Row cap |
time_budget |
60 |
Seconds. None or 0 disables |
until |
"compute" |
"saturation" also stops when coverage plateaus |
grade |
True |
Conduct score |
llm_grade |
False |
Extra LLM judge |
output |
JSONL path | |
advanced |
Keys below |
advanced key |
Default | |
|---|---|---|
concurrency |
192 |
Parallel rollouts |
embedder |
"hash" |
Prompt selection |
seed |
0 |
Reproducible draws |
avg_turns |
4 |
Target conversation length |
Aliases: phrasings= / n= → requests_per_situation; repeats= → rollouts_per_request; unique= → unique_situations; policy= → system_prompt; risk= → fault_rate.
Output
Each row: prompt, messages, steps, final_text, scenario_id. Optional world_state, faults, reward, reason. llm_grade=True adds llm_reward. zps.rank(path) adds quality without changing reward.
The recipe
Each scenario is a draw across the world and the human.
World (from this agent's tools and system prompt)
- objects and tool results that match the spec
- tool outcome: success, timeout, deny, stale, etc.
- world state: exists, missing, already handled, unfinished, etc.
- history: first visit, prior miss, return, etc.
- rules the agent is supposed to follow
Human
- intent: which tool, what they want (randomized sometimes)
- stance: ordinary, ambiguous, adversarial, hurried, etc.
- persona: first time, returning, in a hurry, etc.
- tone: impatient, frustrated, polite, etc.
- typing: standard, lowercase, typo, clipped, etc.
Ordinary asks first, then the edges. On top of that, we embed the openers and add a bit of random noise so the batch stays spread out, not a cluster of near-copies. Spend the row cap and the clock on diversity, not copies.
License
Apache-2.0
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distribution
Built Distribution
Filter files by name, interpreter, ABI, and platform.
If you're not sure about the file name format, learn more about wheel file names.
Copy a direct link to the current filters
File details
Details for the file zeroproof_simulations-1.1.tar.gz.
File metadata
- Download URL: zeroproof_simulations-1.1.tar.gz
- Upload date:
- Size: 114.0 kB
- Tags: Source
- Uploaded using Trusted Publishing? No
- Uploaded via:
uv/0.12.5 {"installer":{"name":"uv","version":"0.12.5","subcommand":["publish"]},"python":null,"implementation":{"name":null,"version":null},"distro":{"name":"Ubuntu","version":"24.04","id":"noble","libc":null},"system":{"name":null,"release":null},"cpu":null,"openssl_version":null,"setuptools_version":null,"rustc_version":null,"ci":true}
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
e89bcb0fa6fb9c5a81e5609132898cafed1541a81c7ab08129cee63b1fe876df
|
|
| MD5 |
2e7f459682a2235152903ff7fe53d76f
|
|
| BLAKE2b-256 |
5007ad3c8967029983199fb57088701141d5254591095bad0ea0177f8790b1d3
|
File details
Details for the file zeroproof_simulations-1.1-py3-none-any.whl.
File metadata
- Download URL: zeroproof_simulations-1.1-py3-none-any.whl
- Upload date:
- Size: 118.7 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? No
- Uploaded via:
uv/0.12.5 {"installer":{"name":"uv","version":"0.12.5","subcommand":["publish"]},"python":null,"implementation":{"name":null,"version":null},"distro":{"name":"Ubuntu","version":"24.04","id":"noble","libc":null},"system":{"name":null,"release":null},"cpu":null,"openssl_version":null,"setuptools_version":null,"rustc_version":null,"ci":true}
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
60bd99c367cad1f1f08eda464553175b15554dac31a41322e1c658ec37cc62b0
|
|
| MD5 |
1a83ef1f34263f6e3271a8aad2f1a607
|
|
| BLAKE2b-256 |
db40efb9c220d22807a0a0d2667d32ea069b9ea215fbfcb2fe619c8341eac34c
|