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.

Java Architecture Diary
Java Architecture Diary
Java Architecture Diary
Why AskUserQuestionTool Makes Java AI Ask Clarifying Questions First

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.

claude code interview model
claude code interview model

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.

JavaSpring AIRequirement ClarificationAI toolAskUserQuestionTool
Java Architecture Diary
Written by

Java Architecture Diary

Committed to sharing original, high‑quality technical articles; no fluff or promotional content.

0 followers
Reader feedback

How this landed with the community

Sign in to like

Rate this article

Was this worth your time?

Sign in to rate
Discussion

0 Comments

Thoughtful readers leave field notes, pushback, and hard-won operational detail here.