One of the wonders of Claude Code is their AskUserQuestion tool. Instead of scrolling through walls of text, this small widget catches your attention and walks you through a list of questions. These lifetime-improvement bits hook me more and more and make AI simpler to use overall — especially the idea of constraining the question to a set of answers while keeping the ability to say your own.
Why Agents Should Ask, Not Guess
Assume you have a database of product sales and an agentIn Limerence, an agent is an AI assistant connected to your database that translates plain-language questions into SQL — the query language databases understand. ready to query it. You ask what is the top-most selling product. That question is ambiguous. Top-most selling can mean highest revenue, highest unit count, most orders, or most repeat purchases.At one company "top-selling" means revenue. At another it means units moved. There is no universal default — only local convention. This is why teaching agents your business language matters so much. Each interpretation produces a different SQL query and a different answer.
Most agents guess. They pick an interpretation, run a query, and hope for the best. If they guess wrong, you notice only after reading the result — if you notice at all. The cost of a wrong guess is not a failed query; it is a
confident, wrong answer that looks right.
"What is the top-selling product?"
Same question. Three interpretations. Three different answers.
SELECT name, SUM(price * qty) AS revenue
FROM orders
JOIN products ON orders.product_id = products.id
GROUP BY name
ORDER BY revenue DESC
LIMIT 1| Product | Revenue |
|---|---|
| MacBook Pro | $1,240,000 |
Our agent does something different. When it detects ambiguity, it stops. It
calls a toolA function the AI model can invoke during a conversation. named render_ask_user_question, and the conversation pauses until you respond. No guessing. No silent assumptions.
Pause, Ask, Resume
When ambiguity appears, the agent pauses the conversation and asks a structured question. You answer inside a focused UI. Only then does the agent continue. That is the whole loop: stop at the moment assumptions would leak into SQL, collect the missing context, then resume with a better answer.
The Wizard
While a question is pending, the chat input disappears. In its place, a multi-step wizard sticks to the bottom of the conversation. This is a deliberate UX choice: the interaction is modal. You cannot send a new message until you answer. The agent asked a question; it expects an answer before it proceeds.
Each question is one step. A progress bar shows dots — one per question, filling as you advance. Back and Next navigate between steps. The final step validates every answer before submitting.
Four Question Types
The tool supports four modes of asking, each suited to a different kind of ambiguity. Scroll through each one below — they are fully interactive.
The Escape Hatches
Every question — regardless of type — gets two extras the agent never defines.
- Other
A text input at the bottom of every option list. The agent is explicitly told never to include an "Other" choice; the UI always adds one. You are never locked into the agent's worldview. The submitted payload preserves both facts: that you rejected the predefined list and the exact replacement you wrote.
- Notes
An optional textarea below every question. Select an option but add commentary: "Last 30 days, but exclude the holiday week." This is where caveats, exceptions, definitions, and business rules belong. The agent receives both the selection and the note, and acts on both.
From Answers to Tool Output
On submit, the wizard serializes your answers into a structured object — which option you picked, any custom text, any notes — and writes it as the tool output. The AI SDK detects that all pending tools now have outputs and automatically fires the next turn. The conversation resumes, and the agent continues with your answers embedded in its context.
From the agent's perspective, it called a function and got back a clean, structured response. From yours, you had a focused interaction that took seconds.
Once that visible loop is clear, the implementation becomes easier to explain. Different models handle this loop with varying degrees of skill — comparing them systematically helps you find which one asks the right questions for your data.
One Boolean That Controls the Whole Gate
The Approval Gate
Here is the engineering decision that makes all of this work: a single boolean flag called needsApproval.
Every tool in our system is registered in a frontend component registry — a mapping from tool name to React component. Most tools (like bash or readFile) are auto-resolved: the moment the model calls them, the frontend immediately writes "rendered" back as the tool output, and the conversation continues without interruption.
render_ask_user_question is different. Its registry entry sets needsApproval: true. That one flag propagates through four layers simultaneously:
- 1
The tool call handler skips auto-resolution. The tool stays in "input-available" state.
- 2
The pending-tool detector scans messages in reverse, finds the unresolved tool, and replaces the chat input with the wizard.
- 3
The conversation timeline renders only the tool's label header — not the full widget — to avoid duplication.
- 4
The auto-continue mechanism refuses to send the next turn to the backend until every pending tool has an output.
◆Key Takeaway
Four behaviors. One flag. Adding a new approval-gated tool to the system requires setting this boolean and nothing else.
Guiding the Model
The tool's schema is defined once, on the frontend. Each request sends it to the model as JSON Schema — no backend duplication.
The system prompt tells the model: when a request is ambiguous or missing details, call the tool before writing SQL. When the user answers through the tool, embed the value as a literal in the query, not as a parameter. The frontend cannot substitute parameters at render time.
A preprocessing step catches a common model mistake: omitting the type
field on a question. An object with options but no type becomes "choice".
One with sql but no type becomes "query_choice". The model need not be
perfect; the system absorbs its rough edges.
Feeding Memory
The query is ambiguous — multiple interpretations detected.
The escape hatches — "Other" and "Notes" — do more than collect answers. They feed the agent's memory.A per-user store of preferences and corrections that the agent recalls in future conversations.
When you type a custom answer or add a note, the tool output includes a
memoryHint: a short signal telling the model that the response contains
something personal — a preference, a correction, context worth remembering. The
model reads this hint and decides whether to save a memory.
Memory saving is not automatic and not guaranteed. The model writes a small markdown file to a virtual filesystem backed by PostgreSQL, scoped to you and to that specific agent.
Markdown on Postgres sounds odd, but it lets the model read and write memories using the same file-manipulation tools it already has — no new API to learn.
On future conversations, the agent loads a memory index and re-injects it as context every few turns. The next time you ask about "top-selling products," the agent already knows you mean revenue.
◆Key Takeaway
This is the closed loop: ambiguity triggers a question, the question captures a preference, the preference becomes a memory, and the memory prevents the same question from being asked again. Each interaction makes the next one faster.
There is a subtlety here worth noting. The model does not save every answer — only custom ones. If you pick a predefined option and move on, no memory is written. Memories are reserved for the moments where you override the agent's assumptions. Those are the moments that carry signal. These high-signal answers also feed into datasets for fine-tuning — closing the loop between live interaction and offline model improvement.
How business context, definitions, and rules help agents generate more accurate queries — the other half of this memory loop.
Image and File Uploads as Question Types
We are looking into adding an image and file upload question type — let the agent ask "show me a screenshot of the report you mean" or "upload the CSV you want to query." The wizard already handles structured input well. Unstructured input is the next frontier.