首页
学习
活动
专区
圈层
工具
发布
社区首页 >专栏 >Spring AI系列之Tool Calling 实战:3 种工具定义方式

Spring AI系列之Tool Calling 实战:3 种工具定义方式

作者头像
SmileNicky
发布2026-04-17 08:46:55
发布2026-04-17 08:46:55
80
举报
文章被收录于专栏:Nicky's blogNicky's blog

Spring AI系列之Tool Calling 实战:3 种工具定义方式

在 Spring AI 开发 AI Agent 的过程中,Tool Calling(工具调用) 是最核心、最能体现 AI 智能化的能力。 很多同学在实战时都会遇到这些问题:

  • 工具到底有几种写法?
  • 函数式工具怎么用才规范?
  • 编程式 ToolCallback 适合什么场景?
  • 项目里到底该选哪种?

今天这篇就带着大家一次性吃透 Spring AI 3 种标准工具定义方式,全部是可直接复制运行的企业级代码,图文并茂、一看就会!

环境:

  • Spring AI 1.1.3
  • SpringBoot 3.5.7
  • JDK 17

一、先看懂:Tool Calling 执行流程(图文秒懂)

Tool Calling 的本质: 让大模型自主判断是否需要调用外部方法 → 自动调用 → 取回结果 → 自然语言回答

🔁 Tool Calling 标准执行流程图
Tool Calling 完整执行流程
Tool Calling 完整执行流程

流程步骤:

  1. 用户提问
  2. 模型分析是否需要调用工具
  3. Spring AI 自动调度对应工具
  4. 执行 Java 方法/函数并返回结果
  5. 模型整合结果,给出最终回答

二、Spring AI 3 种工具定义方式(全文重点)

Spring AI 目前提供 3 种标准工具定义方式,覆盖 99% 开发场景:


方式 1:注解式 @Tool(最简单、企业最常用)

直接在普通 Java 方法上加 @Tool 注解,Spring AI 自动识别为可调用工具。

📦 代码示例
代码语言:javascript
复制
@Component
public class TimeTools {

    /**
     * 获取当前系统时间工具
     */
    @Tool(description = "获取当前系统的日期与时间,格式:yyyy-MM-dd HH:mm:ss")
    public String getCurrentTime() {
        return LocalDateTime.now().format(DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss"));
    }
}
✅ 优点
  • 写法最简单直观
  • 业务代码清晰
  • 支持复杂逻辑、依赖注入
🎯 适用场景

时间查询、天气查询、数据库操作、订单服务、消息推送等常规业务工具


方式 2:函数式工具 Function / BiFunction(官方推荐、极简)

这是 Spring AI 原生支持的优雅写法,也是官方文档重点推荐的方式。 不需要类、不需要注解,基于 JDK 函数式接口定义。

🧩 代码示例 1:编程式构建
代码语言:javascript
复制
// 定义入参、出参
record WeatherRequest(String city, String unit) {}
record WeatherResponse(double temperature, String unit) {}

// 函数式接口
interface WeatherService extends Function<WeatherRequest, WeatherResponse> {
    @Override
    WeatherResponse apply(WeatherRequest request);
}

@Test
void testFunctionTool() {
    // 构建函数式工具
    ToolCallback tool = FunctionToolCallback.builder("currentWeather", new WeatherService() {
                @Override
                public WeatherResponse apply(WeatherRequest request) {
                    return new WeatherResponse(25.5, request.unit());
                }
            })
            .description("获取指定城市的实时天气")
            .inputType(WeatherRequest.class)
            .build();

    // 调用
    String result = ChatClient.create(chatModel)
            .prompt("长沙今天天气怎么样?")
            .tools(tool)
            .call()
            .content();

    System.out.println(result);
}
🧩 代码示例 2:配置类 Bean 方式(企业推荐)
代码语言:javascript
复制
@Configuration
public class AiToolConfig {
    public static final String WEATHER_TOOL = "currentWeather";

    @Bean(WEATHER_TOOL)
    @Description("获取指定城市的实时天气")
    public Function<WeatherRequest, WeatherResponse> currentWeather() {
        return request -> new WeatherResponse(30.0, request.unit());
    }
}
🚀 调用方式
代码语言:javascript
复制
@Test
void testConfigFunctionTool() {
    String content = ChatClient.create(chatModel)
            .prompt("今天长沙天气怎么样?")
            .toolNames(AiToolConfig.WEATHER_TOOL)
            .call()
            .content();

    System.out.println(content);
}
✅ 优点
  • 代码极简、无冗余
  • 结构化强、支持强类型
  • Spring 容器无缝整合
🎯 适用场景

轻量工具、结构化工具、快速开发、企业级规范项目。


方式 3:编程式构建 ToolCallback(最灵活、底层)

完全手动构建工具:名称、描述、入参 Schema、执行体全部自己控制。 适合:动态工具、插件化、运行时注册、多租户场景

⚙️ 代码示例
代码语言:javascript
复制
// 计算器工具
public class CalcTools {
    public Integer add(int a, int b) {
        return a + b;
    }
}

@Test
void testProgrammaticTool() {
    // 反射获取方法
    Method method = ReflectionUtils.findMethod(CalcTools.class, "add", int.class, int.class);

    // 手动定义工具元数据
    ToolDefinition definition = ToolDefinition.builder()
            .name("add")
            .description("计算两个整数的和")
            .inputSchema("""
                {
                    "type": "object",
                    "properties": {
                        "a": { "type": "integer", "description": "第一个数字" },
                        "b": { "type": "integer", "description": "第二个数字" }
                    },
                    "required": ["a", "b"]
                }
            """)
            .build();

    // 构建 ToolCallback
    ToolCallback callback = MethodToolCallback.builder()
            .toolDefinition(definition)
            .toolMethod(method)
            .toolObject(new CalcTools())
            .build();

    // 调用
    String content = ChatClient.builder(chatModel).build()
            .prompt("100 加 1000 等于多少?")
            .tools(callback)
            .call()
            .content();

    System.out.println(content);
}
✅ 优点
  • 最灵活,完全代码控制
  • 支持动态生成工具
  • 支持自定义入参 Schema
  • 适合高级架构、插件系统
🎯 适用场景

动态工具、插件化 AI Agent、工作流、多租户、低代码平台。


三、3 种工具方式对比(一张表看懂)

工具方式

难度

代码量

灵活性

企业使用

@Tool 注解

极少

主流、首选

函数式 Function

⭐⭐

极简

中高

推荐、规范

编程式 ToolCallback

⭐⭐⭐

中等

最高

动态/插件架构

一句话选择:

  • 普通业务 → @Tool
  • 快速优雅开发 → 函数式工具
  • 动态/插件/高级场景 → ToolCallback

四、企业级最佳实践(必看)

  1. 工具描述必须精准,模型靠它决定是否调用
  2. 函数式工具优先使用 @Bean 注册,便于管理
  3. 工具内部必须捕获异常,避免调用失败
  4. 敏感操作必须加权限校验
  5. 生产环境建议使用 MCP 协议 做工具网关
  6. 开启日志可查看完整调用过程

五、总结

Spring AI Tool Calling 3 种标准工具定义方式

  1. @Tool 注解 → 简单、稳定、业务首选
  2. 函数式 Function → 优雅、强类型、企业推荐
  3. 编程式 ToolCallback → 灵活、动态、高级架构

这一篇吃透,你就能轻松开发企业级 AI 智能体(Agent)!

本文参与 腾讯云自媒体同步曝光计划,分享自作者个人站点/博客。
原始发表:2026-04-17,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • Spring AI系列之Tool Calling 实战:3 种工具定义方式
    • 一、先看懂:Tool Calling 执行流程(图文秒懂)
      • 🔁 Tool Calling 标准执行流程图
    • 二、Spring AI 3 种工具定义方式(全文重点)
    • 方式 1:注解式 @Tool(最简单、企业最常用)
      • 📦 代码示例
      • ✅ 优点
      • 🎯 适用场景
    • 方式 2:函数式工具 Function / BiFunction(官方推荐、极简)
      • 🧩 代码示例 1:编程式构建
      • 🧩 代码示例 2:配置类 Bean 方式(企业推荐)
      • 🚀 调用方式
      • ✅ 优点
      • 🎯 适用场景
    • 方式 3:编程式构建 ToolCallback(最灵活、底层)
      • ⚙️ 代码示例
      • ✅ 优点
      • 🎯 适用场景
    • 三、3 种工具方式对比(一张表看懂)
    • 四、企业级最佳实践(必看)
    • 五、总结
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档