当前位置: 首页 > article >正文

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

前言:在最近发布的 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.lryc.cn/news/2394754.html

相关文章:

  • 机器人--里程计
  • 设计模式——原型设计模式(创建型)
  • react库:class-variance-authority
  • 通过mqtt 点灯
  • 随笔笔记记录5.28
  • 大数据-273 Spark MLib - 基础介绍 机器学习算法 决策树 分类原则 分类原理 基尼系数 熵
  • 基于 Spring Boot + Vue 的墙绘产品展示交易平台设计与实现【含源码+文档】
  • 【机器学习】支持向量机
  • ONLYOFFICE深度解锁系列.4-OnlyOffice客户端原理-真的不支持多端同步
  • LLMTIME: 不用微调!如何用大模型玩转时间序列预测?
  • 2.从0开始搭建vue项目(node.js,vue3,Ts,ES6)
  • MySQL 高可用实现方案详解
  • 【pycharm】如何连接远程仓库进行版本管理(应用版本)
  • linux 1.0.7
  • 【Rust 轻松构建轻量级多端桌面应用】
  • IEEE P370:用于高达 50 GHz 互连的夹具设计和数据质量公制标准
  • 青少年编程与数学 02-020 C#程序设计基础 09课题、面向对象编程
  • Denoising Autoencoders 视频截图 DAEs简单实现 kaggle 去噪编码器
  • GoogLeNet网络模型
  • LeetCode Hot100 (贪心)
  • 仿真科普|弥合市场需求断层,高性能仿真,“性能”与“安全”如何兼得?
  • 工业控制核心引擎高性能MCU——MM32F5370
  • Maven---配置本地仓库
  • vue中events选项与$on监听自定义事件他们的区别与不同,以及$emit与$on之间通信和mounted生命周期钩子函数有哪些作用和属性
  • 【C++ 】智能指针:内存管理的 “自动导航仪”
  • 设备制造行业项目管理难点解析,如何有效解决?
  • 浅谈 PAM-2 到 PAM-4 的信令技术演变
  • Protos-SIP:经典 SIP 协议模糊测试工具!全参数详细教程!Kali Linux教程!
  • 复数三角不等式简介及 MATLAB 演示
  • 【Doris基础】Apache Doris 基本架构深度解析:从存储到查询的完整技术演进