SpringAI Tool Calling 工具调用(六)

Tool Calling(工具调用),也称为函数调用,是让大语言模型(LLM)在对话中"调用"外部定义的工具或 API 的机制,通过这个机制,模型可以在生成回答前提出需要执行的操作(如获取实时天气、设置数据库记录、触发业务流程等),然后由应用端执行工具,结果再反馈回模型,最终给用户完整回复。

Tool Calling主要应用场景如下:

* 信息检索:从外部源(如数据库、Web 服务、文件系统或 Web 搜索引擎)检索信息,增强模型的知识,使其能够回答其他方式无法回答的问题。

* 执行操作:在软件系统中执行特定操作,如发送电子邮件、在数据库中创建新记录、提交表单或触发工作流。目标是自动执行原本需要人工干预或显式编程的任务。

Spring AI 提供了方便的 API 来定义工具、解析来自模型的工具调用请求以及执行工具调用。

工具定义与使用

Spring AI中工具调用流程示意图如下:

  1. 开发者定义工具,并将其注册到 Spring 容器中。

  2. 模型在生成响应时,识别到需要调用工具,会生成包含工具调用信息的响应。

  3. 应用程序接收到模型的响应后,解析其中的工具调用信息,执行相应的工具。

  4. 工具执行完成后,将结果返回给应用程序。

  5. 应用程序将工具执行结果作为上下文信息,传递给模型。

  6. 模型使用工具执行结果,生成最终的响应。

工具定义:

开发者可以通过在方法上添加@Tool注解定义工具,该注解允许提供工具的名称、描述和输入参数等信息,模型在调用工具时,会根据这些信息生成相应的调用请求。

定义工具示例如下:

Tool Calling 使用案例

  1. 配置项目pom.xml
html 复制代码
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd">
    <modelVersion>4.0.0</modelVersion>
    <parent>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-parent</artifactId>
        <version>3.5.3</version>
        <relativePath/> <!-- lookup parent from repository -->
    </parent>
    <groupId>com.example</groupId>
    <artifactId>SpringAIToolCalling</artifactId>
    <version>0.0.1-SNAPSHOT</version>
    <name>SpringAIToolCalling</name>
    <description>SpringAIToolCalling</description>

    <properties>
        <java.version>17</java.version>
    </properties>

    <!-- 导入 Spring AI BOM,用于统一管理 Spring AI 依赖的版本,
    引用每个 Spring AI 模块时不用再写 <version>,只要依赖什么模块 Mavens 自动使用 BOM 推荐的版本 -->
    <dependencyManagement>
        <dependencies>
            <dependency>
                <groupId>org.springframework.ai</groupId>
                <artifactId>spring-ai-bom</artifactId>
                <version>1.0.0-SNAPSHOT</version>
                <type>pom</type>
                <scope>import</scope>
            </dependency>
        </dependencies>
    </dependencyManagement>

    <dependencies>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-web</artifactId>
        </dependency>
        <dependency>
            <groupId>org.springframework.ai</groupId>
            <artifactId>spring-ai-starter-model-deepseek</artifactId>
        </dependency>
    </dependencies>


    <!-- 声明仓库, 用于获取 Spring AI 以及相关预发布版本-->
    <repositories>
        <repository>
            <id>spring-snapshots</id>
            <name>Spring Snapshots</name>
            <url>https://repo.spring.io/snapshot</url>
            <releases>
                <enabled>false</enabled>
            </releases>
        </repository>
        <repository>
            <name>Central Portal Snapshots</name>
            <id>central-portal-snapshots</id>
            <url>https://central.sonatype.com/repository/maven-snapshots/</url>
            <releases>
                <enabled>false</enabled>
            </releases>
            <snapshots>
                <enabled>true</enabled>
            </snapshots>
        </repository>
    </repositories>

</project>
  1. 创建tools包并创建MyTools.java类
java 复制代码
package com.example.springaitoolcalling.tools;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.ai.tool.annotation.Tool;
import org.springframework.ai.tool.annotation.ToolParam;
import org.springframework.stereotype.Component;
import org.springframework.web.client.RestTemplate;

@Component
public class MyTools {

    Logger log = LoggerFactory.getLogger(MyTools.class);

    @Tool(description = "返回当前系统时间")
    public String getCurrentTime() {
        log.info("调用 getCurrentTime 工具,当前时间:"+java.time.LocalDateTime.now().toString());
        return java.time.LocalDateTime.now().toString();
    }

    @Tool(description = "对两个数字执行加、减、乘、除运算")
    public double calculate(
            @ToolParam(description = "第一个数字") double a,
            @ToolParam(description = "第二个数字") double b,
            @ToolParam(description = "运算类型") String operation) {
        log.info("调用 calculate 工具,第一个数字:"+a+",第二个数字:"+b+",运算类型:"+operation);

        double result = 0;

        switch (operation) {
            case "add":
                result = a + b;
                break;
            case "subtract":
                result = a - b;
                break;
            case "multiply":
                result = a * b;
                break;
            case "divide":
                if (b != 0) {
                    result = a / b;
                }
        }

        return result;
    }

    private RestTemplate restTemplate = new RestTemplate();
    private
    String baseUrl = "http://shanhe.kim/api/youjia/youjia.php";

    @Tool(description = "查询指定省份的油价,直接返回完整 JSON 字符串")
    public String getOilPriceJson(@ToolParam(description = "省份名称") String province) {
        log.info("调用 getOilPriceJson 工具,查询省份:"+province);
        String url = String.format("%s?province=%s", baseUrl, province);
        return restTemplate.getForObject(url, String.class);
    }
}
相关推荐
陕西企来客1 小时前
企来客科技来客 GEO 优化系统深度解析:核心技术与原因分析
大数据·人工智能·科技·搜索引擎
来让爷抱一个4 小时前
MonkeyCode 多模型切换技巧:什么时候用 Claude/GPT/DeepSeek
人工智能·ai编程
李白你好4 小时前
AI Agent 架构的自动化渗透测试工具
运维·人工智能·自动化
2601_949499945 小时前
8 大工业光模块供应商选型:芯瑞科技 400G OSFP 助力 AI 算力集群升级
人工智能·科技
温柔只给梦中人5 小时前
NLP学习:注意力机制
人工智能·学习·自然语言处理
2601_961194025 小时前
2026初级会计实务公式总结大全|计算题公式手册PDF
java·spring·eclipse·pdf·tomcat·hibernate
广州灵眸科技有限公司5 小时前
瑞芯微RV1126B开发板(EASY-EAI-PI2) Easy-Eai编译环境准备与更新
服务器·前端·人工智能·python·深度学习
深度学习lover5 小时前
<数据集>yolo樱桃识别<目标检测>
人工智能·深度学习·yolo·目标检测·计算机视觉·数据集·樱桃识别
深圳市机智人激光雷达5 小时前
技术筑牢安全冗余:激光雷达在自动驾驶高阶感知中的底层价值与范式演进
人工智能·安全·机器学习·3d·机器人·自动驾驶·无人机
江澎涌5 小时前
拆解与 AI 的一次对话
人工智能·算法·程序员