Poisson Tasks is out. Find where your agent breaks before your users do. Read the launch
Poisson Prove is out. It tells you whether a change to your agent really changed how often it fails. Read the launch
Poisson Labs

Poisson LabsChange control for stochastic systems · open source + cloud

An average can’t tell you what broke.

Whether you’re shipping an AI agent, a robot controller, or a learned policy, a single headline number hides where the system fails—and moves a few points with nothing changed.

Keep the stack, simulator, and runner you already have. Poisson compares your system before and after a change, condition by condition, on matched seeds and cases, and tells you what improved, what regressed, and what is still too close to call before the change ships.

report.md · change in fall rate, by condition
+200-20-40-60-80friction 0.6, push 0.55 m/s: fell 0% then 7%+70.55friction 0.6, push 0.575 m/s: fell 0% then 5%+50.575friction 0.6, push 0.60 m/s: fell 0% then 16%+160.60friction 0.6, push 0.625 m/s: fell 58% then 16%−420.625friction 0.6, push 0.65 m/s: fell 99% then 28%−710.65friction 0.6, push 0.675 m/s: fell 100% then 27%−730.675friction 0.6, push 0.70 m/s: fell 100% then 42%−580.70friction 1, push 0.55 m/s: fell 0% then 9%+90.55friction 1, push 0.575 m/s: fell 0% then 9%+90.575friction 1, push 0.60 m/s: fell 2% then 13%+110.60friction 1, push 0.625 m/s: fell 52% then 16%−360.625friction 1, push 0.65 m/s: fell 96% then 25%−710.65friction 1, push 0.675 m/s: fell 100% then 33%−670.675friction 1, push 0.70 m/s: fell 100% then 45%−550.70friction 0.6friction 1the average-29.7 points+200-20-40-60-80friction 0.6, push 0.55 m/s: fell 0% then 7%+7friction 0.6, push 0.575 m/s: fell 0% then 5%+5friction 0.6, push 0.60 m/s: fell 0% then 16%+16friction 0.6, push 0.625 m/s: fell 58% then 16%−42friction 0.6, push 0.65 m/s: fell 99% then 28%−71friction 0.6, push 0.675 m/s: fell 100% then 27%−73friction 0.6, push 0.70 m/s: fell 100% then 42%−58friction 1, push 0.55 m/s: fell 0% then 9%+9friction 1, push 0.575 m/s: fell 0% then 9%+9friction 1, push 0.60 m/s: fell 2% then 13%+11friction 1, push 0.625 m/s: fell 52% then 16%−36friction 1, push 0.65 m/s: fell 96% then 25%−71friction 1, push 0.675 m/s: fell 100% then 33%−67friction 1, push 0.70 m/s: fell 100% then 45%−55friction 0.6friction 1push 0.55 to 0.70push 0.55 to 0.70the average-29.7 points

significantly safersignificantly worseno significant changethe average

● OpenResearch result · CI workflow previewPromote checkpoint 5999

microduck-walking@v1

build
unit tests
poisson cloud / provefailed

5 of 14 conditions got worse.

8 better · 5 worse · 1 too close to call, below a 8-point limit

5 of 14 conditions significantly worse.

McNemar’s test per condition on 100 paired trials, Benjamini–Hochberg at q < 0.05. The unchanged condition could have shown a rise of 8 points or more.

These files are as Prove 0.0.1 wrote them, in that version’s green and red.

Merge blocked
Fig. 1 Microduck walking policy, checkpoint 2250 → 5999: 14 conditions, 100 paired trials each. The fall rate dropped from 50.5% to 20.8% on average; condition by condition, 5 rose significantly. The result is from the published study; the pull-request check drawn around it previews the workflow, which is in private preview. Read the study

Published on AI agentswalking robotsa vision encodera multi‑agent benchmarktraining stability

01How it works

Your runs in. A verdict out.

Keep what you run. Poisson says what a change did to it, condition by condition.

Agents

OpenAI Agents SDK, LangGraph, CrewAI

Evals and tracers

DeepEval, Ragas, promptfoo, Inspect, OpenAI Evals, Braintrust, Weave, LangSmith

Simulators

MuJoCo, Isaac Lab, PyBullet, Brax

Compute

AWS, GCP, Azure, Your machine, Modal

TasksAvailable

Build the conditions.

Seeded tasks at a difficulty you choose, on your own tools, with checks the system under test can't see.

poisson-tasks · the Petstore API · gpt-5-nano
A Tasks card: strict pass at one, at faults 0, 1, 2 and 4, with 95% intervals.
One run on simulated replies: 10 tasks a level, 40 episodes, $0.015. An example, not a result about the model.

BreakIn development

Find where it fails.

It will search the conditions for the ones that break the system, and keep each as something a fix can be checked against.

go1 · friction 0.35 · push 80% of bodyweight
One cell of the Go1 map, and one draw from it. This one came from the sweep; Break will search for cells like it.

TracePrivate wheel

Locate the step that broke.

It reads the runs you already have and says which step they die at, with the unchanged version as the control.

poisson-trace compare · a planted change
review q = 1.67e-20 A · 206 B · 422 sample q = 0.865 A · 180 B · 157 measure q = 0.422 A · 146 B · 114 RUNS THAT DIED AT THIS STEP, OF 2,000 PER ARM
A, the baseline B, one stage's failure rate doubled significantly more deaths in B, q < 0.05
One stage's failure rate was doubled and sealed before any run. Trace called the pair different (p = 1.7e-9) and named review, the stage the seal named. Read the study

ProveAvailable

Get a verdict per condition.

Every condition, before and after, on the same seeds: 60 safer, 0 worse, 340 with no significant change. In CI, a regression fails the check.

heatmap.svg · go1, before and after a retrain
Prove's heatmap of 400 conditions: 60 significantly safer, 0 significantly worse.
report.mdWhich conditions moved, in words.
heatmap.svgEvery condition, at a glance.
receipt.htmlRuns, seeds and hashes, to check it.
These files are as Prove 0.0.1 wrote them, in that version’s green and red.

02The problem

Change nothing. Run it twice.

We ran the same airline agent twice on τ²-bench: identical configuration, identical seed, temperature zero. The score barely moved. Underneath, 44 of 200 tasks flipped: 23 passed only in the first run and 21 only in the second, and they cancelled out.

45.0 → 44.0percent of 200 tasks solved, run one then run two.
23 + 21tasks that passed in only one of the two runs: 44 flips, cancelling out.
94 of 200pairs of runs that had already split at the first model call.

pairs still identical after each model calln = 200

0 50 100 150 200 012345678 model calls 94 of 200 split at the first call all 200 by call 8

one task, both runs, call by callidentical, then not

τ²-bench airline task 28 seed 1207528101 temperature 0 gpt-4.1-mini

Both runs, identical

  1. 0 user message · 27 tokens
  2. 1 agent message · 46 tokens
  3. 2 user message · 38 tokens
  4. 3 agent get_reservation_details

Call 4: the runs part. The agent is given the same 3,659 tokens in both runs. It writes 96 tokens in one and 129 in the other.

Run R 20260915T210140Z-4847

  1. 4 agent message · 96 tokens
  2. 5 user message · 59 tokens
  3. 6 agent transfer_to_human_agents
  4. 7 agent message · 18 tokens
  5. 8 user message · 3 tokens

Passed solved · COMMUNICATE 1 · DB 1

Run R′ 20260915T211148Z-965d

  1. 4 agent message · 129 tokens
  2. 5 user message · 62 tokens
  3. 6 agent cancel_reservation
  4. 7 agent message · 111 tokens
  5. 8 user message · 95 tokens
  6. 9 agent transfer_to_human_agents
  7. 10 agent message · 18 tokens
  8. 11 user message · 3 tokens

Failed unsolved · COMMUNICATE 1 · DB 0

The same customer-service task in both runs: identical for 4 calls, token for token. At the next, one run hands the customer to a person and passes; the other cancels the reservation and fails. Read the study

Top-line scores stay flat while dozens of tasks flip underneath. Measure the noise before you call anything a change.

03Proof

A safer policy. Measured, condition by condition.

The same method on a different kind of system: the thing under test changes, the way its failures are found and measured does not. We mapped a Go1 walking policy across 400 conditions of floor friction and lateral push. The map showed two conditions its training had never covered; we retrained on those, then ran both policies through every condition again, 32 times each on the same seeds.

60
conditions significantly safer
0
conditions significantly worse
12,800
rollouts per version, 32 per condition on the same seeds
400
conditions tested

340 showed no significant change. For the least-powered of them, the run could not have detected a rise in the fall rate under 34 percentage points. That limit is reported with the result.

beforefall rate · brighter falls more
friction μ, 0.05 → 1
afterblue: significantly safer
friction μ, 0.05 → 1
push 10%lateral push, % bodyweight200%

60 conditions significantly safer after the retrain0 significantly worse, anywhere in the 400

Hover a condition on the right. Fisher’s exact test per cell, Benjamini–Hochberg at q < 0.05.

04The tools

Five tools. One evidence trail.

Find where runs fail. Measure whether a change helped. Map how difficulty changes outcomes. Search for the conditions that break your system. Train an agent on its own failures. Use them on your own machines, or in CI with Poisson Cloud. They grade by code and statistics, never by another model, and send nothing home.

shell · poisson-trace
poisson-trace fix-check OLD NEW --store ROOT --event NAME \    ( --failing-from RUN | --inputs all ) --max-mde X
Show more commands
pip install poisson-tracepip install poisson-prove# where do runs die, over the step indexpoisson-trace where RUN --store ROOT --event NAME# do two runs' survival curves differpoisson-trace compare A B --store ROOT --event NAME --max-mde-hr X# did the change make runs fail less, with the old version as the controlpoisson-trace fix-check OLD NEW --store ROOT --event NAME \    ( --failing-from RUN | --inputs all ) --max-mde X# which inputs moved, corrected across all of thempoisson-trace changes A B --store ROOT --event NAME
whereSee how many runs survive each step, and which steps end them.
fix-checkCompare the old and new versions on the same inputs, with the old one re-run as the control.
readersImport existing DeepEval or Ragas results without rerunning the model. How.

05In your CI

Catch regressions before they ship.

Establish a baseline, rerun the same conditions on every pull request, and block the merge when a condition is significantly worse.

  1. 1

    Establish a baseline

    Run your agent across the conditions you care about, each run on a seed.

  2. 2

    Rerun on every pull request

    The same conditions on the same seeds, so each one is compared with itself.

  3. 3

    Review the evidence

    Improved, regressed, or too small to call, condition by condition. A regression fails the check.

It fails on real regressions, not on noise. A condition fails the check only when it is significantly worse than its own baseline, with the correction for testing every condition at once built in. You get a pass or a fail on the pull request; the full receipt (the test per condition, Benjamini–Hochberg at q < 0.05, and each condition’s detection limit) is one click away. A regression smaller than that limit can pass, and the report says so.

.github/workflows/agent.ymlYAML
on: pull_requestjobs:  agent:    steps:      - name: Check the agent        run: |          poisson-prove sweep agent.toml \              --target my_agent:rollout \              --pair-with <main-run> --yes          poisson-prove check <main-run> <this-run> \              --event violated --fail-on worse

06What it leaves you

Nothing we find is thrown away.

A failure doesn’t end as a line in a report. It becomes a test on every pull request, training data aimed at exactly that failure, and the starting point of the next search. The first is in private preview; the other two are being built.

  1. 1Into your CIAvailable

    Every failure becomes a test.

    Each condition that broke the agent is saved as a file: the change, the seed and the failure rate under it. It re-runs on every pull request as a standing check, so a fixed failure stays fixed.

  2. 2Into trainingIn development

    Every fix becomes training data.

    The same condition on the same seed, failing before a change and passing after, is a preference pair. So are passing and failing runs within one condition, each with the prompt, retry or tool-schema patch behind it. For a robot policy, training ranges shift toward where it broke, as in the Go1 retrain.

  3. 3Into MonteIn research

    Every hunt sharpens the next.

    Labelled failures, each with its trace and the exact condition, are what Monte is built to learn from: a model of where agents fail that starts the next hunt where failure is most likely. It will learn only from records whose owner turned training on.

Nothing counts as fixed until it is re-run. A retrained agent goes back through the same conditions on fresh seeds, and the result is a receipt like any other. The Go1 retrain is this loop, run once: the map showed two conditions training had missed, and the policy was retrained on exactly those.

07How we count

Know what changed, and what a single score misses.

  1. i.

    Measure the noise.

    Establish how much the system varies when nothing was changed on purpose.

  2. ii.

    Compare like with like.

    Match conditions and seeds across the baseline and the new version.

  3. iii.

    Show where it moved.

    Report changes by condition, not just as an average. An average can improve while 5 conditions get worse.

  4. iv.

    Publish what you couldn’t detect.

    State the smallest effect the study was equipped to find.

MATH ASINFRASTRUCTURE.

Get started Talk to us