Inland water, Bermuda watercolor
← Back to blog

AI SAFETY

How to Handle Ambiguous User Requests (and Prevent Dangerous Interpretations)

Asking a clarifying question every time an agent is unsure is not safety, it's a tax users stop paying. The judgment that matters is choosing between ask, assume out loud, and refuse.

Paulina XuMay 11, 202611 min
AI SafetyAgentsDesign

TL;DR

"Ask a clarifying question" is the answer every guide gives for ambiguity, and it's often wrong. An agent that stops to ask about every vague request is technically safe and practically useless; a person who wanted a conversation would have started one.

Take an agent told to "clean up the project files." Asking what that means is correct if the tool underneath is rm -rf. It's needless friction if the tool underneath is "archive files untouched for 90 days" and the agent already knows that's what "clean up" has meant every other time this month.

Detecting ambiguity isn't the hard part; every non-trivial request has some. The hard part is choosing what to do about it: proceed on a stated assumption, ask one specific question, or refuse outright, and picking correctly depends on whether the action can be undone and whether a question would actually resolve anything.

We think that choice should be explicit and testable, not left to a model's mood. Score the request, route it by what's reversible and what a confirmation would actually buy you, and log every assumption the same way you'd log a clarifying question, because both are guesses the agent made on your behalf.

Overview

Take an agent with access to a project's file storage, given the instruction "clean up the project files." The words admit several readings: delete anything untouched in ninety days, remove build artifacts, or archive completed work into cold storage. A guide that says "when in doubt, ask" would have this agent stop and request clarification every time someone phrases a routine request the way people actually phrase routine requests, which is imprecisely. Do that consistently and the agent stops feeling like an assistant and starts feeling like a form you fill out.

The opposite failure is worse and gets more attention: an agent that guesses instead of asking, picks the reading that maximizes how confident it sounds, and deletes something nobody meant for it to delete. Most writing on this topic treats the fix as one lever, ask more, and stops there. That's half a solution. The harder and more useful problem is deciding, for a given ambiguous request, which of three responses is correct: proceed on a stated assumption, ask a specific question, or decline the request entirely.

We think that decision has to be made on purpose, tool by tool, because the cost of guessing wrong scales with what the agent can actually do. A misread that produces a slightly wrong summary costs a re-read. A misread that empties a table, emails ten thousand people, or moves money costs a great deal more, and no amount of clarification-first prompting substitutes for knowing, in advance, which of those two situations you're in.

The goal isn't to eliminate guessing. It's to make sure only cheap, reversible guesses happen silently, and everything else either gets a stated assumption on the record, a specific question, or a flat no.

Two Kinds of Ambiguity

It helps to separate two problems that get treated as one. The first is lexical ambiguity: the words themselves support more than one parse. "Remove the users" could mean delete the rows, revoke access, or unassign them from a project, and the sentence alone can't settle which. The second is pragmatic ambiguity: the words are perfectly clear, but the scope or success criteria aren't. "Send the update to the team" has one grammatical reading and an unresolved question hiding in it: which team, which update, and how far "send" is supposed to reach.

Left alone, a model resolves both kinds the same way: it picks whichever interpretation is statistically most likely given the phrasing, which is exactly the reading most likely to run without triggering any internal doubt. Fluency is the trap here. A model can produce a well-formed plan to "archive the old accounts" without having settled which accounts, how old, or whether archiving means deactivation or deletion. The plan reads like competence. Underneath it is a coin flip the reader can't see.

Ask, Assume, or Refuse

Every ambiguous request has to land in one of three buckets, and the routing should depend on two things: can the action be undone, and would a question actually narrow it down.

Assume and act, but say so. When the guess is cheap to reverse and there's a reading that's clearly more likely than the others, stopping to ask adds friction without adding safety. The agent proceeds and states the assumption plainly, in the response or in a log a person can review afterward.

Ask one specific question. When the action isn't trivially reversible, or no reading is clearly favored, a targeted question is worth the friction. The question should name the actual fork in the road, not invite a general restatement of the request.

Refuse. When the action is hard to undo and no available question would meaningfully narrow the guess, or when answering would require information nobody in the loop can actually supply, asking is theater. Say what's missing and stop.

yes, cheap to undo

yes

no

no, hard to undo

yes

no answer available,
or stakes too high either way

ambiguous request

Reversible
if wrong?

One reading clearly
more likely?

Assume, act,
state the assumption

Ask one specific
question, then act

Would a question
actually resolve it?

Ask, then require
explicit confirmation

Refuse,
state what's missing

Figure 1 — Routing an ambiguous request. Reversibility decides whether silence is affordable; resolvability decides whether asking is worth the interruption.

Scoring the Request Before Routing It

The routing above needs a number to key off, not a vibe. A small model call can produce one.

python
def ambiguity_score(user_input: str) -> float:
    prompt = f"""
    Score how ambiguous this request is from 0 to 1.
    0 = one clear reading (specific goal, target, constraints)
    1 = many plausible readings, unclear target

    Request: "{user_input}"
    Output only a number between 0 and 1, no other text.
    """
    raw = model_call(prompt, temperature=0).strip()
    try:
        return max(0.0, min(1.0, float(raw)))
    except ValueError:
        return 1.0  # if the detector itself is unsure, treat it as ambiguous

The parsing fallback is the important line. When the detector can't produce a clean number, the safe default is to treat the request as maximally ambiguous rather than wave it through, and that same instinct, fail toward caution when uncertain, is what should govern every threshold built on top of this score.

The thresholds themselves are not universal constants; they're where reversibility gets encoded per tool.

python
def route(score: float, reversible: bool) -> str:
    if reversible:
        return "assume" if score < 0.6 else "ask"
    return "ask_and_confirm" if score < 0.6 else "refuse"

A read-only research assistant can carry a high threshold before it bothers anyone. An agent wired to a production database or a payments API should pull reversible to False for nearly everything it touches, which routes almost all its ambiguity through confirmation or refusal by construction, not by hoping the score comes out low.

Assuming Out Loud

This is the bucket most guides skip, and it's the one that actually keeps an agent usable. For low-stakes, reversible actions, the correct behavior isn't silence and it isn't a question. It's proceeding on the most likely reading while making that reading visible, so a wrong guess is cheap to catch and cheap to correct.

python
def assume_and_act(user_input: str, interpretation: str):
    result = act(interpretation)
    return {
        "result": result,
        "assumed": interpretation,
        "note": f"Interpreted \"{user_input}\" as: {interpretation}. Say so if that's wrong.",
    }

The difference between this and silent guessing is entirely in the note. A summary that quietly picked one of three plausible meetings to summarize is a guess hidden inside a confident answer. A summary that says which meeting it picked, and invites a correction, is the same guess made accountable. Log these the same way you'd log a clarifying question or a confirmation. An assumption is still a decision the agent made on the user's behalf, and if it's wrong often enough for a given phrasing, that's a signal the threshold or the tool description needs to change, not a one-off mistake to shrug off.

Confirmation for What Can't Be Undone

When the action is hard to reverse and a question can genuinely narrow the guess, the question earns its interruption, and the response to it has to be unambiguous itself.

python
def require_confirmation(agent, interpretation: str, user_input: str) -> bool:
    prompt = f"""
    The user said: "{user_input}"
    I interpret this as: "{interpretation}"
    Should I proceed? Reply only "YES" or "NO".
    """
    response = agent(prompt).strip().upper()
    return response == "YES"

Anything short of an exact "YES" fails closed: a hedge, a follow-up question, silence, all cancel the action. For genuinely irreversible operations, go one step further and ask the user to restate the specific thing being confirmed rather than answer yes or no, so a reflexive "yes" given to a different question can't be reused as consent for this one. The value of a confirmation gate is entirely in what it forces the user to react to: naming the exact account, the exact amount, the exact recipient, rather than the vague verb they started with.

A restated action is the load-bearing part of any confirmation. "Should I proceed?" confirms nothing. "Should I delete 214 rows from the customers table where last_login is null?" confirms the thing that's actually about to happen.

When to Refuse

Refusal is the response that gets skipped most often, usually because it feels like giving up. It's the correct move whenever asking wouldn't actually help: the person who could answer isn't in the loop, the request is ambiguous in a way no single follow-up would resolve, or the stakes are high enough that even a confirmed guess isn't good enough without a person who has the authority to make the call.

Take a request to "notify the affected customers" after an incident, sent to an agent with no defined list of who's affected and no defined message. One clarifying question won't fix that; the request needs a scoped list and approved language from someone with the authority to send it, and the agent's job is to say exactly that and stop, not to ask a narrower version of the same unanswerable question and proceed once it gets a reply.

The same applies when the ambiguity itself looks engineered: a request folded into a document the agent retrieved, rather than typed by the person it's working for. Asking a clarifying question about an instruction that arrived through an untrusted channel just gives whatever planted it a second chance to answer convincingly. The safer move is to refuse to act on it and surface it to a person, full stop.

Conclusion

A guide that ends with "when unsure, ask" has just swapped one failure mode for a milder one: confident wrong guesses traded for an agent that interrupts constantly and teaches people to stop trusting it with anything non-trivial. Both failures trace back to the same missing decision. Nobody decided, ahead of time, which requests deserve a silent assumption, which deserve a question, and which deserve a refusal.

We think that decision belongs in the design, not in the moment. Score the request, route it by whether the action is reversible and whether a question would actually resolve anything, state every assumption out loud so it's cheap to catch, make confirmations restate the specific thing about to happen, and give the agent a real way to say no when asking wouldn't help. An agent that never asks anything is dangerous. One that asks about everything is just slow to be dangerous in a different way.