Spring AI与DeepSeek实战四:系统API调用

一、概述
在 AI 应用开发中,工具调用 Tool Calling 是增强大模型能力的核心技术。通过让模型与外部 API 或工具交互,可实现 实时信息检索(如天气查询、新闻获取)、系统操作(如创建任务、发送邮件)等功能。
Spring AI 作为企业级 AI 开发框架,在 1.0.0.M6 版本中进行了重要升级:废弃 Function Calling 引入 Tool Calling 以更贴合行业术语;本文结合 Spring AI 与大模型,演示如何通过 Tool Calling 实现系统 API 调用,同时处理多轮对话中的会话记忆。
关于 Spring AI 与 DeepSeek 的集成,以及 API-KEY 的申请等内容,可参考文章《Spring AI与DeepSeek实战一:快速打造智能对话应用》
二、函数调用原理
大模型仅负责 决定是否调用工具 和 提供参数,实际执行逻辑由客户端(Spring 应用)实现,确保工具调用的可控性与安全性。

2.1. 工具元数据注入
在发起Chat Request时,将工具描述(name/description)、参数结构(input schema)等元数据封装至请求体,建立大模型的工具调用能力基线。
2.2. 模型决策响应
大模型根据上下文推理生成工具调用指令(tool_calls字段),返回包含选定工具名称及结构化参数的中间响应。
2.3. 服务端路由执行
Spring AI模块解析工具调用指令,通过服务发现机制定位目标工具实例,注入参数并触发同步/异步执行。
2.4. 执行结果标准化
工具返回原始执行结果后,系统进行数据类型校验、异常捕获和JSON序列化处理,生成模型可解析的标准化数据结构。
2.5. 上下文增强推理
将标准化结果作为新增上下文(tool_outputs)回传大模型,触发基于增强上下文的二次推理流程。
2.6. 终端响应生成
模型综合初始请求与工具执行结果,生成最终自然语言响应,完成工具增强的对话闭环。
三、核心代码
3.1. 定义工具
创建类 TestTools 并用 @Tool 注解定义 tool 的描述
public static class TestTools {
@Tool(description = "获取今天日期")
String getCurrentDateTime() {
System.out.println("======getCurrentDateTime");
return LocalDate.now().format(DateTimeFormatter.ofPattern("yyyy年MM月dd日"));
}
@Tool(description = "获取当前温度")
String getCurrentTemperature(MyToolReques toolReques) {
System.out.println("======getCurrentTemperature: " + toolReques.localName + "__" + toolReques.date);
return toolReques.date + toolReques.localName + "温度为20摄氏度";
}
public record MyToolReques(String localName, String date) {}
}
这里定义了两个方法,并通过注解的 description 参数告诉大模型方法的用途。
record 类型是 Java17 的新特性,可用于替代传统的 POJO 类。
3.2. 创建对话接口
private ChatMemory chatMemory = new InMemoryChatMemory();
private MessageChatMemoryAdvisor messageChatMemoryAdvisor = new MessageChatMemoryAdvisor(chatMemory);
@GetMapping(value = "/chat")
public String chat(@RequestParam String input, String sessionId, HttpServletResponse response) {
response.setCharacterEncoding("UTF-8");
return chatClient.prompt().user(input)
.tools(new TestTools())
.advisors(messageChatMemoryAdvisor)
.advisors(spec -> spec
.param(MessageChatMemoryAdvisor.CHAT_MEMORY_CONVERSATION_ID_KEY, sessionId))
.call()
.content();
}
- tools 给大模型注册可以调用的方法。
- MessageChatMemoryAdvisor 实现聊天记忆,
InMemoryChatMemory为SpringAI自带的实现(基于内存)。 - 可以使用 CHAT_MEMORY_CONVERSATION_ID_KEY 参数指定对话ID,不同的会话ID用于隔离记忆。
3.3. 测试

通过后台打印信息可以看到大模型会自动识别,先调用 getCurrentDate 方法获取今天日期,再调用 getCurrentTemperature 方法获取天气。
======getCurrentDate
======getCurrentTemperature: 广州__2025年04月13日
加一个聊天框,测试多轮对话效果:

第二次会话直接输入 广州 大模型就知道我要问什么了,说明聊天记忆功能已生效。
四、总结
本文以问天气为场景,通过 Tool Calling 实现系统 API 调用,同时实现多轮对话中的会话记忆。需要注意的是 InMemoryChatMemory 只能作为测试使用,在企业应用中需要使用其他实现方式,把聊天记录存储在 Redis 或者 数据库中,并且需要考虑消息的保存时间、容量、如何清除等问题。
五、完整代码
- Gitee地址:
https://gitee.com/zlt2000/zlt-spring-ai-app
- Github地址:
https://github.com/zlt2000/zlt-spring-ai-app
Spring AI与DeepSeek实战四:系统API调用的更多相关文章
- 多说评论系统API调用和本地身份说明(JWT)
多说评论系统是一个非常好用的第三方评论插件,聚合了大多数的SNS平台账号登录和分享功能,UI也很不错. 作为网站快速接入评论系统,多说是一个比较好的选择,其也提供了一些实用的API去满足定制化需求. ...
- WHMCS系统API调用
WHMCS:域名管理系统,现在网络上很多借助此系统Shadowsocks插件+ShadowsocksR多用户服务端进行VPN的售卖,能做到流量控制等. 在对接此系统的API时,我发现了很多功能都已经实 ...
- Spring Boot 揭秘与实战(四) 配置文件篇 - 有哪些很棒的特性
文章目录 1. 使用属性文件2. YAML文件 1.1. 自定义属性 1.2. 参数引用 1.3. 随机数属性 1.4. application-{profile}.properties参数加载 3. ...
- Spring Cloud第十四篇 | Api网关Zuul
本文是Spring Cloud专栏的第十四篇文章,了解前十三篇文章内容有助于更好的理解本文: Spring Cloud第一篇 | Spring Cloud前言及其常用组件介绍概览 Spring C ...
- Spring Boot 揭秘与实战(三) 日志框架篇 - 如何快速集成日志系统
文章目录 1. 默认的日志框架 logback2. 常用的日志框架 log4j 1.1. 日志级别 1.2. 日志文件 3. 源代码 Java 有很多日志系统,例如,Java Util Logging ...
- AI应用开发实战 - 定制化视觉服务的使用
AI应用开发实战 - 定制化视觉服务的使用 本篇教程的目标是学会使用定制化视觉服务,并能在UWP应用中集成定制化视觉服务模型. 前一篇:AI应用开发实战 - 手写识别应用入门 建议和反馈,请发送到 h ...
- SpringSecurity权限管理系统实战—四、整合SpringSecurity(上)
目录 SpringSecurity权限管理系统实战-一.项目简介和开发环境准备 SpringSecurity权限管理系统实战-二.日志.接口文档等实现 SpringSecurity权限管理系统实战-三 ...
- Spring Boot 揭秘与实战(六) 消息队列篇 - RabbitMQ
文章目录 1. 什么是 RabitMQ 2. Spring Boot 整合 RabbitMQ 3. 实战演练4. 源代码 3.1. 一个简单的实战开始 3.1.1. Configuration 3.1 ...
- Spring Boot 2.X(十四):日志功能 Logback
Logback 简介 Logback 是由 SLF4J 作者开发的新一代日志框架,用于替代 log4j. 主要特点是效率更高,架构设计够通用,适用于不同的环境. Logback 分为三个模块:logb ...
- 【半小时大话.net依赖注入】(下)详解AutoFac+实战Mvc、Api以及.NET Core的依赖注入
系列目录 上|理论基础+实战控制台程序实现AutoFac注入 下|详解AutoFac+实战Mvc.Api以及.NET Core的依赖注入 前言 本来计划是五篇文章的,每章发个半小时随便翻翻就能懂,但是 ...
随机推荐
- react 趟坑
最近一直在做react项目,发现一个bug,困扰了我两天. Can't perform a React state update on an unmounted component. This is ...
- MongoDB:文档基本CRUD
- 《SpringBoot》EasyExcel实现百万数据的导入导出
24年11月6日消息,阿里巴巴旗下的Java Excel工具库EasyExcel近日宣布,将停止更新,未来将逐步进入维护模式,将继续修复Bug,但不再主动新增功能. EasyExcel 是一款知名的 ...
- HPC的基本概念
本文分享自天翼云开发者社区<HPC的基本概念>,作者:它零食抱佛jio HPC(High Performance Computing)是一种高性能计算技术,它利用大规模并行处理器集群或超级 ...
- HPC中常见的调度器介绍
本文分享自天翼云开发者社区<HPC中常见的调度器介绍> 作者:土豆炒肉丝 在高性能计算(HPC)环境中,调度器是负责管理和分配计算资源(如计算节点.处理器核心.内存等)给待执行任务的重要组 ...
- Django项目实战:解除跨域限制
Django项目实战:解除跨域限制 在Web开发中,跨域资源共享(CORS)是一个重要的安全特性,它限制了网页只能与其同源的服务器进行交互.然而,在开发过程中,我们经常需要前端(如Vue.js.Rea ...
- .NET最佳实践:避免滥用Task.Run
在 C# 中,Task.Run 是用来在后台线程中执行异步任务的一个常见方法. 它非常适用于需要并行处理的场景,但如果不加以谨慎使用,可能会导致额外的线程池调度,进而影响程序的性能. 什么是线程池? ...
- Q:nginx 访问报错403 forbidden
curl 访问本地时 403 forbidden 查看nginx日志,路径为/var/log/nginx/error.log (13: Permission denied),详细报错如下: 2021 ...
- 流程控制之do while循环
语法 do { //代码语句}while(布尔表达式): 与while的区别 while是先判断再执行,do while是先执行再判断 循环体至少会被执行一次 实例1: package com. ...
- ORACLE SELECT INTO 赋值为空,抛出 NO DATA FOUND 异常
例子: DECLARE ORDER_NUM VARCHAR2(20); BEGIN SELECT S.ORDER_NUM INTO ORDER_NUM FROM SALES_ORDER S WHERE ...