Personalize this lesson
Adapt explanations and teaching visuals to your background and preferred voice.
A coding agent passes eight of its first ten held-out tasks. Should its next deployment receive more traffic? The observed rate is 0.800, but ten tasks can still mislead, and yesterday's agents may provide useful evidence you shouldn't quietly discard.
Probability for Machine Learning introduced base rates and conditioning. Now ask a narrower question: before those ten tasks, which pass rates were plausible? Bayesian inference makes that starting belief explicit, updates it with outcomes, and carries uncertainty into the next deployment decision.[1][2]
We'll keep one running ledger: Beta(2, 2) before the run, then eight passes and two failures. The count flow makes those two sources of information visible before we name the equations.

Name the uncertainty before seeing the new run
Let mean the probability that this agent passes a future task drawn from the same task population. The last ten outcomes don't reveal exactly. They provide evidence about plausible values.
| Quantity | Question it answers | Worked value |
|---|---|---|
| Prior | Which rates were plausible before this eval? | Beta(2, 2) |
| Observations | What actually happened? | 8 passes, 2 failures |
| Likelihood | How compatible are those outcomes with each rate? | proportional to |
| Posterior | Which rates remain plausible after the update? | Beta(10, 4) |
Read the table as a sequence. The prior proposes candidate rates, the likelihood scores how well each rate explains the eight passes and two failures, and the posterior combines both sources and normalizes them. The likelihood by itself isn't yet a probability distribution over .
The prior Beta(2, 2) is a probability distribution over possible success rates, symmetric around 0.5. For intuition, its two parameters carry success-shaped and failure-shaped weight into the update. They're modeling assumptions, not four real benchmark rows. Relative to a uniform Beta(1, 1) starting point, Beta(2, 2) could instead arise from one observed success and one observed failure, so disclose the baseline before treating parameters as historical evidence.

The update transfers only when the old and new tasks share a success-rate meaning. If historical agents performed differently, came from a different benchmark, or used another tool policy, treating their records as evidence about this agent will distort the update.
Work through the update by hand
Start with the ledger rather than the symbol: two prior success weights plus eight observed passes gives 10, and two prior failure weights plus two failures gives 4. For a binary outcome, this neat addition is the beta-binomial update. A beta prior and Bernoulli observations (independent pass-or-fail draws under the assumed model) stay in the same beta family, which is why beta is a conjugate prior:[2]
Here and are the prior parameters, counts observed passes, and counts observed failures. Substitute the actual numbers:
The posterior mean is:
The sample-only rate is . The prior-only mean is . The updated mean lies between them because the prior supplies modeling weight while the observations supply new evidence under the assumed model.
The next cell repeats that arithmetic and checks the parameter totals before printing the updated rate.
1prior_success = 2
2prior_failure = 2
3observed_pass = 8
4observed_fail = 2
5
6posterior_success = prior_success + observed_pass
7posterior_failure = prior_failure + observed_fail
8posterior_mean = posterior_success / (posterior_success + posterior_failure)
9
10assert (posterior_success, posterior_failure) == (10, 4)
11print(f"observed rate: {observed_pass / (observed_pass + observed_fail):.3f}")
12print(f"posterior: Beta({posterior_success}, {posterior_failure})")
13print(f"next-task pass probability: {posterior_mean:.3f}")1observed rate: 0.800
2posterior: Beta(10, 4)
3next-task pass probability: 0.714Predict one future task from the posterior
If the next task is comparable, the posterior predictive probability gives us a forecast before that task runs. Under this beta-binomial model, one new task passes with probability equal to the posterior mean: 10/14, or about 0.714. That's a model-based prediction, not a guarantee that the next task passes.
Why does the posterior mean equal 10/14 instead of the observed pass rate 8/10?
Answer
The Beta(2,2) prior contributes two success-shaped and two failure-shaped counts. Combining them with eight passes and two failures yields Beta(10,4), whose mean is 10 divided by 14.
Check whether the prior dominates the evidence
Two engineers can see the same ten outcomes and reach different posterior means because they chose different priors. Hold the observations fixed and vary only the historical assumption.
The next cell reuses the pass and failure counts and compares a weak Beta(1, 1) prior, a moderate Beta(2, 2) prior, and a strong Beta(20, 20) prior. Predict what should happen before reading the numbers: the strong prior should stay closer to 0.5.
1for success_count, failure_count in [(1, 1), (2, 2), (20, 20)]:
2 updated_success = success_count + observed_pass
3 updated_total = success_count + failure_count + observed_pass + observed_fail
4 print(
5 f"Beta({success_count:>2}, {failure_count:>2}) -> "
6 f"posterior mean {updated_success / updated_total:.3f}"
7 )1Beta( 1, 1) -> posterior mean 0.750
2Beta( 2, 2) -> posterior mean 0.714
3Beta(20, 20) -> posterior mean 0.560Beta(20, 20) gives its starting mean a weight of 40 in this update, so the ten new outcomes barely move it. That can be reasonable when the prior came from substantial, comparable historical evidence.
Relative to a uniform Beta(1, 1) baseline, reaching Beta(20, 20) would require 19 historical passes and 19 historical failures, not 40 observed tasks. The parameter weight is bookkeeping; it isn't a provenance record. Keep those two facts separate.
| Prior | Prior parameter weight | Posterior mean | Interpretation |
|---|---|---|---|
| Beta(1, 1) | 2 | 0.750 | Weak symmetric starting assumption |
| Beta(2, 2) | 4 | 0.714 | Mild pull toward 0.5 |
| Beta(20, 20) | 40 | 0.560 | Strong historical assumption dominates ten tasks |
Report several defensible priors when the sample is small. If the deployment decision flips between them, collect more representative evidence instead of quietly choosing the prior that makes the preferred outcome win.
An engineer claims Beta(20,20) proves that 40 comparable historical tasks were observed. What information is missing?
Answer
The prior has total parameter weight 40, but that weight isn't automatically 40 observed tasks. Relative to a uniform Beta(1,1) baseline, the same prior could result from 19 historical passes and 19 historical failures. The earlier baseline and the historical evidence's provenance must both be disclosed.
Keep posterior uncertainty separate from the average
A mean of 0.714 doesn't say every plausible success rate is 0.714. Beta(10, 4) still spreads probability across a range of rates. For Beta(), the posterior variance is:
At Beta(10, 4), this is , giving a posterior standard deviation near 0.117. A credible interval would summarize posterior quantiles; its interpretation still depends on the prior and the sampling model.[1]
Does a posterior mean of 0.714 establish that the agent's unknown success probability is exactly 0.714?
Answer
No. The mean summarizes the Beta(10,4) posterior, while its standard deviation near 0.117 shows that other success probabilities remain plausible under the assumed prior, likelihood, and sample.
Test how more evidence changes uncertainty
Hold the Beta(2, 2) prior fixed and increase the evidence: compare the ten-task run with eighty passes and twenty failures. The larger run yields Beta(82, 22), whose mean is about 0.788 and whose posterior standard deviation is about 0.040. More representative data narrows uncertainty and reduces the prior's influence.
The next independent cell computes both summaries from the closed-form beta variance.
1from math import sqrt
2
3for successes, failures in [(10, 4), (82, 22)]:
4 total = successes + failures
5 mean = successes / total
6 variance = successes * failures / (total**2 * (total + 1))
7 print(f"Beta({successes}, {failures}): mean={mean:.3f}, sd={sqrt(variance):.3f}")1Beta(10, 4): mean=0.714, sd=0.117
2Beta(82, 22): mean=0.788, sd=0.040Check calibration on new tasks
Posterior spread and calibration answer different questions. The posterior describes uncertainty about a success rate under a chosen model. Calibration asks whether forecasts line up with later outcomes: among many comparable tasks assigned a pass probability near 0.7, do about 70% pass?
The 0.714 forecast can't establish calibration from the same ten tasks that produced it. To test transfer, update on an initial batch, freeze predictions for later tasks, group similar forecasts into bins, and compare each bin's average prediction with its observed pass fraction. A mismatch points you back to task shift, duplicated retries, policy changes, or a misspecified likelihood. More data can narrow a wrong model's interval without making its forecasts honest.[1][3]
Break the assumptions before trusting the result
The arithmetic can be correct while the inference is wrong.
| Failure | Visible symptom | Repair |
|---|---|---|
| Repeated retries of one task | Ten rows claim to represent ten independent tasks | Group retries by underlying task and sample distinct tasks |
| Easy benchmark slice | Posterior looks strong while hard production tasks fail | Stratify by task family and compare deployment traffic |
| Historical prior from another agent | Strong prior hides a real regression | Record prior provenance and run sensitivity checks |
| Hidden prompt changes | Outcomes combine incompatible policies | Pin model, prompt, tools, and task definitions |
| Selective release reporting | Only a favorable stopping point or chosen agent is disclosed | Record every evaluated agent, stopping rule, and release decision |
Bayesian updating handles evidence under a model. Under a correctly specified likelihood and an ignorable stopping rule, stopping early doesn't automatically invalidate a posterior. Selectively reporting the most favorable model or repeatedly changing the release decision still distorts the evidence available to readers. Updating can't turn duplicated, biased, or contaminated rows into representative observations.
A model passes eight out of ten tasks, but all ten rows are retries of the same prompt. Why is Beta(10,4) misleading?
Answer
The update treats the rows as distinct exchangeable task outcomes. Retries of one prompt mainly describe that prompt, so they exaggerate evidence about performance across the deployment population.
Build a release-decision worksheet
Write a compact evaluation worksheet with four columns: observed passes and failures, declared prior and its provenance, posterior parameters, and the resulting next-task probability. Start with the ten reviewed tasks and compare Beta(1,1), Beta(2,2), and Beta(20,20). The expected output is a posterior-mean sequence of 0.750, 0.714, and 0.560, with the historical prior's source stated separately from the number of benchmark rows.
Add a second row group for 80 passes and 20 failures. Verify that Beta(2,2) becomes Beta(82,22), then compare its posterior standard deviation of about 0.040 with 0.117 for the ten-task update. Before releasing, state which policy you apply: posterior mean, a lower credible bound, or the posterior probability that exceeds a launch threshold. Mark the release undecided if defensible priors disagree, retries inflate the sample, or the benchmark population doesn't match deployment traffic. Keep the worksheet as a reviewable artifact rather than publishing a bare pass-rate headline.
What should a release reviewer conclude when one justified prior passes the deployment threshold but another equally defensible prior fails it?
Answer
The available sample doesn't support a prior-robust decision. Record both priors and posterior results, keep the release undecided, and collect additional representative tasks before claiming the threshold is met.