☰
Spring AI Alibaba Graph框架实现Tools工具调用
2026/10/1 2:57:17 网站建设 项目流程

目录

前言

Spring AI Alibaba Graph框架实现Agent工作流水线

一、为什么需要 Tools 工具调用?

二、项目依赖

三、定义工具类 MyTools

关键注解说明

四、配置 ChatClient 注册工具

defaultTools 与 tools 的区别

五、Controller 层

六、测试验证

七、工具调用的底层原理

八、注意事项

九、小结


前言

在上一篇博客中,我们完成了 Spring AI Alibaba 项目的搭建,实现了基本的 ChatClient 对话功能。但此时的 AI 还只是一个“只会聊天”的模型——它无法获取实时信息,也无法执行任何实际操作。本篇博客将在此基础上,为 ChatClient 集成Tools 工具调用能力,让 AI 能够真正“动手做事”。

阅读前提:建议先阅读第一篇,了解 Spring AI Alibaba 的基础配置和 ChatClient 的构建方式。

Spring AI Alibaba Graph框架实现Agent工作流水线

一、为什么需要 Tools 工具调用?

大语言模型有一个根本性的局限:它无法访问实时信息,也无法执行操作。

当你问“现在几点了”,模型只能回复“我无法获取实时时间”。当你问“北京天气怎么样”,模型同样无能为力——因为这些信息不在它的训练数据中,它也没有能力主动去查询。

Tools(工具调用)正是为了解决这个问题。它的本质是:让模型能够请求调用应用程序中定义的方法,并将方法返回值作为上下文继续推理。

需要特别强调的是,模型永远无法直接访问你定义的任何工具 API。整个流程是:模型只负责“决定调用哪个工具、传什么参数”,真正的执行逻辑完全由客户端应用程序负责-15。这是一个关键的安全设计。

Tools 主要用于两类场景:

  • 信息检索:从数据库、Web 服务、文件系统等外部源获取数据,增强模型的知识

  • 执行操作:发送邮件、创建记录、提交表单、触发工作流等自动化任务

二、项目依赖

在第一篇的基础上,需要确保以下依赖已配置:

<dependency> <groupId>org.projectlombok</groupId> <artifactId>lombok</artifactId> <version>${lombok.version}</version> </dependency> <dependency> <groupId>cn.hutool</groupId> <artifactId>hutool-all</artifactId> <version>${hutool-all.version}</version> </dependency> <dependency> <groupId>org.mapstruct</groupId> <artifactId>mapstruct</artifactId> <version>${mapstruct.version}</version> </dependency> <dependency> <groupId>org.mapstruct</groupId> <artifactId>mapstruct-processor</artifactId> <version>${mapstruct.version}</version> </dependency>

application.yml配置:

spring: ai: dashscope: api-key: ${AI_DASHSCOPE_API_KEY} chat: options: model: qwen-plus

或者application.properties配置:

spring.ai.openai.api-key=${AI_DASHSCOPE_API_KEY} spring.ai.openai.base-url=https://llm-o4uz6dvcl1e8uyxv.cn-beijing.maas.aliyuncs.com/compatible-mode #spring.ai.openai.chat.options.model=qwen3.7-max spring.ai.openai.chat.options.model=deepseek-v4-flash

三、定义工具类 MyTools

在 Spring AI 中,定义工具最简单的方式是使用@Tool注解。任何 Spring Bean 中的方法,只要加上@Tool注解,就可以被大模型识别并调用。我们创建一个MyTools类,包含两个工具:一个无参数的“获取当前时间”,一个带参数的“查询天气”:

@Component public class MyTools { // ===== 无参数工具:获取当前时间 ===== @Tool(description = "获取当前系统时间,包括年月日时分秒") public String getCurrentTime() { LocalDateTime now = LocalDateTime.now(); DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy年MM月dd日 HH:mm:ss"); return now.format(formatter); } // ===== 带参数工具:查询天气 ===== @Tool(description = "查询指定城市的实时天气情况") public String getWeather( @ToolParam(description = "城市名称,如:北京、上海、深圳") String city) { // 这里可以调用第三方天气 API,目前返回模拟数据 return String.format("城市:%s,天气:晴,温度:28°C,湿度:60%%", city); } }

关键注解说明

@Tool:标记一个方法为可调用工具。description属性至关重要,它告诉模型这个工具是做什么的、什么时候应该使用它。描述越准确,模型选择工具的准确性越高-。

@ToolParam:为工具方法的参数添加描述。Spring AI 会根据方法签名自动生成参数的 JSON Schema,而@ToolParam则为每个参数提供人类可读的说明,帮助模型正确填充参数值-10。

类上的@Component:工具类必须注册为 Spring Bean,这样才能在 ChatClient 构建时注入。

四、配置 ChatClient 注册工具

接下来修改AIServiceImpl,在构建 ChatClient 时通过defaultTools()方法注册工具:

@Service public class AIServiceImpl implements AIService { private final ChatClient chatClient; public AIServiceImpl(ChatClient.Builder builder, ChatMemory chatMemory, MyTools myTools) { this.chatClient = builder // 注册对话记忆 .defaultAdvisors(MessageChatMemoryAdvisor.builder(chatMemory).build()) // 注册 Tool:让大模型知道有哪些工具可用 .defaultTools(myTools) .build(); } public String ask(String question) { return chatClient.prompt() .user(question) .call() .content(); } }

defaultTools 与 tools 的区别

Spring AI 提供了两种注册工具的方式:

方法作用范围适用场景
.defaultTools()该 ChatClient 的所有请求全局工具,所有对话都可用
.tools()仅当前一次请求临时工具,针对特定问题

defaultTools()是ChatClient.Builder接口的方法,注册的工具会在该 Builder 构建出的所有 ChatClient 请求中生效-。对于本项目来说,时间和天气是通用能力,适合使用defaultTools()。

五、Controller 层

Controller 层保持不变,直接调用 Service 即可:

@GetMapping("/ask") public String ask(@RequestParam String question) { return aiService.ask(question); }

六、测试验证

启动项目后,通过浏览器或 curl 测试:

测试 1:询问时间

GET http://localhost:8080/ask?question=现在几点了

预期 AI 会调用getCurrentTime()工具,返回类似:

现在是2025年6月15日 14:30:25。

测试 2:查询天气

GET http://localhost:8080/ask?question=北京天气怎么样

预期 AI 会调用getWeather("北京")工具,返回类似:

北京当前天气:晴,温度28°C,湿度60%。

测试 3:不涉及工具的普通对话

GET http://localhost:8080/ask?question=你好

AI 会正常回复,不会触发任何工具调用。

七、工具调用的底层原理

理解工具调用的执行流程,有助于排查问题和优化效果。

Spring AI 在底层通过ToolCallingAdvisor来管理工具调用的完整生命周期。整个流程如下:

  1. 注入工具定义:ChatClient 将@Tool方法的名称、描述、参数 Schema 提取出来,连同用户问题一起发送给模型。

  2. 模型决策:模型判断是否需要调用工具。如果需要,返回一个包含工具调用请求的响应(指定调用哪个工具、传什么参数)。

  3. 执行工具:ToolCallingManager找到对应的工具方法并执行,将返回值追加到对话历史中。

  4. 循环推理:更新后的对话历史(包含工具执行结果)再次发送给模型,模型基于工具返回的数据生成最终回答。

  5. 终止条件:当模型返回的响应中不包含任何工具调用请求时,循环结束,最终答案返回给用户。

值得注意的是,上述流程在需要时会自动循环执行——如果模型需要连续调用多个工具,框架会持续迭代,直到模型给出不含工具调用的最终回答。

八、注意事项

1. 工具描述的质量直接影响调用准确率

@Tool的description是模型判断“是否调用”和“调用哪个”的唯一依据。描述应该清晰说明工具的用途和使用场景,而不是简单的方法名翻译。

2. 参数类型要明确

@ToolParam中的描述应包含参数格式提示(如日期格式、城市名称示例等),帮助模型正确填充参数。

3. 工具返回结果不宜过长

工具返回的内容会作为上下文发送给模型,过长的返回结果会消耗 Token 并可能干扰模型推理。建议只返回模型需要的核心信息。

4. 模型支持情况

并非所有大模型都支持工具调用功能。DashScope 的 qwen-plus、qwen-max 等模型均已支持。

5. 后续进阶

本篇介绍的是ChatClient 层级的工具调用,这是最基础也最常用的方式。Spring AI Alibaba 的 Graph 框架提供了更强大的ToolNode 工具节点,可以将工具调用作为工作流中的一个独立节点进行编排,支持并行执行、条件路由等高级能力。这部分内容将在后续博客中展开。

九、小结

本篇博客完成了以下工作:

  1. 理解了 Tools 工具调用的核心价值和使用场景

  2. 通过@Tool和@ToolParam注解定义了两个工具方法(无参数 + 带参数)

  3. 使用defaultTools()将工具注册到 ChatClient

  4. 验证了 AI 能够自动识别并调用工具完成实时信息查询

下一篇将进入Spring AI Alibaba Graph 框架,探索如何用 Graph 编排更复杂的 Agent 工作流。

需要专业的网站建设服务?

联系我们获取免费的网站建设咨询和方案报价,让我们帮助您实现业务目标

立即咨询