Spring AI Agentic Patterns (Part 2): AskUserQuestionTool - Agents That Clarify Before Acting

Spring AI 代理模式(第二部分):AskUserQuestionTool——行动前先澄清的代理

https://spring.io/blog/2026/01/16/spring-ai-ask-user-question-tool


Traditional AI interactions follow a common pattern: you provide a prompt, the AI makes assumptions, and produces a response. When those assumptions don't match your needs, you're left iterating through corrections. Each assumption creates rework—wasting time and context.

What if your AI agent could ask you clarifying questions before providing answers?

The AskUserQuestionTool addresses this. It allows the AI agent to ask clarifying questions before answering, gathers requirements interactively, and creates a specification aligned with your actual needs from the start.

Spring AI's implementation brings this interactive pattern to the Java ecosystem, ensuring LLM portability—define your question handlers once and use them with OpenAI, Anthropic, Google Gemini, or any other supported model.

This is Part 2 of our Spring AI Agentic Patterns series. In Part 1, we explored Agent Skills—modular capabilities that extend AI functionality. Now we examine AskUserQuestionTool, which transforms AI agents into collaborative partners that gather requirements interactively.

传统人工智能交互遵循一个固定模式:用户提供提示,AI作出假设并生成响应。当这些假设与需求不符时,用户只能反复修正。每个假设都会导致返工——既浪费时间又破坏上下文连贯性。

如果您的AI助手能在回答前主动澄清疑问会怎样?

AskUserQuestionTool正是为此而生。它让AI助手在响应前先提出澄清问题,通过互动收集需求,从一开始就创建符合实际需求的精准方案。

Spring AI将这种交互模式引入Java生态系统,确保大语言模型的通用性——只需定义一次问题处理器,即可兼容OpenAI、Anthropic、Google Gemini或任何受支持模型。

此为Spring AI智能体模式系列第二篇。首篇我们探讨了扩展AI功能的模块化技能(Agent Skills),本篇重点解析AskUserQuestionTool如何将AI助手转变为能交互收集需求的协作伙伴。

How AskUserQuestionTool Works

AskUserQuestionTool, part of the spring-ai-agent-utils toolkit, is a portable, Spring AI implementation of Claude Code's AskUserQuestion tool, enabling AI agents to ask users multiple-choice questions during execution.

AskUserQuestionTool 工作原理
AskUserQuestionTool 是 spring-ai-agent-utils 工具包中的一个组件,作为 Claude Code 的 AskUserQuestion 工具的轻量级 Spring AI 实现,它允许 AI 代理在执行过程中向用户提出多选题。

The tool follows a question-answer workflow:

  1. AI generates questions - The agent determines it needs input and constructs questions (each containing question text, header, 2-4 options, and multiSelect flag) and calls the askUserQuestion tool function
  2. User provides answers - Your custom handler receives these questions, presents them through your UI, collects answers, and returns them to AI.
  3. Ask additional questions - Repeat 1 and 2 if necessary to collect additional user feedback
  4. AI continues with context - The agent uses the answers to provide tailored solutions

该工具遵循问答式工作流程:

AI生成问题 - 代理确定需要输入信息时,会构建问题(每个问题包含问题文本、标题、2-4个选项及多选标志),并调用askUserQuestion工具函数
用户提供答案 - 您的自定义处理器接收这些问题,通过用户界面展示,收集答案后返回给AI
追加提问 - 必要时重复步骤1和2以收集更多用户反馈
AI继续处理上下文 - 代理利用获得的答案提供定制化解决方案

Each question supports:

  • Single-select or multi-select - Choose one option or combine multiple
  • Free-text input - Users can always provide custom text beyond predefined options
  • Rich context - Every option includes a description explaining implications and trade-offs

每个问题支持:

单选或多选 - 选择一个选项或组合多个选项
自由文本输入 - 用户始终可以在预定义选项之外提供自定义文本
丰富的上下文 - 每个选项都包含解释影响和权衡的描述

💡 Portability and Model Agnostic - No Vendor Lock-In - Unlike implementations tied to specific LLM platforms, this Spring AI implementation works across many LLM providers, letting you switch models without rewriting code or question handlers.

可移植性与模型无关性 - 无供应商锁定 - 与绑定特定LLM平台的实现不同,该Spring AI实现可跨多个LLM提供商运行,让您无需重写代码或问题处理程序即可切换模型。

💡 Relation to MCP Elicitation - AskUserQuestionTool serves as an agent-local approach to interactive user input, conceptually similar to the MCP Elicitation capability. While MCP Elicitation enables MCP servers to request structured user input via JSON schemas, AskUserQuestionTool provides the same interactive pattern directly within your agent without requiring an MCP server. Spring AI also provides full MCP Elicitation support via the @McpElicitation annotation for server-driven scenarios.

与MCP启发式的关系 - AskUserQuestionTool作为一种代理本地的交互式用户输入方法,在概念上类似于MCP启发式能力。虽然MCP启发式允许MCP服务器通过JSON模式请求结构化用户输入,但AskUserQuestionTool直接在您的代理中提供相同的交互模式,无需MCP服务器。Spring AI还通过@McpElicitation注解为服务器驱动场景提供完整的MCP启发式支持。

Example: Travel Recommendation Assistant

Here's how the tool works in practice with a travel recommendation use case from the ask-user-question-demo:

USER: What EU country to visit next?

Interests: What are your main interests when traveling?
  1. History & Culture - Museums, historical sites, architecture
  2. Nature & Outdoors - Hiking, beaches, mountains, national parks
  3. Food & Drink - Culinary experiences, wine regions, food tours
  4. Cities & Urban - Urban exploration, shopping, nightlife
  (Enter numbers separated by commas, or type custom text)
1,2

Season: When are you planning to travel?
  1. Spring - March to May - Mild temperatures, fewer tourists
  2. Summer - June to August - Warm weather, peak season
  3. Fall - September to November - Cooler temps, autumn colors
  4. Winter - December to February - Christmas markets, winter sports
  (Enter a number, or type custom text)
3

Budget: What's your approximate budget level for this trip?
  1. ...
...

ASSISTANT: Based on your preferences for a fall trip with interests in history,
culture, and nature on a moderate budget, while seeking a mix of popular spots
and off-the-beaten-path experiences, here are excellent EU countries to consider:

1. **Portugal** - Lisbon's historic districts, Douro Valley wine harvests,
   Algarve coastlines. Affordable with pleasant fall temperatures.
2. **Greece** - Ancient sites, beautiful islands, still warm for swimming
   in fall with fewer crowds.
3. **Slovenia** - Lake Bled, Julian Alps, spectacular autumn colors.
   More affordable than neighboring Austria or Italy.

The agent gathered comprehensive requirements through interactive questions before providing personalized recommendations—no assumptions, no iteration needed.

Getting Started

1. Add the dependency:

<dependency>
    <groupId>org.springaicommunity</groupId>
    <artifactId>spring-ai-agent-utils</artifactId>
    <version>0.3.0</version>
</dependency>

2. Configure your agent:

ChatClient chatClient = chatClientBuilder
    .defaultTools(AskUserQuestionTool.builder()
        .questionHandler(this::handleQuestions)
        .build())
    .build();

3. Implement your QuestionHandler using the console or web examples below.

The agent automatically invokes the tool when it needs clarification and uses the answers to provide tailored solutions.

💡 Demo: ask-user-question-demo

QuestionHandler Examples

Console-Based QuestionHandler

A console-based implementation:

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("\n" + 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());
        }

        System.out.println(q.multiSelect()
            ? "  (Enter numbers separated by commas, or type custom text)"
            : "  (Enter a number, or type custom text)");

        String response = scanner.nextLine().trim();

        // Parse numeric selection(s) or use as free text
        try {
            String[] parts = response.split(",");
            List<String> labels = new ArrayList<>();
            for (String part : parts) {
                int index = Integer.parseInt(part.trim()) - 1;
                if (index >= 0 && index < q.options().size()) {
                    labels.add(q.options().get(index).label());
                }
            }
            answers.put(q.question(), labels.isEmpty() ? response : String.join(", ", labels));
        } catch (NumberFormatException e) {
            answers.put(q.question(), response);
        }
    }
    return answers;
}

The handler displays options, accepts numeric selections (like "1,2") or free text (like "A moderate budget"), and returns answers to the agent.

Web-Based QuestionHandler

For web applications, use CompletableFuture to bridge async UI interactions with the synchronous QuestionHandler API. Send questions to your frontend via WebSocket/SSE and block on future.get(). Complete the future when the user submits answers via a REST endpoint.

Conclusion

AskUserQuestionTool transforms AI agents from assumption-based responders into collaborative partners that gather requirements before acting, delivering answers aligned with your needs on the first attempt.

Next in this series:

  • TodoWriteTool - Track multi-step workflows transparently
  • Subagent Orchestration - Hierarchical multi-agent architectures
  • A2A Integration - Building interoperable agents with the Agent2Agent protocol
  • Subagent Extension Framework (coming soon) - Protocol-agnostic agent orchestration

Start experimenting with the ask-user-question-demo.

Resources

  • Part 1Agent Skills - Modular, reusable capabilities
  • Part 2: AskUserQuestion Tool (this post) - Interactive workflows
  • Part 3TodoWriteTool - Structured planning
  • Part 4Subagent Orchestration - Hierarchical agent architectures
  • Part 5A2A Integration - Building interoperable agents with the Agent2Agent protocol
  • Part (soon): Subagent Extension Framework (coming soon) - Protocol-agnostic agent orchestration

-

Spring AI Agentic Patterns (Part 1): 

https://spring.io/blog/2026/01/13/spring-ai-generic-agent-skills#getting-started

Logo

欢迎加入DeepSeek 技术社区。在这里,你可以找到志同道合的朋友,共同探索AI技术的奥秘。

更多推荐