轻松入门SpringAI-SpringAI的函数调用

Spring AI 函数调用(Tool/Function Calling)轻松入门
(2026年最新实用写法 · 零到上手完整示例)

函数调用是让大模型“知道自己不知道”并主动调用你提供的工具/函数来获取实时信息或执行操作的核心能力。

目前(2026年初)Spring AI 已经从早期的 FunctionCallback 升级到更强大的 Tool Calling 体系,主要有三种主流写法,按推荐顺序:

排名写法风格优点缺点/注意点推荐指数难度
1@Tool 注解 + 对象实例最简洁、最现代、最推荐(1.0+主流)需要实例化类★★★★★★☆☆
2@Bean + @Description 函数式纯函数风格、方便测试描述写在注解里,稍显分散★★★★☆★★☆
3手动 FunctionToolCallback.builder()最大灵活性、可动态代码量多★★★☆☆★★★

推荐写法1:使用 @Tool 注解(最简单、最常用)

// 1. 先定义一个工具类(可以是普通的POJO)
@Component  // 可选,如果想自动扫描
public class WeatherTools {

    @Tool(value = "get_current_weather",  // 工具唯一名称(模型会用这个名字调用)
          description = "获取指定城市当前的天气信息,支持摄氏度和华氏度")
    public String getWeather(
            @ToolParam(description = "城市名称,如 '北京', 'Shanghai', 'Las Vegas'") String city,
            @ToolParam(description = "温度单位:celsius 或 fahrenheit,默认celsius") 
            String unit) {

        // 模拟真实查询,也可以换成调用第三方API
        String temp = switch (city.toLowerCase()) {
            case "beijing", "北京" -> "今天北京 -5℃,寒冷刺骨,多穿点!";
            case "shanghai", "上海" -> "上海今天12℃,阴天,有点湿冷";
            case "las vegas" -> "拉斯维加斯现在是" + (unit.equalsIgnoreCase("fahrenheit") ? "68°F" : "20℃") + ",阳光明媚适合游泳";
            default -> "抱歉,目前只知道北京、上海、拉斯维加斯的天气~";
        };

        return temp;
    }
}
// 2. Controller中使用(最常用写法)
@RestController
@RequestMapping("/ai/tool")
@RequiredArgsConstructor
public class ToolDemoController {

    private final ChatClient chatClient;

    @GetMapping("/weather")
    public String askWeather(@RequestParam String question) {
        // 直接把工具类实例传进去(支持多个)
        return chatClient.prompt()
                .user(question)
                .tools(new WeatherTools())           // ← 这里最关键
                // .tools(工具实例1, 工具实例2, ...)  // 支持多个工具类
                .call()
                .content();
    }
}

测试例子(浏览器或postman直接试):

http://localhost:8080/ai/tool/weather?question=拉斯维加斯现在天气怎么样?用华氏度告诉我
http://localhost:8080/ai/tool/weather?question=北京今天冷不冷?

模型会自动判断是否需要调用工具 → 调用 → 把结果塞回上下文 → 最终给出自然语言回答

推荐写法2:函数式(@Bean + @Description)

适合喜欢函数式风格的同学,也非常常用:

@Configuration
public class ToolFunctionsConfig {

    @Bean
    @Description("获取指定城市的当前天气,支持celsius/fahrenheit两种单位")
    public Function<WeatherQuery, String> currentWeather() {
        return query -> {
            // 模拟实现
            return switch (query.city().toLowerCase()) {
                case "beijing" -> "北京 " + (query.unit().equals("f") ? "-5℃ ≈ 23°F" : "-5℃") + ",冷到想回家";
                case "las vegas" -> "Las Vegas " + (query.unit().equals("f") ? "68°F" : "20℃") + ",适合户外活动";
                default -> "暂无该城市天气数据";
            };
        };
    }

    // 记录类型(作为输入参数)
    public record WeatherQuery(String city, String unit) {}
}

使用方式:

chatClient.prompt()
    .user("上海天气如何?")
    .functions("currentWeather")   // ← 使用bean名称
    .call()
    .content();

进阶小技巧(生产常用)

  1. 多个工具一起用(并行调用)
.tools(new WeatherTools(), new StockPriceTools(), new CalculatorTools())
  1. 流式 + 工具调用(前端打字机 + 工具)

目前大多数模型流式下工具调用支持有限,建议先用普通.call(),等模型成熟再切.stream()

  1. 带记忆的工具对话(最实用组合)
chatClient.prompt()
    .system("你是生活助手,会用工具帮用户解决问题")
    .user(question)
    .tools(new WeatherTools())
    .advisors(new MessageChatMemoryAdvisor(chatMemory))
    .call()
    .content();
  1. 强制/禁用工具(精细控制)
// 只允许使用某个工具
.tools(new WeatherTools())

// 强制调用某个工具(极少用)
.toolChoice(ToolChoice.REQUIRED)  // 或 ToolChoice.FORCE("get_weather")

一句话总结2026年最舒服的入门函数调用方式

ChatClient + .tools(带有@Tool注解的类实例) 
+ DeepSeek-R1 / GPT-4o / 通义千问 / 硅基流动兼容模型

快速练习建议(由易到难):

  1. 实现天气查询工具(上面例子)
  2. 实现汇率查询工具(调用免费汇率API)
  3. 实现计算器工具(加减乘除)
  4. 实现查快递工具
  5. 实现生成周报/日报小工具

需要我帮你把上面任意一个练习做成更完整的可运行小项目(包含配置、假数据/真API、测试页面)吗?
直接告诉我你想先实现哪个工具~ 😄

文章已创建 3855

发表回复

您的邮箱地址不会被公开。 必填项已用 * 标注

相关文章

开始在上面输入您的搜索词,然后按回车进行搜索。按ESC取消。

返回顶部