How to use the bandit dashboard
Goal: understand which verified email angle to send per segment without letting unsafe claims win.
What is a multi-arm bandit in this project?
A multi-armed bandit repeatedly chooses one action from a set and learns only from the action it chose. Here, an arm is an email angle, the context is the audience segment, and the reward is a booked meeting. Unlike a fixed A/B test, the traffic allocation changes after every observation.
Each tick samples one plausible CTR, \(\theta_i\), from every eligible arm's current posterior and selects \(\arg\max_i \theta_i\). This randomized policy naturally sends more traffic to strong arms while still testing uncertain ones. The Stanford Thompson Sampling tutorial provides the algorithmic background.
The Gate is a hard eligibility filter applied before optimization. Unsafe arms can remain visible for auditability but cannot enter the candidate set. Treat this like an allowlist boundary: policy decides what may compete; the bandit optimizes only inside that set.
Additional context
For software engineers
Think of the bandit as a stateful request router. Its state is one posterior per segment and arm. For each request it filters ineligible arms, samples a score from each remaining posterior, routes to the highest sample, records the outcome, and updates only that arm.
The important difference from a normal load balancer is feedback: every routing result changes future routing probabilities.
For conversion administrators
Think of each arm as a campaign creative competing for the next send. Traffic is not split evenly forever. Copy that appears effective receives more opportunities, while uncertain copy still receives enough traffic to prove or disprove its potential.
The Gate ensures that conversion performance cannot promote claims that are not approved.
Intervention controls
These controls mutate experiment state. Inject creates a new arm with a \(\operatorname{Beta}(1,1)\) prior, so it begins maximally uncertain and will receive exploratory traffic. Pause stops new observations without changing stored state. Fast-forward sends the current state to the backend, executes exactly 1,000 normal decision/update cycles, and applies the returned state atomically; it is a convergence test, not synthetic aggregation.
Pace changes only wall-clock timing, not the random process or posterior math. Reset is destructive to in-memory evidence: counters, posterior parameters, regret, and logs return to initialization. Gate masking changes the eligible action set before sampling; turning it off intentionally allows planted unsafe arms to compete.
Additional context
For software engineers
Classify each control by side effect. Pace and pause affect scheduling. Inject changes configuration and initializes state. Gate masking changes the selection predicate. Reset replaces all experiment state with defaults.
When debugging, log the control action and compare state before and after it. A timing control should never mutate posterior parameters.
For conversion administrators
Pause before investigating a surprising result so new sends do not move the numbers while you inspect them. Use fast-forward only to observe how the demo behaves with more traffic; it is not a substitute for real campaign evidence.
Adding a new message creates an unproven challenger. Expect early volatility while the system learns where it belongs.
Simulation traffic pulse
Sends is the global denominator across all segments and arms. Meetings booked is the global positive-reward count; \(47/248 = 19.0\%\) is a useful aggregate health check, but it should not be used to rank arms because traffic is adaptively allocated and segments differ.
List burn counts unsubscribes. The alert rate is \(r_{\text{unsub}}=N_{\text{unsub}}/N_{\text{sends}}\), with a warning above \(0.50\%\). At the posterior level, an unsubscribe adds three \(\beta\) pseudo-counts, encoding that reputational harm costs more than an ordinary miss.
Gate veto count is an observability metric, not a denominator in CTR. It shows how often the demo exercised its safety boundary. A high count can mean the control is working under adversarial pressure; it does not by itself indicate degraded campaign performance.
Additional context
For software engineers
These are service-level counters, not model parameters. Use them for monitoring and alerting. Arm-level sends and outcomes drive posterior updates; global totals summarize system throughput and harm.
A useful invariant is that global sends equal the sum of sends across all segments and arms.
For conversion administrators
Read meetings and unsubscribes together. A campaign with strong bookings but unacceptable list burn is not healthy. Also check absolute counts: one unsubscribe in a tiny sample can create a large temporary rate.
Gate vetoes show prevented risk, not lost conversions from approved copy.
Live belief curves and statistical confidence
Each curve is a Beta distribution: the bandit's current belief about one copy arm's true meeting-booking rate. The x-axis is possible CTR. The curve's shape tells you confidence.
- Wide curve: not enough data yet. The arm may still be good or bad.
- Tall narrow curve: enough evidence has accumulated. The model is more certain.
- Curve shifted right: the arm is believed to have higher CTR.
- Overlapping curves: no clear winner yet; exploration should continue.
- Hollow circle: one Thompson sample drawn from that arm's curve for the current decision. The sample changes on every simulated send.
- Circle with an outer ring: the winning sample. The bandit serves the arm whose sampled CTR is highest; the label above it explains whether that choice exploits the current leader or explores a challenger.
- Truth and dashed line: the arm's fixed underlying CTR in this demo simulation. It generates the simulated outcomes and lets you compare the model's belief with reality. In a production experiment, this value is unknown and must be learned from observed results.
The y-axis is probability density, not probability. A taller peak does not mean a higher CTR; horizontal position indicates CTR, while narrowness indicates concentration. The NIST Beta distribution reference covers the density and shape parameters.
Stable winner
Angle A is narrow and right-shifted. Angle B is lower. Action: keep serving A, archive B only if it remains weak after enough sends.
Uncertain challenger
Angle B is wide and overlaps A. Action: do not archive yet. Let the bandit explore until the credible interval tightens.
Additional context
For software engineers
A curve is a serialized uncertainty state rendered as a density. The area under each curve is one; height alone is not a score. Horizontal position represents plausible CTR values, and width represents how uncertain the model remains.
The dashed truth line exists only because this is a simulator. Treat it like test-fixture data that production code would never receive.
For conversion administrators
Use the curve to answer two separate questions: “Where is this message likely to perform?” and “How sure are we?” A right-shifted but very wide curve may still be too uncertain for a campaign decision.
Do not archive a challenger merely because its current peak is lower when its range still overlaps the leader.
Exploit winner vs explore underdog
The meter classifies historical decisions, not a configured exploration rate. A pull is exploit when the sampled winner is also the arm with the highest posterior mean at that tick. It is explore when uncertainty gives another arm the highest random Thompson sample.
Thompson sampling has no fixed epsilon. Exploration emerges from posterior overlap: wide distributions occasionally produce high draws. As evidence accumulates, weak-arm distributions narrow and their chance of winning a draw falls.
Persistent exploration is not automatically a bug. It can indicate statistically similar arms, sparse traffic, a non-stationary reward process, or noisy outcomes. Investigate posterior overlap and segment quality before forcing exploitation.
Additional context
For software engineers
There is no hard-coded exploration percentage. Random posterior samples implement the policy. As uncertainty contracts, the probability that a weak arm produces the maximum sample naturally decreases.
If exploration never declines, inspect reward ingestion, segment keys, posterior persistence, and whether resets are occurring unexpectedly.
For conversion administrators
Exploration is the cost of learning. It intentionally sends some traffic to copy that is not the current leader so the system can detect a better option.
A high explore share is acceptable early. Later, it should be explained by close-performing messages, limited data, or recent creative changes.
Candidate copy arms
Each card shows the operational and statistical state of a copy angle.
- Claim tags: the evidence-backed claims the message relies on.
- Belief \(\operatorname{Beta}(\alpha,\beta)\): \(\alpha\) grows with meetings; \(\beta\) grows with misses and more sharply with unsubscribes.
- \(P(\text{Best})\): Monte Carlo estimate of how often this arm beats the others.
- 95% credible interval: the plausible range for this arm's CTR based on current evidence.
- Archive copy: removes the arm from future pulls without deleting its history.
Worked example
Start with the excerpt as an engineer would see it in the dashboard, then separate observed state from inferred state.
Worth a 20-minute look?
\(\theta_A\sim\operatorname{Beta}(\alpha=2,\beta=3)\) \(N=3\) archive: \(M_A=0\)
1. Separate copy metadata from experiment data
- 22%
- A verified claim embedded in the email body. It is product evidence, not observed conversion data and not an input to the posterior update.
- 20 minutes
- The proposed meeting duration in the CTA. It also has no statistical role.
- 3 sends
- The number of times this arm was selected for the current segment. This is the arm-local sample count, also shown as \(N=3\).
- 1 click
- One send produced the positive reward event. The UI says click, while the experiment interprets it as a booked-meeting success.
2. Reconstruct the posterior
The model starts each arm with a uniform \(\operatorname{Beta}(1,1)\) prior over its unknown conversion probability \(\theta_A\). Beta is conjugate to the Bernoulli likelihood, so ordinary binary outcomes update its two shape parameters as pseudo-counts:
The raw observed rate is \(1/3=33.3\%\). The displayed estimate is the posterior mean:
The difference is prior smoothing. With only three observations, the two prior pseudo-counts still have substantial influence. As traffic grows, the likelihood dominates and the posterior mean approaches the empirical rate.
Implementation nuance: an unsubscribe applies \(\beta\leftarrow\beta+3\) instead of \(\beta\leftarrow\beta+1\). That is a deliberate utility penalty equivalent to three negative pseudo-observations. Once weighted outcomes are used, interpret \(\operatorname{Beta}(\alpha,\beta)\) as a decision model, not a literal posterior from only independent Bernoulli trials.
3. Read absolute uncertainty
\([6.7\%,80.3\%]\) approximates the central 95% posterior credible interval. The dashboard takes 1,000 samples from \(\operatorname{Beta}(2,3)\), sorts them, and uses draws near \(Q_{0.025}\) and \(Q_{0.975}\). Conditional on the model, roughly 95% of posterior probability lies between those bounds:
This is not a frequentist confidence interval and does not mean 95% of future clicks land in that range. It describes uncertainty about the single latent CTR parameter. The interval is extremely wide because three sends contain little information.
4. Read relative ranking
\(P(\text{Best}_A)=84.5\%\) answers a different question from estimated CTR. For each of 1,000 Monte Carlo rounds, the dashboard draws one \(\theta_i\) from every eligible arm and records which draw is largest. Angle A won about \(845/1000\) rounds.
This probability depends on the competing arms and the current Gate/archive mask. It can change even if Angle A receives no new data, because another arm changed or left the pool. At \(\hat p=0.845\) and \(R=1000\) draws, the Monte Carlo standard error is approximately
That is roughly 1.1 percentage points, so small refresh-to-refresh changes are simulation noise.
5. Read policy state
- Learned leader
- The eligible arm with the highest current \(P(\text{Best})\), not a declaration that learning is complete. Wide intervals can coexist with a leader when competitors are even less promising.
- \(M_A=0\)
- Archiving sets this arm's action mask to zero. Thompson sampling stops selecting it, but \(N\), \(\alpha\), \(\beta\), and historical outcomes remain intact for auditability or restoration.
Additional context
For software engineers
The arm card combines three data domains: immutable creative metadata, mutable counters, and derived statistics. Debug them separately. A claim-tag problem is configuration; a send-count problem is event ingestion; a confidence problem is model computation.
Archiving should be reversible and must preserve historical state. It changes eligibility, not evidence.
For conversion administrators
Start with message identity and approved claims, then check volume, estimated CTR, uncertainty, and relative rank. Never treat the “Learned leader” label as automatic permission to launch broadly.
A decision-ready arm needs enough sends, acceptable list health, a credible advantage, and approved copy.
Real-time decision stream
Copy Arm:
A Explore · sample 31.6% Meeting bookedThe feed is an append-only audit view displayed newest-first. Each row records the segment, selected arm, decision classification, sampled \(\theta_i\), timestamp, and observed outcome. The sampled percentage is the random Thompson draw that won this tick; it is not the arm's estimated CTR.
Follow one row through the state transition: selection increments sends; a meeting applies \(\alpha\leftarrow\alpha+1\); an ordinary miss applies \(\beta\leftarrow\beta+1\); an unsubscribe applies \(\beta\leftarrow\beta+3\). The dashboard then recomputes confidence and redraws the posterior for the affected segment.
Use the feed to explain discontinuities. If an arm's estimated CTR drops sharply, inspect recent outcomes rather than assuming a rendering defect. Repeated unsubscribes should produce a faster leftward update than repeated ordinary misses because of the weighted penalty.
Additional context
For software engineers
Treat each feed row as an event in an event-sourced system: decision inputs, chosen action, outcome, and timestamp. Given the prior state and this event, you should be able to reconstruct the next posterior state.
The feed is capped at 50 rows, so it is a debugging window rather than a durable audit log. Production would persist these events outside the browser.
For conversion administrators
Use the feed to connect aggregate movement to individual sends. If list burn rises, look for which message and audience produced unsubscribes. If a challenger jumps in rank, look for a recent run of meetings.
One event is evidence, not a trend. Look for repeated outcomes before changing campaign policy.
Specialist diagnostics
Interpret the example values
1.7
0.42
1.86
2
Estimated regret accumulates the simulated opportunity cost of each choice:
A value of \(R_T=1.7\) means 1.7 expected successes were forgone across the run. This is available only because the demo knows each arm's hidden truth, \(\theta_i\); production cannot compute true regret directly.
Policy entropy is computed over each active arm's \(P(\text{Best})\):
It measures how diffuse the current ranking is. For two arms, entropy approaches \(0\) when one dominates and peaks at \(\log 2\approx0.693\) when both are equally likely to be best. Entropy depends on pool size, \(K\), so compare it only with the same eligible-arm count.
Average KL divergence measures how far each posterior has moved from its \(\operatorname{Beta}(1,1)\) prior, then averages across active arms:
Higher means more belief change, not necessarily better performance. KL is asymmetric and measured in nats here. SciPy's entropy and relative-entropy reference gives the definitions.
Active arm pool is the count after archive and Gate masks. It is the denominator for competition and changes the interpretation of entropy and \(P(\text{Best})\).
Additional context
For software engineers
These metrics diagnose the learning process rather than campaign success. Regret requires simulator truth. Entropy summarizes routing uncertainty. KL divergence summarizes model movement from initialization. Pool size supplies the comparison context.
Alert on impossible combinations, not arbitrary values: for example, an active pool of zero means selection cannot proceed, while high KL with zero sends suggests corrupted state.
For conversion administrators
Use entropy to ask whether the system has a clear preference, not whether the campaign is good. Use KL to ask whether it has learned much, not whether performance improved.
A confidently learned poor result is still poor. Always pair diagnostics with estimated CTR, credible intervals, meetings, and list burn.
Head-to-head win probability matrix
| Arm | A | B |
|---|---|---|
| A | — | 78.4% |
| B | 21.6% | — |
Each Monte Carlo round draws one plausible CTR from every active posterior. Cell \((A,B)=78.4\%\) estimates \(P(\theta_A>\theta_B)\): A's draw exceeded B's in roughly 784 of 1,000 rounds. With continuous Beta distributions, ties have probability zero, so
The diagonal is undefined because comparing an arm with itself has no decision value. This matrix answers pairwise superiority, while \(P(\text{Best})\) asks whether an arm beats all competitors simultaneously. With three or more arms, \(P(\theta_A>\theta_B)\) can be high while A's \(P(\text{Best})\) remains modest because arm C often wins.
Treat 70% highlighting as a dashboard heuristic, not a universal statistical threshold. Use the interval width, business cost, and sample volume when deciding whether the evidence is actionable.
Additional context
For software engineers
The matrix is computed from the same 1,000 synchronized Monte Carlo rounds used for ranking. For every draw, compare each ordered pair and increment the corresponding cell.
Useful invariants: the diagonal is empty, every off-diagonal value lies in \([0,1]\), and opposite cells sum to approximately one.
For conversion administrators
Read across a row as “How often does this message beat each alternative?” A green cell means directional evidence, not guaranteed future performance.
Use pairwise comparisons when deciding between two specific creatives. Use \(P(\text{Best})\) when deciding which creative leads the entire active set.
Posterior parameter table
| Arm | Mean | Mode | Variance | KL div |
|---|---|---|---|---|
| Angle A | 40.00% | 33.33% | 0.04000 | 0.235 |
| Angle B | 20.00% | 0.00% | 0.02667 | 0.636 |
Interpret the example values
A: 40.00%
B: 20.00%
A: 33.33%
B: 0.00%
A: 0.04000
B: 0.02667
A: 0.235
B: 0.636
Turn the table into an action
- Check volume first: confirm sends and outcomes are large enough to support interpretation. Sparse rows produce unstable means and boundary modes.
- Use mean for direction: identify which arm currently has the higher expected CTR.
- Use variance and the credible interval for confidence: determine whether the apparent gap is stable or still dominated by uncertainty.
- Use \(P(\text{Best})\) and the win matrix for comparison: verify that the preferred arm usually beats the alternatives across posterior draws.
- Check business constraints: review unsubscribes, approved claims, audience fit, and the cost of sending weak copy.
- Choose the least destructive action: continue learning when evidence is weak, favor the leader when evidence is directional, and archive only when evidence and business context agree.
Mean is the expected CTR under the posterior and the estimate used to identify the current mean leader. Mode is the peak location when both parameters exceed one:
Mean and mode differ for skewed distributions.
Variance measures posterior spread:
Lower variance means the posterior is more concentrated, but compare variance alongside the mean because probabilities near zero or one naturally have different scale.
KL divergence quantifies information gained relative to the uniform prior. It does not encode direction: a confidently poor arm can have higher KL than a promising but uncertain arm. The table is the numeric representation of the same distributions drawn in the belief chart.
Additional context
For software engineers
This table is a deterministic projection of \(\alpha\) and \(\beta\). Mean, mode, and variance should be reproducible from those two parameters. KL should be reproducible from the posterior and the configured prior.
When the chart and table disagree, verify that both use the same segment, active-arm filter, and posterior snapshot.
For conversion administrators
Mean is the easiest planning estimate. Mode is the single most likely point, but can be unstable with little data. Variance tells you how cautiously to interpret either point.
Prefer a slightly lower estimate with tight uncertainty over a dramatic estimate supported by only a few sends when making a high-cost rollout decision.
Posterior drift log
[00:41:05] CFO Core: Arm B pulled. KL: 0.64, Est CTR: 20.0%, P(Best): 15.5%
Each entry is a compact state snapshot after a pull: timestamp, segment, arm, KL divergence, updated posterior mean, and \(P(\text{Best})\). Read adjacent entries as transitions, not independent events.
One success increments \(\alpha\), usually moving the mean right. One miss increments \(\beta\), moving it left. Either outcome generally reduces \(\operatorname{Var}(\theta)\) as effective evidence increases. An unsubscribe increments \(\beta\) by three, so both the mean and \(D_{\mathrm{KL}}\) can move more sharply.
\(P(\text{Best})\) may move even when the displayed arm was not selected because all arms are re-compared after relevant segment updates. The log retains only the newest 50 entries, so it is an operational debugging buffer rather than durable experiment storage.
Additional context
For software engineers
Use the drift log to verify update ordering: record outcome, mutate posterior, recompute derived statistics, then render. Logging before recomputation produces stale P(Best) values and confusing traces.
Because Monte Carlo estimates are random, repeated computations on unchanged state can differ slightly. Large changes should correspond to evidence or eligibility changes.
For conversion administrators
The log explains why a number moved. A meeting should generally improve that arm's estimated CTR; a miss should reduce it; an unsubscribe should reduce it more sharply.
Small P(Best) changes can be simulation noise. Focus on sustained direction and the outcomes that caused it.
Scenario examples and actions
Scenarios combine several signals. Avoid making operational decisions from one KPI: first confirm eligibility, then inspect outcome quality, posterior uncertainty, and convergence.
Scenario 1: CFO ROI proof is clearly winning
Evidence: high \(P(\text{Best})\), a narrow credible interval, low entropy, and mostly exploit pulls. Action: keep it active and consider archiving weak challengers only after checking their send counts. Promotion still requires copy and claim review; statistical rank does not validate message truth.
Scenario 2: Transparent pricing has few sends and a wide interval
Evidence: lower posterior mean, low N, and substantial interval overlap. Action: do not archive based on point estimate alone. Continue normal exploration or fast-forward the demo, then reassess whether uncertainty actually contracts.
Scenario 3: Planted lie has the highest latent CTR
Evidence: the unsafe arm's simulated truth is high, but it is marked Gate-vetoed and absent from sampling. Action: keep masking enabled. This demonstrates separation of concerns: evidence policy controls eligibility, while the optimizer controls allocation.
Scenario 4: List burn spikes
Evidence: global unsubscribe rate exceeds 0.50%, with recent unsubscribe outcomes concentrated in the feed. Action: pause, identify the contributing segment and arm, inspect absolute counts as well as rate, then archive the arm if the harm is concentrated. A one-event spike at tiny N needs different treatment from sustained burn.
Scenario 5: Entropy remains high after many sends
Evidence: \(P(\text{Best})\) remains diffuse and posterior curves overlap despite substantial traffic. Action: check reward latency, non-stationarity, broad segments, and near-identical arms. More traffic does not fix a misspecified reward or mixed population; consider splitting the segment or redesigning the challenger.
Additional context
For software engineers
Use a fixed triage order: validate event ingestion, validate segment and arm keys, confirm Gate/archive masks, reconstruct posterior updates, then inspect Monte Carlo output. This separates data defects from expected statistical uncertainty.
Capture the state snapshot before applying a corrective action so the behavior is reproducible.
For conversion administrators
Use a fixed decision order: confirm the copy is eligible, check list health, check sample size and uncertainty, compare alternatives, then decide whether to continue, pause, archive, or promote.
Document both the evidence and the business threshold behind the action. “Highest CTR” alone is not a complete campaign decision.