大模型之 Spring AI实战系列(十七):Spring AI Tools 高级技巧——异步调用、事务控制与错误处理攻略
系列篇章💥
No. | 文章 |
---|---|
1 | 大模型之Spring AI实战系列(一):基础认知篇 - 开启智能应用开发之旅 |
2 | 大模型之Spring AI实战系列(二):Spring Boot + OpenAI 打造聊天应用全攻略 |
3 | 大模型之Spring AI实战系列(三):Spring Boot + OpenAI 实现聊天应用上下文记忆功能 |
4 | 大模型之Spring AI实战系列(四):Spring Boot + OpenAI 使用OpenAI Embedding实现文本向量化 |
5 | 大模型之Spring AI实战系列(五):Spring Boot + OpenAI 构建带角色设定的智能对话系统 |
6 | 大模型之Spring AI实战系列(六):Spring Boot + OpenAI 利用PromptTemplate构建动态提示词系统 |
7 | 大模型之Spring AI实战系列(七):Spring Boot + OpenAI 构建结构化输出的AI响应系统 |
8 | 大模型之Spring AI实战系列(八):Spring Boot + OpenAI 使用Whisper实现语音转文本功能 |
9 | 大模型之Spring AI实战系列(九):Spring Boot + OpenAI 使用TTS实现文本转语音功能 |
10 | 大模型之Spring AI实战系列(十):Spring Boot + OpenAI 使用 DALL·E实现文本生成图像功能 |
11 | 大模型之Spring AI实战系列(十一):Spring Boot + OpenAI 集成本地向量数据库Chroma |
12 | 大模型之Spring AI实战系列(十二):Spring Boot + OpenAI 构建基于RAG的智能问答系统 |
13 | 大模型之Spring AI实战系列(十三):Spring Boot + OpenAI 基于 Tool Calling 实现单个外部工具调用 |
14 | 大模型之Spring AI实战系列(十四):Spring Boot + OpenAI 支持多个 Tool 的插件化调用实践 |
15 | 大模型之 Spring AI实战系列(十五):Spring AI Tools 初体验——搭建首个可调用工具 |
16 | 大模型之 Spring AI实战系列(十六):Spring AI Tools 初级开发——解锁天气查询与数据库操作工具 |
17 | 大模型之 Spring AI实战系列(十七):Spring AI Tools 高级技巧——异步调用、事务控制与错误处理攻略 |
目录
- 系列篇章💥
- 前言
- 一、异步调用工具方法 — 提升响应速度与并发能力
- (一)为什么需要异步调用?
- (二)使用 `CompletableFuture` 实现异步工具调用
- (三)控制器中异步处理示例:
- (四)配置线程池提升并发性能
- 二、事务控制 - 在数据库操作中确保数据一致性
- (一)场景说明
- (二)使用 `@Transactional` 注解管理事务
- (三)注意事项
- 三、错误处理机制 - 构建容错的工具系统
- (一)工具调用失败的常见原因
- (二)在工具方法中捕获异常并返回提示信息
- (三)模型如何反馈错误信息?
- 四、工具链设计 - 多工具协同工作
- (一)同时注册多个工具
- (二)控制调用顺序(串行)
- (三)并行调用多个工具(需模型支持)
- 五、日志追踪与调用链监控
- (一)查看工具调用日志
- (二)使用 MDC 或 Sleuth 进行上下文追踪
- 六、小结
前言
在前两篇文章中,我们已经掌握了如何创建基础的 DateTimeTool 和 WeatherTool、UserQueryTool 等自定义工具,并通过 ChatClient 调用它们。但在实际项目中,仅仅实现功能是不够的,我们还需要考虑性能、稳定性、异常处理等高级开发需求。
一、异步调用工具方法 — 提升响应速度与并发能力
(一)为什么需要异步调用?
在默认情况下,Spring AI 的工具调用是同步阻塞的,即模型会等待工具执行完成后再继续推理。这在执行耗时较长的操作(如网络请求、数据库查询)时会导致性能瓶颈。
(二)使用 CompletableFuture 实现异步工具调用
修改你的 WeatherTool.java,使其支持异步返回:
@Tool(description = "根据城市名查询当前天气情况") public CompletableFuture getWeatherAsync(String city) { String apiKey = "your_openweather_api_key"; String url = "/weather?q={city}&appid={apiKey}&units=metric"; return webClient.get() .uri(url, city, apiKey) .retrieve() .bodyToMono(String.class) .toFuture(); }
(三)控制器中异步处理示例:
@GetMapping("/async-weather") public Mono asyncWeather(@RequestParam String city) { return ChatClient.create(chatModel) .prompt("What is the current weather in " + city + "?") .tools(weatherTool) .call() .content(); }
(四)配置线程池提升并发性能
在 [application.properties] 中配置:
spring.task.execution.pool.core-size=5 spring.task.execution.pool.max-size=10
二、事务控制 - 在数据库操作中确保数据一致性
(一)场景说明
如果你的工具涉及到数据库写操作(如插入、更新),你需要确保其具备事务性,以防止部分操作成功而另一部分失败导致的数据不一致问题。
(二)使用 @Transactional 注解管理事务
修改 UserQueryTool.java,添加一个更新用户邮箱的方法:
@Tool(description = "更新用户的邮箱地址") @Transactional public String updateUserEmail(String username, String newEmail) { Optional userOpt = userRepository.findByUsername(username); if (userOpt.isPresent()) { User user = userOpt.get(); user.setEmail(newEmail); userRepository.save(user); return "邮箱已更新"; } else { return "未找到该用户"; } }
(三)注意事项
- 方法必须为 public;
- 不建议在同一个类内部调用事务方法;
- 可结合 @Transactional(rollbackFor = Exception.class) 指定回滚规则。
三、错误处理机制 - 构建容错的工具系统
(一)工具调用失败的常见原因
类型 示例 网络异常 API 调用超时 参数错误 用户输入非法参数 数据库异常 查询失败或连接中断 (二)在工具方法中捕获异常并返回提示信息
@Tool(description = "根据用户名查询用户信息") public String getUserInfo(String username) { try { Optional userOpt = userRepository.findByUsername(username); if (userOpt.isPresent()) { User user = userOpt.get(); return String.format("找到用户:%s,邮箱:%s", user.getUsername(), user.getEmail()); } else { return "未找到该用户"; } } catch (Exception e) { return "查询过程中发生错误:" + e.getMessage(); } }
(三)模型如何反馈错误信息?
当工具返回错误信息时,模型会将其整合到自然语言回复中,例如:
“查询用户信息失败:未找到该用户。”
四、工具链设计 - 多工具协同工作
(一)同时注册多个工具
.tools(dateTimeTool, weatherTool, userQueryTool)
(二)控制调用顺序(串行)
你可以通过 Prompt 引导模型按顺序调用多个工具:
.prompt("First, tell me the current time. Then, check the weather in Beijing.")
(三)并行调用多个工具(需模型支持)
某些模型(如 GPT-4o)支持一次调用多个工具。你可以在 Prompt 中引导它这样做:
.prompt("Get the current time and the weather in Shanghai at the same time.")
五、日志追踪与调用链监控
(一)查看工具调用日志
启动应用后,观察控制台输出,你会看到类似如下日志:
Function calling: getCurrentDateTime Function response: 2025-04-05T14:30:45
(二)使用 MDC 或 Sleuth 进行上下文追踪
添加依赖:
org.springframework.cloud spring-cloud-starter-sleuth
然后在日志中可以看到调用链 ID、时间戳等信息,便于排查问题。
六、小结
通过本文,你已经掌握了以下技能:
- 使用 CompletableFuture 实现异步工具调用;
- 在数据库操作中使用事务控制;
- 捕获并处理工具调用中的各种异常;
- 设计多工具联合调用流程;
- 使用日志和监控手段追踪工具调用过程。
在下一篇文章中,我们将继续深入探讨 如何将 Spring AI Tools 与 RESTful API 集成,打通企业系统与 AI 的桥梁。欢迎关注!
🎯🔖更多专栏系列文章:AI大模型提示工程完全指南、AI大模型探索之路(零基础入门)、AI大模型预训练微调进阶、AI大模型开源精选实践、AI大模型RAG应用探索实践🔥🔥🔥 其他专栏可以查看博客主页📑
😎 作者介绍:资深程序老猿,从业10年+、互联网系统架构师,目前专注于AIGC的探索(CSDN博客之星|AIGC领域优质创作者)
📖专属社群:欢迎关注【小兵的AI视界】公众号或扫描下方👇二维码,回复‘入群’ 即刻上车,获取邀请链接。
💘领取三大专属福利:1️⃣免费赠送AI+编程📚500本,2️⃣AI技术教程副业资料1套,3️⃣DeepSeek资料教程1套🔥(限前500人)
如果文章内容对您有所触动,别忘了点赞、⭐关注,收藏!加入我们,一起携手同行AI的探索之旅,开启智能时代的大门!