Skip to content

10. Spring AI 中如何实现工具调用(Tool Calling)? ​

难度 P1 高频 · 岗位 应用 · 频率 ★★★ · 预计阅读 11 min

本题阅读地图 ​

  1. 💡 简要回答
  2. 📝 详细解析
  3. 🎯 面试总结

👔面试官:Spring AI 里怎么实现工具调用?跟 Function Calling 有什么区别?

🙋‍♂️我:就是给模型配几个工具,让模型自己决定调哪个。

👔面试官:具体怎么定义工具?模型怎么告诉你要调哪个工具?Spring AI 的工具管理和原生 Function Calling 比有什么优势?

🙋‍♂️我:……具体 API 不太清楚。

Spring AI 的工具调用机制比原生 Function Calling 更工程化。下面把完整实现讲清楚。

💡 简要回答 ​

Spring AI 的工具调用基于 Function Calling 标准,但提供了更友好的封装:

  • 用 @Tool 注解定义工具(不需要手写 JSON Schema)
  • 框架自动生成工具描述和参数定义
  • 支持工具回调的自动执行和结果回传
  • 与 Spring 生态无缝集成(依赖注入、Bean 管理)

📝 详细解析 ​

定义工具:@Tool 注解 ​

java
@Service
public class WeatherTools {

    @Tool(description = "查询指定城市的实时天气,包括气温、天气状况、风向")
    public WeatherInfo getWeather(
        @ToolParam(description = "城市名称,如北京、上海、广州") String city,
        @ToolParam(description = "温度单位,celsius 或 fahrenheit", required = false) String unit) {

        // 调用天气 API
        return weatherApiClient.query(city, unit);
    }
}

public record WeatherInfo(
    String city,
    double temperature,
    String condition,
    String windDirection
) {}

@Tool 和 @ToolParam 注解让框架自动生成 JSON Schema,不需要手写。

注册工具到 ChatClient ​

java
@Configuration
public class ChatClientConfig {

    @Bean
    public ChatClient chatClient(ChatModel model, WeatherTools weatherTools) {
        return ChatClient.builder(model)
            .defaultTools(weatherTools)  // 注册工具 Bean
            .build();
    }
}

工具调用的完整流程 ​

java
@Service
public class TravelAssistant {
    @Autowired
    private ChatClient chatClient;

    public String planTrip(String destination) {
        return chatClient.prompt()
            .user("我打算去%s旅游,帮我查一下天气" .formatted(destination))
            .call()  // Spring AI 自动处理工具调用循环
            .content();
    }
}

// 执行流程:
// 1. 用户问「我打算去杭州旅游,帮我查一下天气」
// 2. 模型判断需要调用 getWeather 工具,参数 city="杭州"
// 3. Spring AI 自动执行 WeatherTools.getWeather("杭州")
// 4. 结果回传给模型
// 5. 模型生成最终回答「杭州今天晴,25°C,适合出游」

工具调用的内部机制 ​

用户提问
    ↓
LLM 判断:是否需要工具?
    ↓ 需要
生成 tool_calls JSON
    ↓
Spring AI 解析 tool_calls
    ↓
找到对应 Bean 方法,反射调用
    ↓
获取返回结果
    ↓
把结果塞进对话上下文
    ↓
再次调用 LLM
    ↓
返回最终答案

这个过程叫做 Tool Calling Loop,Spring AI 自动完成,开发者只需要写工具逻辑。

多工具管理 ​

java
@Configuration
public class ToolConfig {

    @Bean
    public ChatClient chatClient(
            ChatModel model,
            WeatherTools weatherTools,
            SearchTools searchTools,
            CalculatorTools calculatorTools) {

        return ChatClient.builder(model)
            .defaultTools(weatherTools, searchTools, calculatorTools)
            .build();
    }
}

工具数量多时,建议:

  1. 按业务模块拆分 Tool 类
  2. 用 Bean 名称做命名空间
  3. 工具描述要精确,避免模型选错

工具上下文传递 ​

java
// 在多轮对话中保持工具状态
ChatClient chatClient = ChatClient.builder(model)
    .defaultTools(weatherTools)
    .defaultAdvisors(new MessageChatMemoryAdvisor(chatMemory))
    .build();

// 第一轮
chatClient.prompt()
    .user("杭州天气怎么样?")
    .advisors(a -> a.param(CHAT_MEMORY_CONVERSATION_ID, "session-001"))
    .call().content();

// 第二轮(模型记得上下文)
chatClient.prompt()
    .user("那边适合穿什么衣服?")  // 模型知道「那边」指杭州
    .advisors(a -> a.param(CHAT_MEMORY_CONVERSATION_ID, "session-001"))
    .call().content();

🎯 面试总结 ​

Spring AI 工具调用的核心优势:注解驱动,自动 Schema 生成,Loop 自动处理。

三步使用:

  1. 定义:@Tool + @ToolParam 注解
  2. 注册:ChatClient.defaultTools()
  3. 调用:框架自动处理 Tool Calling Loop

与原生 Function Calling 对比:

  • 更少的样板代码:不需要手写 JSON Schema
  • 更好的 Spring 集成:依赖注入、Bean 管理
  • 更简单的多轮对话:配合 Advisor 自动维护上下文

面试时要能说出 Tool Calling Loop 的概念和 @Tool 注解的价值(省掉手写 Schema)。



章节首页 · ← Q9 · Q11 →

最后更新2026-05-01
难度P1
频率medium
阅读11 min
主题tool-use / framework
觉得有帮助?把这个链接转给正在求职的朋友 · 用 Ctrl + K 全站搜索其它题