1. 教程概述

本教程旨在帮助开发者快速掌握 spring-ai-mcp-client-spring-boot-starter 中 Tool 注解 的核心功能与使用方法。通过 Tool 注解,开发者可以轻松将自定义业务逻辑封装为 AI 可调用的工具,实现 AI 与本地服务的无缝集成,适用于智能对话、任务调度、自动化处理等场景。

1.1 适用人群

  • 熟悉 Spring Boot 开发的后端工程师
  • 需集成 AI 工具调用能力的开发者
  • 对 spring-ai 生态有基础了解的技术人员

1.2 前置依赖

在开始前,请确保环境满足以下条件:

  • JDK 11 及以上版本
  • Maven 3.6+ 或 Gradle 7.0+
  • Spring Boot 2.7.x 及以上版本
  • spring-ai-mcp-client-spring-boot-starter 1.0.0 及以上版本

2. Tool 注解核心概念

2.1 什么是 Tool 注解?

@Tool 是 spring-ai-mcp-client-spring-boot-starter 提供的核心注解,用于标记可被 AI 调用的工具类或方法。通过该注解,框架会自动扫描并注册标记的组件,AI 模型可根据需求主动调用这些工具,执行具体业务逻辑(如数据库查询、API 调用、文件处理等)。

2.2 Tool 注解的核心作用

  1. 自动注册:标记的工具会被框架自动扫描并注册到工具注册表,无需手动配置。
  1. 元数据声明:通过注解属性定义工具的名称、描述、参数说明,帮助 AI 理解工具用途。
  1. 参数校验:支持结合 Spring 校验注解(如 @NotNull、@Size)实现参数合法性校验。
  1. 结果封装:自动将工具执行结果封装为 AI 可识别的格式,简化结果处理流程。

3. 环境搭建与依赖配置

3.1 引入依赖

在 Spring Boot 项目的 pom.xml(Maven)或 build.gradle(Gradle)中引入 spring-ai-mcp-client-spring-boot-starter 依赖。

Maven 配置

<dependencies>
    <!-- spring-ai-mcp-client 核心依赖 -->
    <dependency>
        <groupId>org.springframework.ai</groupId>
        <artifactId>spring-ai-mcp-client-spring-boot-starter</artifactId>
        <version>1.0.0</version> <!-- 替换为最新版本 -->
    </dependency>
    <!-- Spring Boot Web 依赖(如需提供 HTTP 接口) -->
    <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-web</artifactId>
    </dependency>
    <!-- 参数校验依赖 -->
    <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-validation</artifactId>
    </dependency>
</dependencies>

Gradle 配置

dependencies {
    // spring-ai-mcp-client 核心依赖
    implementation 'org.springframework.ai:spring-ai-mcp-client-spring-boot-starter:1.0.0' // 替换为最新版本
    // Spring Boot Web 依赖
    implementation 'org.springframework.boot:spring-boot-starter-web'
    // 参数校验依赖
    implementation 'org.springframework.boot:spring-boot-starter-validation'
}

3.2 配置 MCP 客户端

在 application.yml 或 application.properties 中配置 MCP(Model Control Plane)客户端参数,确保工具能与 AI 模型正常通信。

application.yml 配置示例

spring:
  ai:
    mcp:
      client:
        base-url: http://localhost:8080/mcp # MCP 服务地址
        api-key: your-api-key # 访问 MCP 服务的 API 密钥(如有)
        connect-timeout: 5000 # 连接超时时间(毫秒)
        read-timeout: 10000 # 读取超时时间(毫秒)
        tool:
          scan-base-packages: com.example.ai.tool # Tool 注解扫描的基础包路径(必填)

4. Tool 注解详细使用方法

4.1 注解属性说明

@Tool 注解支持以下属性,用于定义工具的元数据信息:

属性名类型是否必填说明
nameString工具名称,默认值为类名或方法名(首字母小写),建议手动指定唯一名称。
descriptionString工具功能描述,需清晰说明工具用途(AI 会根据描述判断是否调用该工具)。
parameters@ToolParam[]工具参数列表,用于定义参数名称、类型、描述及是否必填(复杂参数时使用)。

补充:@ToolParam 注解

当工具方法参数较多或需要详细说明时,可通过 @ToolParam 注解标记参数,属性如下:

属性名类型是否必填说明
nameString参数名称(需与方法参数名一致)。
descriptionString参数描述,帮助 AI 理解参数含义及传入格式。
requiredboolean是否为必填参数,默认值为 true。

4.2 工具定义的两种方式

方式 1:类级别的 @Tool(推荐用于复杂工具)

将 @Tool 注解标记在类上,类中所有公共方法(public)会被自动识别为工具的子方法,适用于功能关联的一组工具(如订单相关工具:创建订单、查询订单、取消订单)。

示例:订单工具类

package com.example.ai.tool;
import org.springframework.ai.mcp.client.annotation.Tool;
import org.springframework.ai.mcp.client.annotation.ToolParam;
import org.springframework.validation.annotation.Validated;
// 类级别 Tool 注解,定义工具组名称和描述
@Tool(name = "orderTool", description = "订单相关操作工具,支持创建、查询、取消订单")
@Validated // 开启参数校验
public class OrderTool {
    /**
     * 创建订单
     * @param orderId 订单ID(必填,格式:ORD-2024xxxx)
     * @param amount 订单金额(必填,单位:元,需大于0)
     * @param userId 用户ID(必填)
     * @return 订单创建结果
     */
    public String createOrder(
            @ToolParam(name = "orderId", description = "订单ID,格式为 ORD-2024xxxx") 
            @NotBlank(message = "订单ID不能为空") 
            @Pattern(regexp = "ORD-d{8}", message = "订单ID格式错误,需符合 ORD-2024xxxx") 
            String orderId,
            @ToolParam(name = "amount", description = "订单金额,单位:元,需大于0") 
            @DecimalMin(value = "0.01", message = "订单金额需大于0") 
            BigDecimal amount,
            @ToolParam(name = "userId", description = "用户ID") 
            @NotBlank(message = "用户ID不能为空") 
            String userId
    ) {
        // 业务逻辑:调用订单服务创建订单
        return String.format("订单创建成功!订单ID:%s,用户ID:%s,金额:%.2f元", orderId, userId, amount);
    }
    /**
     * 查询订单
     * @param orderId 订单ID(必填)
     * @return 订单详情
     */
    public String queryOrder(
            @ToolParam(name = "orderId", description = "要查询的订单ID") 
            @NotBlank(message = "订单ID不能为空") 
            String orderId
    ) {
        // 业务逻辑:调用订单服务查询订单
        return String.format("订单详情:订单ID:%s,状态:已支付,金额:99.00元,创建时间:2024-05-20 14:30:00", orderId);
    }
}

方式 2:方法级别的 @Tool(适用于独立工具)

将 @Tool 注解直接标记在方法上,每个方法对应一个独立工具,适用于功能单一的工具(如日期格式化、天气查询)。

示例:日期工具类

package com.example.ai.tool;
import org.springframework.ai.mcp.client.annotation.Tool;
import org.springframework.ai.mcp.client.annotation.ToolParam;
import org.springframework.stereotype.Component;
import org.springframework.validation.annotation.Validated;
import java.text.SimpleDateFormat;
import java.util.Date;
@Component // 需注入 Spring 容器
@Validated
public class DateTool {
    /**
     * 日期格式化工具
     * @param date 原始日期(必填,格式:yyyy-MM-dd HH:mm:ss)
     * @param pattern 目标格式(可选,默认:yyyy-MM-dd,支持 yyyy/MM/dd、MM-dd-yyyy 等)
     * @return 格式化后的日期字符串
     * @throws Exception 日期格式错误时抛出异常
     */
    @Tool(
        name = "dateFormatter", 
        description = "日期格式化工具,支持将原始日期转换为指定格式",
        parameters = {
            @ToolParam(name = "date", description = "原始日期,格式为 yyyy-MM-dd HH:mm:ss(必填)"),
            @ToolParam(name = "pattern", description = "目标日期格式,默认 yyyy-MM-dd(可选)", required = false)
        }
    )
    public String formatDate(
            @NotBlank(message = "原始日期不能为空") 
            String date,
            String pattern
    ) throws Exception {
        // 默认格式
        if (pattern == null || pattern.isEmpty()) {
            pattern = "yyyy-MM-dd";
        }
        // 解析原始日期
        SimpleDateFormat inputFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
        Date parsedDate = inputFormat.parse(date);
        // 格式化目标日期
        SimpleDateFormat outputFormat = new SimpleDateFormat(pattern);
        return outputFormat.format(parsedDate);
    }
}

4.3 工具注册与扫描

框架会自动扫描 application.yml 中 spring.ai.mcp.client.tool.scan-base-packages 配置的包路径下所有标记了 @Tool 的类或方法,并将其注册为可用工具。

注意事项:

  1. 标记 @Tool 的类需满足以下条件之一:
    • 类上添加 @Component、@Service 等注解,确保被 Spring 容器管理;
    • 通过 @Configuration 配置类手动注入容器。
  1. 方法级别的 @Tool 必须标记在 Spring 容器中的 Bean 的公共方法 上,否则无法被扫描。

5. 工具调用示例

5.1 通过 MCP 客户端调用工具

spring-ai-mcp-client-spring-boot-starter 提供了 McpClient 接口,可用于手动调用已注册的工具(也可由 AI 自动触发调用)。

示例:在 Service 中调用订单工具

package com.example.ai.service;
import org.springframework.ai.mcp.client.McpClient;
import org.springframework.ai.mcp.client.model.ToolCallRequest;
import org.springframework.ai.mcp.client.model.ToolCallResponse;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import java.util.HashMap;
import java.util.Map;
@Service
public class AiOrderService {
    @Autowired
    private McpClient mcpClient;
    /**
     * 调用订单工具创建订单
     */
    public String createOrderByTool(String orderId, BigDecimal amount, String userId) {
        // 1. 构建工具调用请求
        Map<String, Object> parameters = new HashMap<>();
        parameters.put("orderId", orderId);
        parameters.put("amount", amount);
        parameters.put("userId", userId);
        ToolCallRequest request = ToolCallRequest.builder()
                .toolName("orderTool") // 工具名称(与 @Tool(name) 一致)
                .methodName("createOrder") // 方法名称(类级别 Tool 时需指定)
                .parameters(parameters) // 工具参数
                .build();
        // 2. 调用工具
        ToolCallResponse response = mcpClient.callTool(request);
        // 3. 处理调用结果
        if (response.isSuccess()) {
            return "工具调用成功,结果:" + response.getResult();
        } else {
            return "工具调用失败,原因:" + response.getErrorMessage();
        }
    }
}

5.2 AI 自动触发工具调用

当集成 AI 模型(如 ChatGPT、通义千问)时,AI 会根据用户需求自动判断是否需要调用工具,并通过 MCP 客户端执行。开发者无需手动触发,只需确保工具已正确注册。

示例:AI 对话中自动调用日期工具

用户输入:"把 2024-05-20 14:30:00 转换成 MM/dd/yyyy 格式"
AI 思考:用户需要日期格式化,需调用 dateFormatter 工具。
AI 调用:自动构建 ToolCallRequest(toolName=dateFormatter,parameters={date:"2024-05-20 14:30:00", pattern:"MM/dd/yyyy"})
工具返回:"05/20/2024"
AI 回复:"转换后的日期格式为:05/20/2024"

6. 常见问题与排查

6.1 工具未被扫描注册

可能原因:

  1. spring.ai.mcp.client.tool.scan-base-packages 配置错误,未包含工具类所在包;
  1. 工具类未被 Spring 容器管理(未加 @Component 等注解);
  1. 方法级别的 @Tool 标记在非公共方法(如 private、protected)上。

排查步骤:

  1. 检查 application.yml 中扫描包路径是否正确;
  1. 确认工具类上是否有 Spring 组件注解(如 @Component);
  1. 查看日志(日志级别调整为 DEBUG),搜索 ToolScanner 相关日志,确认工具是否被扫描到。

6.2 工具调用参数校验失败

可能原因:

  1. 传入参数缺失必填项;
  1. 参数格式不符合校验规则(如正则、数值范围);
  1. 未开启参数校验(未加 @Validated 注解)。

解决方法:

  1. 在工具类上添加 @Validated 注解,开启参数校验;
  1. 确保所有必填参数通过 @NotBlank、@NotNull 等注解标记;
  1. 检查工具调用时传入的参数是否符合 @Pattern、@DecimalMin 等注解的规则。

6.3 工具调用超时

可能原因:

  1. MCP 服务地址配置错误或服务不可用;
  1. 工具业务逻辑执行时间过长,超过 read-timeout 配置;
  1. 网络问题导致通信失败。

解决方法:

  1. 验证 spring.ai.mcp.client.base-url 是否正确,确保 MCP 服务正常运行;
  1. 优化工具业务逻辑,减少执行时间;
  1. 适当调整 spring.ai.mcp.client.connect-timeout 和 read-timeout 配置(单位:毫秒)。

7. 总结与扩展

通过本教程,开发者已掌握 spring-ai-mcp-client-spring-boot-starter 中 Tool 注解的核心使用方法,包括工具定义、配置、调用及问题排查。Tool 注解的设计简化了 AI 与本地服务的集成流程,开发者可基于此扩展更多场景:

  1. 复杂工具封装:将数据库操作、第三方 API 调用(如支付、物流)封装为工具,供 AI 调用;
  1. 工具权限控制:结合 Spring Security 实现工具调用的权限校验,确保只有授权用户可调用敏感工具;
  1. 工具调用日志:通过 AOP 拦截工具调用过程,记录调用日志,便于问题排查和审计;
  1. 多环境适配:通过 Spring Profiles 实现不同环境(开发、测试、生产)下的工具配置切换。

如需进一步了解 spring-ai-mcp-client-spring-boot-starter 的其他功能,可参考官方文档:Spring AI 官方文档。

本站提供的所有下载资源均来自互联网,仅提供学习交流使用,版权归原作者所有。如需商业使用,请联系原作者获得授权。 如您发现有涉嫌侵权的内容,请联系我们 邮箱:[email protected]