Skip to content
All insights
Agent reliabilityDraft· 7 min read

Confidence is not a safety mechanism

Confidence scores tell you how certain a model is. They tell you nothing about what it costs to be wrong — and those are different questions that production systems keep conflating.

Byline pendingUnpublished draft — no date

The most common design in agentic systems is a confidence threshold. Above 0.9, act. Below it, escalate to a person. It is an appealing design because it is one number and one comparison, and because it feels like a safety mechanism.

It is not one. A confidence score is an estimate of correctness. Whether an action should require a human is a question about consequence. Correctness and consequence are independent, and a single threshold collapses them into each other.

Two systems, one threshold

Consider two actions in the same support workflow. One re-sends a password reset email. The other issues a £440 refund. Suppose the agent is 0.93 confident in both.

The first action, taken wrongly, produces a mildly confusing email and no lasting harm. The second, taken wrongly, moves money out of the business, and the recovery path involves a conversation nobody wants to have. The confidence is identical. The decision should not be.

Confidence is a property of the prediction. Authority should be a property of the action.

Separate the two axes

The design that holds up is boring: classify actions by consequence in configuration, and let confidence operate only within a class. An action class carries its own rules, and those rules live in code that a team can read and change without touching a prompt.

ts
type ActionClass = 'reversible' | 'costly' | 'always_review'

interface ActionPolicy {
  class: ActionClass
  /** Confidence below this escalates, within the class's own rules. */
  minConfidence: number
  /** Hard ceiling enforced in code, never by the model. */
  maxAmount?: number
  /** Per-account limit, independent of confidence. */
  rateLimit?: { count: number; perHours: number }
}

const policies: Record<string, ActionPolicy> = {
  'auth.resend_reset':  { class: 'reversible',    minConfidence: 0.75 },
  'billing.apply_credit': { class: 'costly',      minConfidence: 0.95, maxAmount: 50_00 },
  'billing.issue_refund': { class: 'always_review', minConfidence: 1 },
}
Authority expressed as configuration rather than inferred from a score.

The third entry is the important one. Its minimum confidence is 1, which is unreachable in practice, and that is deliberate: refunds always involve a person. Encoding that as an unreachable threshold rather than a special case keeps the decision logic uniform while making the intent obvious to anyone reading the file.

Calibration makes this worse than it looks

There is a second problem. A threshold assumes the score is calibrated — that outputs scored 0.9 are correct about 90% of the time. Language model confidence frequently is not calibrated, and it tends to be miscalibrated precisely where it matters most.

  • Confidence is often high on inputs that are well-formed but subtly unusual.
  • It can be high on fluent, plausible fabrication — the failure mode you most need to catch.
  • It shifts when the prompt, the model version or the retrieved context changes, so a threshold tuned in March may not mean the same thing in June.

If you do use a threshold, measure what it actually buys you. Plot the escalation rate against the silent-error rate at several thresholds on a fixture set. In most systems we have built, the curve is flatter than expected: raising the threshold escalates many more cases while catching only a few more real errors, because the errors that reach production are usually confident ones.

Deterministic checks catch what confidence cannot

The cheapest reliability win in most agentic systems is not a better model or a tuned threshold. It is ordinary validation code: does the output parse against the schema, do the line items sum to the total, is this supplier known, is the amount within the written limit.

These checks have a property no confidence score has. They fail the same way every time, and they are unit testable. A system whose safety rests on tested functions can be reasoned about. A system whose safety rests on a float cannot.

  • RetrievalDraft

    Retrieval is a ranking problem, not a vector problem

    Most RAG systems that disappoint are not failing at embedding. They are failing at everything that happens before and after it — chunking, ranking, and knowing when to return nothing.

    8 min read
  • EvaluationDraft

    Write the evaluation set before the prompt

    An evaluation set written before implementation is a specification. Written afterwards, it is a description of whatever the system already does.

    6 min read
07Next step

Have something difficult in mind?

We like ambitious problems — the ones with awkward constraints, messy data and a real cost attached to getting them wrong. Tell us what you are building and what makes it hard.

Good fit
A real workflow with real constraints, an internal owner who can make decisions, and a problem where being wrong actually matters.
Less good fit
A chatbot with no defined job, a fixed-scope rebuild of something that already works, or a project that needs to look finished before it is understood.