Concept
The confidence gate¶
A head that knows when it is unsure can step aside. The gate turns that into a threshold you set once.
The head replaces an LLM call, but it does not have to answer every decision. A confidence-gated fallback (paper App. N.3) marks a decision whose confidence is below a threshold as deferred, and the agent then calls the original LLM component for that decision. Deferral never makes the agent worse than before the head: it falls back to the component the head replaced. It costs what the LLM costs, so the deferral rate is the number to watch.
The paper reports that TabHead's confidence flags its own errors at AUROC 0.88, which is why a gate can work, and App. O.2 runs the gate in the loop.
The confidence signal¶
For a ranking, tabagent.tabhead.confidence gives one value per decision, by one of two methods:
| Method | Definition | Use |
|---|---|---|
largest_gap (default) |
the largest drop between consecutive ranked scores | cutoff-free, so deployable |
margin_at_r |
score of the R-th candidate minus score of the (R+1)-th, where R is the size of the relevant set | needs R, an oracle quantity, so for analysis only |
For a single-class decision, the confidence is the probability of the predicted class.
Use the gate¶
head = tabagent.onboard("./logs", decision="ToolShortlist", gate_coverage=0.9)
head.gate_threshold # decisions below this confidence are deferred
gate_coverage=0.9 calibrates the threshold on the cross-validated decisions so that 90% stay with the head
and the least confident 10% go back to the LLM. On the command line: tabagent onboard ... --gate-coverage 0.9.
The gate is calibrated on ranking scores, so it does not apply to kind="single".
# a TabAgent (rows that carry the training columns)
out = agent.decide(rows, k=5, defer_below=0.5, fallback=ask_the_llm)
out[["decision", "candidate", "confidence", "deferred"]]
out.attrs["fallback"] # what `fallback` returned for the deferred decisions' rows
# an onboarded head (a trajectory prefix)
head.decide(prefix, candidates, k=5, defer_below=0.5) # defaults to the calibrated gate_threshold
fallback is called with the rows of the deferred decisions, typically the original LLM component, and its return
value is stored in result.attrs["fallback"].
Choose a threshold¶
tabagent.tabhead.risk_coverage(confidence_values, correct) returns, for each coverage level (the fraction of
decisions kept), the mean correctness of the kept decisions. Plot it to see how much quality you buy by deferring
more, which is the paper's Fig. 14.
Deferral is not only the gate¶
A decision is also deferred when the extractor fails on the prefix (a field the training prefixes had is missing,
the code raises, the sandbox cannot start), whatever its confidence, and, in the HTTP service, when the extraction
runs past its deadline. In every case the answer carries "deferred": true, and error says why unless the cause
is the gate. The agent's side of the contract is in the
production runbook.
When the gate misleads¶
- Calibration is a property of the training distribution. If the live decisions drift, the deferral rate moves with no change to the head: see Drift, and when to re-onboard.
- A deferral rate that rises with no drift means the threshold no longer fits: recalibrate with
onboard --gate-coverageon recent logs.