A bank row router makes one decision per row: does this parsed transaction pass as clean, or does it go to a bigger model for a second look? Teams usually report the cheap model's accuracy and move on. That number hides the mistake that matters. In a cascade, an error where a clean row is escalated costs money and latency, which is visible and self-correcting in your bill. An error where a dirty row is passed as clean costs nothing at the moment it happens and surfaces months later in a reconciliation break.
The two error types are not symmetric per row, and the metrics literature is explicit that which metric matters depends on the cost of each kind of misclassification and on class balance (Google's classification metrics crash course). Bank rows are the extreme case: dirty rows are a small minority, so a model that labels every row clean scores very high accuracy and is worthless as a gate.
The right lens is precision on the clean label, and specifically its complement. The false-clean rate is:
false_clean_rate = rows labeled clean that are actually dirty
---------------------------------------
all rows labeled clean
This is the error you never see in logs, and it is the only input that should move your threshold. It also lines up with the broader cascade literature. Work on small-to-large routing finds that confidence signals are task-dependent and can stay high while the small model is wrong, which makes the measured miss rate, not the model's self-reported confidence, the thing to calibrate against (Hossen et al. on confidence-based routing). A calibration-first router treats threshold choice as constrained cost minimization on a calibrated error probability rather than a tuning exercise, and reports cutting inference cost by 31% at micro-F1 0.91 on a production named entity workload with 75,000 labeled queries (UCCI on calibrated uncertainty for cascade routing). The lesson: measure first, then set a number.



