SpringAI系列4: Tool Calling 工具调用 【感觉这版本有bug】

article/2025/9/14 12:59:09

前言:在最近发布的 Spring AI 1.0.0.M6 版本中,其中一个重大变化是 Function Calling 被废弃,被 Tool Calling 取代。Tool Calling工具调用(也称为函数调用)是AI应用中的常见模式,允许模型通过一组API或工具进行交互,从而增强其能力


1、Tool Calling 工具调用 简介

Spring AI 中的工具调用使 AI 模型能够与外部工具和服务交互,从而增强其功能。Tool Calling 工具调用允许 AI 模型执行外部函数、访问外部服务、执行复杂操作和与现有系统集成

主要使用的场景:

  1. 信息检索(Information Retrieval)。

    此类工具可用于从外部资源(如数据库、Web服务、文件系统或者 WEB 搜索引擎)检索信息。

    目标:增强模型的知识,使其能够回答其其它方式不能回答的问题。例如,工具用于检索给定的位置天气、检索最新的新闻文章或者查询数据库。

  2. 采取行动(Taking Action)

    此类工具可用于在软件系统中的执行操作(如发送电子邮件、在数据库中创建新记录、提交表单或触发工作流),自动执行原本需要人工干预或者显式编程的任务。例如,与机器人交互生成待办事项、自动填写网页表单、聊天机器人预订机票、创建会议安排等。

注意: 通常我们认为工具调用是模型功能,但实际上由客户端应用程序提供工具调用逻辑,模型只能请求工具调用并提供输入参数,模型本身不执行工具调用。


2、为什么废弃 Function Calling?

  • 更好的改进和扩展 Spring AI 中工具调用功能。

  • 新的 API 从 functions 改为 tools 术语,与行业术语保持一致性。

除以上两点之外,在设计上也做了一定的优化,主要体现在;

  • 新的 API 在工具的定义和实现之间提供了更好的分离

  • 工具定义可以在不同的实现中重复使用

  • 在使用上,简化了构造器模式,更好的支持基于方法的工具,并改进了错误处理。

两者在本质上概念上没有区别,都是为增强大模型的能力,在底层的实现原理上也是一致的,只是对外提供的概念稍微变动一下。官方建议尽快将 Function Calling 相关使用的 API 迁移到 Tool Calling API。Function Calling API 在后续的版本中会被移除。基本上是将原API 中的Function 替换为 Tool,再者就是为了方便方法的使用做了一些优化。


3、Tool Calling 主要操作流程和源代码

(1)主要操作流程

  1. 定义工具 :当需要向模型提供工具时,需在聊天请求中包含其定义。每个工具定义包含名称、描述及输入参数的模式(schema)。

  2. 模型发起调用 :当模型决定调用工具时,会返回包含工具名称和符合预定义模式的输入参数的响应。

  3. 应用执行工具 :应用程序负责根据工具名称识别并执行对应工具,传入提供的输入参数。

  4. 处理结果 :工具调用的结果由应用程序处理。

  5. 返回结果至模型 :应用程序将工具调用结果返回给模型。

  6. 生成最终响应 :模型结合工具调用结果作为上下文生成最终响应

(2)源码

​
@Target({ ElementType.METHOD, ElementType.ANNOTATION_TYPE })
@Retention(RetentionPolicy.RUNTIME)
@Documented
public @interface Tool {/*** 指定工具的名称,如果不指定则默认使用方法名称。* 注意:方法名称的唯一性*/String name() default "";/*** 工具的描述,模型可以使用它来了解何时以及如何调用工具,如果不指定则使用方法名。* 强烈建议:详细,清晰的描述工具的功能,这对于工具的使用至关重要,直接影响大模型的* 使用效果。*/String description() default "";/*** 指定工具执行的结果是直接返回,还是要发给大模型,默认发送给大模型*/boolean returnDirect() default false;/*** 指定工具执行结果转换器。Spring AI 内置一个默认转换为String,如果有特殊业务* 需求可自行实现。*/Class<? extends ToolCallResultConverter> resultConverter() default DefaultToolCallResultConverter.class;}​

4、Tool Calling 快速入门​

让我们通过一个示例了解如何在Spring AI中使用工具调用。我们将实现两个简单工具:一个用于信息检索,另一个用于执行操作。信息检索工具用于获取用户时区的当前日期和时间,操作工具用于设置指定时间的闹钟。

(1)信息检索

AI模型无法访问实时信息。任何涉及当前日期、天气预报等实时信息的问题,模型都无法直接回答。但我们可以提供能够检索此类信息的工具,并让模型在需要实时数据时调用这些工具。

首先在DateTimeTools类中实现一个获取用户时区当前日期时间的工具。该工具不需要参数,通过Spring框架的LocaleContextHolder获取用户时区。工具方法使用@Tool注解,并添加详细描述帮助模型理解调用时机。

package com.hs.demo.tool;import org.springframework.ai.tool.annotation.Tool;
import org.springframework.context.i18n.LocaleContextHolder;import java.time.LocalDateTime;public class DateTimeTools {@Tool(description = "获取用户时区的当前日期和时间")String getCurrentDateTime() {return LocalDateTime.now().atZone(LocaleContextHolder.getTimeZone().toZoneId()).toString();}}

接下来将工具提供给模型,本例使用ChatClient与模型交互,通过tools()方法传入DateTimeTools实例。当模型需要实时时间信息时,会自动请求调用该工具。ChatClient会执行工具调用并将结果返回给模型,模型结合结果生成最终响应。

输出示例:

明天是2025-05-30。

如果直接提问但不提供工具,模型将返回:

我无法访问实时信息,请提供当前日期以便计算明天的日期。

这证明模型在缺乏工具时无法自主获取实时数据

 (2)  执行操作

AI模型可以生成实现目标的计划(如制定瑞士旅行计划),但无法直接执行。此时需要工具来落实模型生成的计划。

我们将定义第二个工具,用于在特定时间设置闹钟。在第一个工具的基础上,先获取当前时间,在当前时间的基础上设置闹钟。在现有DateTimeTools类中新增设置闹钟的工具。该工具接收ISO-8601格式的时间参数,向控制台输出闹钟设置信息。同样使用@Tool注解并添加详细描述

class DateTimeTools {@Tool(description = "获取用户时区的当前日期和时间")String getCurrentDateTime() {return LocalDateTime.now().atZone(LocaleContextHolder.getTimeZone().toZoneId()).toString();}@Tool(description = "为指定ISO-8601时间设置用户闹钟")void setAlarm(String time) {LocalDateTime alarmTime = LocalDateTime.parse(time, DateTimeFormatter.ISO_DATE_TIME);System.out.println("闹钟已设置为 " + alarmTime);}
}

通过ChatClient同时提供两个工具。当请求"10分钟后设置闹钟"时,模型会先调用getCurrentDateTime获取当前时间,计算目标时间后调用setAlarm工具。ChatClient自动处理工具调用请求并返回结果,模型最终生成响应

ChatModel chatModel = ...String response = ChatClient.create(chatModel).prompt("能设置10分钟后的闹钟吗?").tools(new DateTimeTools()).call().content();System.out.println(response);

应用日志将显示正确设置的闹钟时间,验证工具调用流程


参考链接:

Spring AI 框架在升级,Function Calling 废弃,被 Tool Calling 取代

Spring AI之工具调用_springai-CSDN博客


http://www.hkcw.cn/article/avTrpawJkN.shtml

相关文章

SAR ADC 比较器噪声分析(二)

SAR ADC的比较器是非常重要的模块&#xff0c;需要仔细设计。主要考虑比较器的以下指标&#xff1a; 1)失调电压 2)输入共模范围 3)比较器精度 4)传输延时 5)噪声 6)功耗 这里主要讲一下动态比较器的noise。 动态比较器一般用于高速SAR ADC中&#xff0c;且精度不会超过12bit…

Haproxy搭建Web集群

目录 Haproxy概述 Haproxy调度算法 静态调度算法 动态调度算法 其他调度算法 案例环境 配置网站 配置Haproxy Haproxy日志 MySQL负载均衡调度模式 Nginx负载均衡算法 Haproxy概述 Haproxy是一款开源、高性能的负载均衡和代理服务器&#xff0c;支持TCP和HTTP协议&a…

中联教育 - 嵌入式BI助力财经数据分析服务

“借助Wyn商业智能软件嵌入式BI工具强大的嵌入式能力&#xff0c;我们实现了与已有的财经教育教学实训平台的深度融合&#xff0c;大幅提升了平台的数据分析服务能力。同时&#xff0c;产品简单易用的特性&#xff0c;也让我们的学员能够快速上手&#xff0c;进行财务报表的设计…

Qt实现csv文件按行读取的方式

Qt实现csv文件按行读取的方式 场景:我有一个保存数据的csv文件,文件内保存的是按照行保存的数据,每行数据是以逗号为分隔符分割的文本数据。如下图所示: 现在,我需要按行把这些数据读取出来。 一、使用QTextStream文本流的方式读取 #include <QFile>void readfil…

VMware Workstation虚拟系统设置双网口

一.设置windows11系统VMware Network Adapter VMnet1。 1.进入到网络和Internet -> 高级网络设置 2.找到VMware Network Adapter VMnet1&#xff0c;进入到“更多配置选项”并“编辑”。 3.进入到属性&#xff0c;双击“Interenet协议版本4&#xff08;TCP/IPv4&#xff…

CppCon 2014 学习:Lock-Free Programming

你这段文字讲的是“为什么要使用无锁&#xff08;Lock-Free&#xff09;代码”&#xff0c;我帮你总结并解释一下&#xff1a; 为什么选择无锁代码&#xff1f; 并发性和可扩展性&#xff08;Concurrency and scalability&#xff09; 无锁算法允许多个线程同时操作共享数据&a…

MFA多因素认证与TOTP算法核心解析(含Java案例)

目录 一、多因素认证(MFA)概述MFA基本概念MFA与2FA的区别MFA的重要性 二、TOTP算法原理TOTP基本概念时间变量T的计算TOTP生成过程TOTP验证过程 三、TOTP在MFA中的应用绑定流程认证流程TOTP的优势 四、TOTP的安全考虑哈希算法选择密钥管理防暴力破解时间同步通信安全 五、TOTP的…

openssl-aes-ctr使用openmp加速

openssl-aes-ctr使用openmp加速 openssl-aes-ctropenmp omp for openssl-aes-ctr 本文采用openssl-1.1.1w进行开发验证开发&#xff1b;因为aes-ctr加解密模式中&#xff0c;不依赖与上一个模块的加/解密的内容&#xff0c;所以对于aes-ctr加解密模式是比较适合进行并行加速的…

git查看commit属于那个tag

1. 快速确认commit原始分支及合入tag # git describe 213b4b3bbef2771f7a1b8166f6e6989442ca67c8 查看commit合入tag # git describe 213b4b3bbef2771f7a1b8166f6e6989442ca67c8 --all 查看commit原始分支 2.查看分支与master关系 # git show --all 0.5.67_0006 --stat 以缩…

怎么在window上打开ubuntu虚拟机?

怎么在window上打开ubuntu虚拟机&#xff1f; 1.先下载ubuntu镜像包并解压&#xff08;VM-ubuntu18-202304.7z&#xff09;,下载地址在本文档中有链接&#xff0c;自行查找。&#xff08;解压路径不要有中文&#xff09; 2.打开VMware软件&#xff0c;&#xff08;软件下载地址…

中国移动咪咕助力第五届全国人工智能大赛“AI+数智创新”专项赛道开展

第五届全国人工智能大赛由鹏城实验室主办&#xff0c;新一代人工智能产业技术创新战略联盟承办&#xff0c;华为、中国移动、鹏城实验室科教基金会等单位协办&#xff0c;广东省人工智能与机器人学会支持。 大赛发布“AI图像编码”、“AI增强视频质量评价”、“AI数智创新”三大…

第十三章 MQTT消息

系列文章目录 系列文章目录 第一章 总体概述 第二章 在实体机上安装ubuntu 第三章 Windows远程连接ubuntu 第四章 使用Docker安装和运行EMQX 第五章 Docker卸载EMQX 第六章 EMQX客户端MQTTX Desktop的安装与使用 第七章 EMQX客户端MQTTX CLI的安装与使用 第八章 Wireshark工具…

国芯思辰| 16通道12位模数转换器SC1425高性价比SGM5200替代方案,专为数字电源优化

与传统的模拟电源相比&#xff0c;数字电源的主要区别是控制与通信部分。在复杂的多系统业务中&#xff0c;数字电源是通过软件编程来实现多方面的应用&#xff0c;数字电源广泛应用于在可控因素较多、实时反应速度更快、需要多个模拟系统电源管理的、复杂的高性能系统应用中。…

Java 大数据处理:使用 Hadoop 和 Spark 进行大规模数据处理

Java 大数据处理&#xff1a;使用 Hadoop 和 Spark 进行大规模数据处理 在当今数字化时代&#xff0c;数据呈现出爆炸式增长&#xff0c;如何高效地处理大规模数据成为企业面临的重要挑战。Java 作为一门广泛使用的编程语言&#xff0c;在大数据处理领域同样发挥着关键作用。本…

深度学习复习笔记

深度前馈神经网络 卷积神经网络 Advanced卷积神经网络 Lightweight CNN dwconv squeezenet 这边右侧的e3是3x3卷积吧 SENet 在通道维度压一下&#xff0c;强迫各维度混合学习&#xff0c;再还原 ShuffleNet Group Convolution在 AlexNet 中引入&#xff0c;用于将模型分布到…

Linux系统编程收尾(35)

文章目录 前言一、读写锁二、自旋锁总结 前言 大家好&#xff0c;这是我们Linux系统编程的最后一节课了&#xff01;   大家请再撑住一会儿~ 一、读写锁 提到读写锁&#xff0c;我们就不得不提到 读者写者模型 &#xff0c;跟 生产者消费者模型 不同的是&#xff0c;本模型的…

C文件操作1

一、为什么使用文件 如果没有文件&#xff0c;我们写的程序的数据是存储在电脑的内存中&#xff0c;如果程序退出&#xff0c;内存回收&#xff0c;数据就丢失 了&#xff0c;等再次运行程序&#xff0c;是看不到上次程序的数据的&#xff0c;如果要将数据进行持久化的保存&am…

基于 AUTOSAR 的域控产品软件开发:从 CP 到 AP 的跨越

基于 AUTOSAR 的域控产品软件开发&#xff1a;从 CP 到 AP 的跨越 一、AUTOSAR AP 架构解析&#xff1a;面向智能汽车的自适应框架 &#xff08;一&#xff09;引言 随着汽车智能化向 L3 演进&#xff0c;传统 AUTOSAR CP&#xff08;经典平台&#xff09;在实时性、动态性和…

解密震颤背后的神经隐情

在人体精密运行的神经世界里&#xff0c;有一种疾病悄然打破生命的节奏&#xff0c;它就是帕金森。这一病症并非突然降临&#xff0c;而是随着时间&#xff0c;如潮水般慢慢侵蚀着身体的正常机能。​ 患病后&#xff0c;最直观的变化体现在肢体运动上。双手会不受控制地颤抖&a…

数据即资产:GEO如何重塑企业的信息价值链

在数字经济时代&#xff0c;数据早已被公认为企业的核心资产。然而&#xff0c;随着生成式AI的崛起&#xff0c;数据资产的定义、价值和管理方式正在发生根本性变革。深耕数字营销二十余年&#xff0c;我们亲历了从"数据即记录"到"数据即洞察"&#xff0c;…