The Escalation Path Is Part of the Design
An agent with no defined way to stop will improvise one, and its improvisation is a confident answer. Escalation deserves a tool, a destination, and a metric — and one field that stops the human starting over.
Ask most teams what their agent does when it can't complete a task and you'll get an answer about error handling — retries, timeouts, a fallback message. That covers the case where something broke. It doesn't cover the more common and more damaging case: the agent can technically proceed, shouldn't, and does anyway.
An agent with no defined way to stop and hand over will improvise one, and its improvisation is usually to produce a confident answer.
Four situations that need an exit
Missing information. The request is under-specified and the agent doesn't have what it needs. Without an escalation path it picks the most likely interpretation and proceeds. Sometimes right; when wrong, wrong in a way nobody notices, because the output doesn't mention that a choice was made.
Low confidence in a consequential decision. The agent can act but shouldn't without a check. This needs to be available as a decision the agent can make, rather than a policy applied uniformly from outside.
Out of scope. The request is legitimate and this agent isn't the right handler. Without a route, it attempts the task with the wrong tools.
Repeated failure. Three attempts, three failures, and the fourth won't be different. Something must decide to stop, and "the turn limit" is a poor decider — it stops without telling anyone why.
Make handing over a first-class action
The mechanism is a tool the agent can call, not a special output format to be parsed:
escalate(
reason: enum[missing_info, low_confidence, out_of_scope, repeated_failure],
question: string, # the specific thing needed
gathered: string, # what it already established — do not discard
attempted: string[], # what it tried, so nobody repeats it
suggested_next: string
)
Two fields carry most of the value and are the ones usually missing. gathered preserves the work done so far — a human picking this up shouldn't restart from zero, and an escalation that throws away twenty turns of investigation is barely better than a failure. attempted stops the human from re-treading the same ground.
Making it a tool call also means it appears in the trace, gets counted, and can be asserted on in evals. An escalation buried in prose does none of those.
Ask a question rather than escalating, when a question would do
For missing information, the lighter option is often better: ask the user, in-conversation, and continue when they answer.
Worth being explicit about when each applies:
- Ask when the user is present, the question is small, and answering unblocks immediately.
- Escalate when the user can't resolve it, the run is asynchronous, or the block requires authority the user doesn't have.
⚠️ Many agents do neither, because the prompt frames asking a question as a failure to be helpful. If you want clarifying questions, say so explicitly and make sure your eval suite contains cases where asking is the correct answer. Otherwise the model optimizes toward confident guessing, which is what "be helpful" reads as under ambiguity.
Route the escalation somewhere real
An escalation that lands in a log nobody reads is the same as no escalation. Each reason should have a destination: a queue, a channel, a ticket, an assigned person. And the response has to be able to come back into the run — a resumable run that receives the missing information and continues is enormously more useful than one that has to be restarted with a better prompt.
🔍 The metrics that tell you it's calibrated
Escalation rate is a tuning dial with a wrong setting at each end:
- Near zero — the agent has no working exit and is guessing under ambiguity. Check by sampling: how many completed runs involved an unstated assumption?
- Very high — it's escalating things it could handle, and the humans will start ignoring the queue.
- The useful number: what fraction of escalations the human resolves differently from what the agent would have done. High means the escalations are earning their cost. Near zero means the agent should have proceeded, and the threshold is too conservative.
That last metric requires recording what the agent would have done, which costs one extra field and turns escalation tuning from opinion into measurement.
The takeaway
Agents need a defined way to stop that isn't an error. Give escalation its own tool, with the reason, the specific question, and — critically — the work already done. Route each reason to a real destination, allow the answer back into the run, and measure how often a human decides differently. An agent that can say "I need something I don't have" is more useful than one that always produces an answer, and it's the same agent with one more tool.