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 小时前
Spring AI 实战教程(七):Agent 智能体 —— 用电商购物助手学透自主规划与工具执行
java·人工智能·spring
我也曾把你举过头顶1 小时前
Skill/MCP/RAG/Agent/OpenClaw是什么
人工智能·ai agent·mcp
南宫萧幕1 小时前
基于 Simulink 与 Python 联合仿真的 eVTOL 强化学习全链路实战
开发语言·人工智能·python·算法·机器学习·控制
HDD9851 小时前
2026年录音转文字工具实测:免费且好用的选择有哪些?
人工智能·语音识别·效率工具·语音转文字
跨境卫士苏苏1 小时前
经营变量持续增加之下跨境团队如何减少月度计划偏差
大数据·人工智能·内容运营·亚马逊·跨境
m0_466525291 小时前
东软添翼医疗大模型领跑 医疗AI进入“可信时代”
人工智能
美团技术团队1 小时前
美团 LongCat 开源 General 365:树立推理评测新标尺
人工智能
eastyuxiao1 小时前
能源电力领域的数字孪生应用场景有哪些
大数据·人工智能·智慧城市·能源·数字孪生
张二娃同学2 小时前
第08篇_RNN_LSTM_GRU序列模型
人工智能·python·rnn·深度学习·神经网络·gru·lstm