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);
    }
}
相关推荐
火山引擎开发者社区35 分钟前
VeOps CLI:你的火山引擎可观测排障助手
人工智能
卓怡学长1 小时前
w255基于springboot仓库管理系统
java·数据库·spring boot·spring·intellij-idea
To_OC3 小时前
调用远程MCP,手搓一个能查酒店、自动打开浏览器的 Agent
人工智能·agent·mcp
启雀AI3 小时前
生物医疗行业如何建设合规、安全、可复用的知识库?
人工智能·安全·软件构建·知识图谱·知识库
x-cmd3 小时前
Mac 涨价后,本地 AI 还能千元入门吗?
linux·人工智能·macos·ai·agent·amd·本地ai入门
To_OC3 小时前
跑通第一个 MCP Server 后,我终于搞懂它到底解决了什么问题
人工智能·agent·mcp
楷哥爱开发3 小时前
如何使用 Claude Fable 5 进行网页抓取?2026最新实战教程
大数据·网络·人工智能
YMWM_3 小时前
lerobot中use_relative_actions=True需要重新计算meta/stats.json等信息
人工智能·深度学习·lerobot
触底反弹3 小时前
🔥 DeepSeek 560 万美金干翻 OpenAI?一文讲透「蒸馏」的来龙去脉
人工智能
私人珍藏库3 小时前
[Android] 会计快题库 -财会职称考试刷题学习
android·人工智能·学习·app·软件·多功能