尧图网络科技YAOTU DIGITAL 获取报价
获取报价
首页 / 资讯中心 / 文章详情

Spring AI Tools 工具配置 TaoToken:@Tool/@ToolParam 与 MethodToolCallback 骨架

发布时间:2026/9/29 3:41:39

资讯中心
01
ARTICLE

Spring AI Tools 工具配置 TaoToken:@Tool/@ToolParam 与 MethodToolCallback 骨架

Spring AI Tools 工具配置 TaoToken:@Tool/@ToolParam 与 MethodToolCallback 骨架
1. Spring AI Tools 工具调用链路为什么需要统一 Key 通道Spring AI Tools 是 Spring AI 框架里让大模型能够调用外部 Java 方法的一套机制。简单说它把普通的方法变成大模型可以“看懂并调用”的工具模型在对话过程中判断需要执行某个动作时就会生成工具调用请求框架负责反射执行并把结果回传给模型。适合谁适合已经在用 Spring Boot 做后端、想让 AI 真正“动手做事”的 Java 开发者比如查数据库、调内部接口、做计算、发通知。但实际落地时很多人卡在第一步模型通道怎么配。Spring AI 默认对接各家模型有自己的 starter一旦你想换模型、想统一管理 Key、想在一个项目里同时用多个模型做对比配置就会散落在 application.yml、环境变量、甚至硬编码里。我试过在一个项目里同时接三家模型结果 Key 管理乱成一团后来把模型通道统一收敛到 TaoToken 的 OpenAI 兼容接口Spring AI 侧只需要改 base-url 和 api-key 两个值工具调用链路完全不用动。这篇就聚焦这条链路用 TaoToken 作为统一 Key/API 通道在 Spring Boot 里配好 application.yml用 Tool/ToolParam 定义工具再用 MethodToolCallback 手动注册已有方法最后跑一次本地调用验证工具回调是否真的触发。全程可复制跟着做就能跑通。2. TaoToken 前置拿到统一 Key 与兼容端点TaoToken 在这里扮演的角色是“模型调用的统一入口”。Spring AI 的 OpenAI starter 支持自定义 base-url所以只要 TaoToken 提供 OpenAI 兼容的 /v1/chat/completions 端点Spring AI 就能直接对接工具调用的 function calling 字段也能正常传递。你需要先拿到一个 API Key。进入控制台创建即可控制台入口https://taotoken.net/console?utm_sourcetaotoken_aicg_blog_endutm_mediumcsdnutm_campaignrewriteutm_contentconsoleAPI Key 管理https://taotoken.net/api-keys?utm_sourcetaotoken_aicg_blog_endutm_mediumcsdnutm_campaignrewriteutm_contentapi-keys创建完 Key 之后记下两个值一个是 Key 本身一个是 base-url。TaoToken 的 API 根地址是https://taotoken.net/api注意这个地址不带任何查询参数Spring AI 里配置时通常需要带上/v1后缀具体以你使用的 starter 版本为准OpenAI 兼容模式一般填到/v1。注意Key 不要写死在代码里提交到仓库用环境变量或配置中心注入。下面示例里我用${TAOTOKEN_API_KEY}占位。如果你还没决定用哪个模型可以先去模型对话页面看看当前支持的模型列表选一个支持 function calling 的模型对话https://taotoken.net/chat?utm_sourcetaotoken_aicg_blog_endutm_mediumcsdnutm_campaignrewriteutm_contentmodel-chat3. 可复制配置application.yml 与依赖3.1 Maven 依赖Spring AI 的版本迭代较快这里用 1.0.x 系列的坐标。核心是 OpenAI starter 和 tools 支持tools 通常已包含在核心包里。dependency groupIdorg.springframework.ai/groupId artifactIdspring-ai-starter-model-openai/artifactId version1.0.0/version /dependency dependency groupIdorg.springframework.boot/groupId artifactIdspring-boot-starter-web/artifactId /dependency dependency groupIdorg.projectlombok/groupId artifactIdlombok/artifactId optionaltrue/optional /dependency3.2 application.yml关键点把 base-url 指向 TaoTokenapi-key 用环境变量注入chat 的 options 里指定模型名。spring: ai: openai: # TaoToken 的 OpenAI 兼容端点注意 /v1 后缀 base-url: https://taotoken.net/api/v1 api-key: ${TAOTOKEN_API_KEY} chat: options: # 换成你在模型对话页确认可用的模型名 model: gpt-4o-mini temperature: 0.7启动前设置环境变量export TAOTOKEN_API_KEY你的Key3.3 注入 ChatClientSpring AI 的自动配置会基于上面的 yml 创建OpenAiChatModel我们把它包成ChatClient方便链式调用。import org.springframework.ai.chat.client.ChatClient; import org.springframework.ai.chat.model.ChatModel; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; Configuration public class ChatClientConfig { Bean public ChatClient chatClient(ChatModel chatModel) { return ChatClient.builder(chatModel).build(); } }到这里模型通道就通了。接下来定义工具。4. Tool/ToolParam 定义工具与 MethodToolCallback 注册骨架4.1 用注解定义工具Tool标注在方法上description是给模型看的模型靠它判断“什么时候该调用这个工具”。ToolParam标注在参数上required控制是否必填。import lombok.extern.slf4j.Slf4j; import org.springframework.ai.tool.annotation.Tool; import org.springframework.ai.tool.annotation.ToolParam; import java.time.LocalDateTime; import java.time.ZoneId; import java.time.format.DateTimeFormatter; Slf4j public class CommonTools { Tool(description 获取用户所在时区的当前日期和时间) public String getCurrentDateTime() { DateTimeFormatter fmt DateTimeFormatter.ofPattern(yyyy-MM-dd HH:mm:ss); String now fmt.format(LocalDateTime.now().atZone(ZoneId.of(Asia/Shanghai))); log.info(当前时间 {}, now); return now; } Tool(name setAlarm, description 以ISO-8601格式为给定时间设置用户闹钟提醒) public void setAlarm( ToolParam(description ISO-8601格式的时间, required true) String time) { LocalDateTime alarmTime LocalDateTime.parse(time, DateTimeFormatter.ISO_DATE_TIME); log.info(设置闹钟的时间 {} - {}, time, alarmTime); } }4.2 用注解方式直接挂到 ChatClient这是最省事的方式.tools(对象)会自动扫描对象里的Tool方法。GetMapping(/base) public String base() { String content chatClient.prompt() .user(当前时间是多少星期几) .tools(new CommonTools()) .call() .content(); log.info(使用工具回复: {}, content); return content; }4.3 MethodToolCallback 注册骨架当你的方法已经存在于某个 Service 里、不想为了加注解去改它或者需要动态控制工具元数据时用MethodToolCallback手动注册。核心是三步反射拿到 Method、构建 ToolDefinition、绑定 toolObject。import org.springframework.ai.tool.ToolCallback; import org.springframework.ai.tool.method.MethodToolCallback; import org.springframework.ai.tool.support.ToolDefinitions; import org.springframework.util.ReflectionUtils; import java.lang.reflect.Method; public ToolCallback buildUserListCallback(UserService userService) { Method method ReflectionUtils.findMethod(UserService.class, getUserList); if (method null) { throw new IllegalStateException(getUserList 方法未找到); } return MethodToolCallback.builder() .toolDefinition(ToolDefinitions.builder(method) .name(getUserList) .description(获取所有用户信息用户名列表) .build()) .toolMethod(method) .toolObject(userService) .build(); }toolObject是方法所属的实例。如果方法是静态的可以省略这个参数。ToolDefinitions.builder(method)会自动根据方法签名生成 inputSchema你也可以用.inputSchema({...})手动覆盖。4.4 带参数的 MethodToolCallback参数是对象时用JsonPropertyDescription描述字段模型才能正确填充。import com.fasterxml.jackson.annotation.JsonProperty; import com.fasterxml.jackson.annotation.JsonPropertyDescription; import lombok.AllArgsConstructor; import lombok.Data; import lombok.NoArgsConstructor; Data AllArgsConstructor NoArgsConstructor public static class UserModel { JsonPropertyDescription(用户名) JsonProperty(required true) private String name; JsonPropertyDescription(用户年龄) JsonProperty(required true) private Integer age; }注册时把addUser方法绑上去Method addMethod ReflectionUtils.findMethod(UserService.class, addUser, UserService.UserModel.class); ToolCallback addCallback MethodToolCallback.builder() .toolDefinition(ToolDefinitions.builder(addMethod) .name(addUser) .description(添加用户信息) .build()) .toolMethod(addMethod) .toolObject(userService) .build();5. 验证请求本地调用确认工具回调触发写一个 Controller把上面两种方式都跑一遍观察日志里工具方法是否被真正执行。import lombok.RequiredArgsConstructor; import lombok.extern.slf4j.Slf4j; import org.springframework.ai.chat.client.ChatClient; import org.springframework.ai.tool.ToolCallback; import org.springframework.web.bind.annotation.GetMapping; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RestController; Slf4j RestController RequiredArgsConstructor RequestMapping(/chat/tools) public class ToolsController { private final ChatClient chatClient; private final UserService userService; GetMapping(/base) public String base() { String content chatClient.prompt() .user(当前时间是多少星期几) .tools(new CommonTools()) .call() .content(); log.info(注解方式回复: {}, content); return content; } GetMapping(/listUser) public String listUser() { ToolCallback callback buildUserListCallback(userService); String content chatClient.prompt() .user(查询一下用户列表) .toolCallbacks(callback) .call() .content(); log.info(MethodToolCallback 回复: {}, content); return content; } }启动后访问http://localhost:8080/chat/tools/base控制台应该能看到类似输出当前时间 2025-01-15 14:32:10 注解方式回复: 现在是2025年1月15日 14:32星期三。访问/chat/tools/listUser日志里会出现getUserList被调用的痕迹模型回复里包含张三、李四、王五。如果工具没触发模型会直接编造一个用户列表这时候就要检查 description 是否足够清晰、模型是否支持 function calling。提示用户提示词里最好显式引导模型去调用工具比如“请先获取当前时间再回答”否则模型有时会跳过工具直接输出导致时间错误。6. 本篇常见错排查工具没被调用模型直接编答案。最常见的原因是 description 写得太模糊模型判断不出该不该用。把 description 写成“获取用户所在时区的当前日期和时间”比“获取时间”有效得多。另外确认你选的模型支持 function calling部分轻量模型不支持。报 401 或 403。检查TAOTOKEN_API_KEY环境变量是否真的注入到进程里echo $TAOTOKEN_API_KEY确认一下。base-url 是否带了/v1TaoToken 的 OpenAI 兼容端点在/api/v1下。MethodToolCallback 报 inputSchema 生成失败。通常是方法参数类型太复杂Jackson 无法推导 schema。解决办法是用.inputSchema({...})手动指定 JSON Schema或者把参数换成简单类型。工具执行了但模型没拿到结果。检查toolCallResultConverter默认的DefaultToolCallResultConverter会把返回值序列化成字符串。如果你返回的是复杂对象且没实现序列化可能传空。简单起见先返回 String。静态方法注册报 toolObject 相关错误。静态方法不需要toolObject去掉.toolObject(...)这一行即可。多轮对话里工具结果丢失。如果你自己管理 ChatMemory记得把工具执行结果也 add 进 memory否则下一轮模型看不到工具返回的内容。7. 下一步把工具链路接到长期编码场景工具调用跑通之后下一步通常是把它接到实际的编码或 Agent 场景里。如果你打算在 IDE 或命令行里长期用这套通道做代码辅助可以看看 Coding PlanCoding Planhttps://taotoken.net/coding-plan?utm_sourcetaotoken_aicg_blog_endutm_mediumcsdnutm_campaignrewriteutm_contentcoding-plan如果你更想先在网页里验证模型对工具调用的支持情况直接去模型对话页试模型对话https://taotoken.net/chat?utm_sourcetaotoken_aicg_blog_endutm_mediumcsdnutm_campaignrewriteutm_contentmodel-chat接入过程中遇到 Key 或端点问题回到 API Keys 页面核对API Keyshttps://taotoken.net/api-keys?utm_sourcetaotoken_aicg_blog_endutm_mediumcsdnutm_campaignrewriteutm_contentapi-keys配置细节和参数说明以官方文档为准接入文档https://taotoken.net/doc?utm_sourcetaotoken_aicg_blog_endutm_mediumcsdnutm_campaignrewriteutm_contentdoc我自己的习惯是先把/base这个最简单的无参工具跑通确认日志里工具方法被调用再去加带参数的工具和 MethodToolCallback。这样出问题时排查范围小不会一上来就被 schema 和反射绕晕。
02
RELATED NEWS

相关资讯

更多网站建设与数字化升级内容

03
WHY YAOTU

想打造同款高转化官网?

懂行业、懂生意,从建站到增长一站式陪跑

◈

场景化定制

不做模板站,围绕你的业务场景量身设计,小众不撞款。

◐

营销型架构

以转化目标组织内容与路径,让官网真正带来询盘。

▲

全周期服务

设计、开发、运营、运维一体,上线只是开始。

免费获取你的建站方案

留下需求,专属顾问 24 小时内为你输出方案建议。