Why AskUserQuestionTool Makes Java AI Ask Clarifying Questions First
The article explains how Spring AI's AskUserQuestionTool brings an interview‑style questioning model to Java, letting AI clarify ambiguous requirements before generating code, and provides step‑by‑step implementation details, code samples, and a walkthrough of the underlying tool architecture.
Vibe Coding illustrates a common problem: when users ask AI for a feature like "login", the model may assume a default implementation (username/password) while the user actually wants a different approach (e.g., phone‑code login). This stems from language ambiguity and highlights the need for AI to ask clarification questions before acting.
Claude Code’s Interview Model
Claude Code already uses an "Interview Model" that asks multiple‑choice questions to resolve vague requirements, ensuring the AI only proceeds after the user has clarified their intent.
AskUserQuestionTool: A Java‑Based Requirement Clarification Assistant
Spring AI’s AskUserQuestionTool brings this questioning capability to the Java ecosystem. It is a standard Spring AI Tool that agents can invoke when they encounter uncertain steps, prompting the user for answers and then continuing execution.
The tool revolves around three core concepts:
Question : contains the question text, a short header for UI, a list of options (each with a label and description), and a flag indicating whether multiple selections are allowed.
QuestionHandler : responsible for presenting questions to the user, collecting responses, and returning a map of answers.
AskUserQuestionTool : serializes the Question objects, sends them to the user, parses the returned answers, and feeds them back to the agent.
Three‑Line Quick Start
Add the Maven dependency:
<dependency>
<groupId>org.springaicommunity</groupId>
<artifactId>spring-ai-agent-utils</artifactId>
<version>0.5.0</version>
</dependency>Implement a console‑based QuestionHandler:
private static Map<String, String> handleQuestions(List<Question> questions) {
Map<String, String> answers = new HashMap<>();
Scanner scanner = new Scanner(System.in);
for (Question q : questions) {
System.out.println("
" + q.header() + ": " + q.question());
for (int i = 0; i < q.options().size(); i++) {
Option opt = q.options().get(i);
System.out.printf(" %d. %s - %s%n", i + 1, opt.label(), opt.description());
}
String response = scanner.nextLine().trim();
answers.put(q.question(), response);
}
return answers;
}Register the tool with the ChatClient:
ChatClient chatClient = chatClientBuilder
.defaultTools(AskUserQuestionTool.builder()
.questionHandler(yourHandler::handleQuestions)
.build())
.build();Tool Implementation Details
The tool is annotated with @Tool, exposing the method askUserQuestion that accepts a list of Question objects and an optional map of previously collected answers.
@Tool(name = "AskUserQuestionTool",
description = """
When the agent needs to ask the user for clarification, invoke this tool.
Scenarios include:
1. Collecting user preferences
2. Disambiguating vague commands
3. Soliciting feedback during execution
4. Choosing the next step
""")
public String askUserQuestion(
@ToolParam(description = "List of questions (1‑4)") List<Question> questions,
@ToolParam(description = "User answers collected by the UI", required = false)
Map<String, String> answers) { ... }The Question record defines the data structure:
public record Question(
String question, // e.g., "Which library should we use?"
String header, // short label, max 12 chars
List<Option> options,
Boolean multiSelect) { }Each Option simply holds a label and a description:
public record Option(String label, String description) { }Interaction Flow: How the AI Decides to Call the Tool
When a user says, "Help me build a blog system," the AI detects that the request is too vague (uncertain about feature scope, tech stack, deployment). It then invokes askUserQuestion with a set of clarifying questions such as:
[
{
"question": "Which type of blog system do you want?",
"header": "Feature Scope",
"options": [
{"label": "Minimal", "description": "Only posts and comments"},
{"label": "Standard", "description": "Adds tags, categories, search"},
{"label": "Advanced", "description": "Multi‑author, subscriptions, paywall"}
],
"multiSelect": false
}
]The QuestionHandler formats and displays these options, the user selects "Standard", and the answer is fed back to the AI, which then proceeds with the clarified requirement.
Conclusion
AskUserQuestionTool embodies a simple yet powerful principle: when the AI is uncertain, ask the user. This mirrors good product‑management practice of iteratively confirming requirements, leading to fewer rework cycles and more accurate code generation.
Java Architecture Diary
Committed to sharing original, high‑quality technical articles; no fluff or promotional content.
How this landed with the community
Was this worth your time?
0 Comments
Thoughtful readers leave field notes, pushback, and hard-won operational detail here.
