Spring Boot 无缝集成SpringAI的函数调用模块
这是一个 完整的 Spring AI 函数调用实例,涵盖从函数定义、注册到实际调用的全流程,以「天气查询」功能为例,结合代码详细说明:
1. 环境准备
1.1 添加依赖
<!-- Spring AI OpenAI -->
<dependency><groupId>org.springframework.ai</groupId><artifactId>spring-ai-openai-spring-boot-starter</artifactId>
</dependency>
1.2 配置 OpenAI 密钥
# application.properties
spring.ai.openai.api-key=YOUR_API_KEY
spring.ai.openai.chat.options.model=gpt-3.5-turbo-0125
2. 定义函数逻辑
2.1 天气服务接口
@Service
public class WeatherService {// 模拟天气数据存储private Map<String, String> weatherData = Map.of("北京", "晴,气温 25°C","上海", "多云,气温 28°C","广州", "阵雨,气温 30°C");/*** 定义函数:获取当前天气* @Function 注解描述函数元数据*/@Function(name = "getCurrentWeather",description = "获取指定城市的当前天气信息",inputType = @Function.Parameter(type = "object",properties = @Function.ParameterProperty(name = "location", type = "string", description = "城市名称,如 '北京'")))public String getWeather(@RequestParam String location) {return weatherData.getOrDefault(location, "暂无该城市天气数据");}
}
3. 注册函数到 Spring AI
3.1 函数回调配置
@Configuration
public class FunctionConfig {@Beanpublic FunctionCallback weatherFunction(WeatherService weatherService) {return new FunctionCallbackWrapper<>("getCurrentWeather", // 函数名称(必须与 @Function 注解一致)"获取天气信息", // 函数描述(可选)weatherService::getWeather, // 函数实现方法引用new WeatherRequestConverter() // 参数转换器(见下一步));}// 参数转换器:将模型传入的 JSON 参数转换为 Java 对象private static class WeatherRequestConverter implements Converter<String, String> {@Overridepublic String convert(String source) {// 解析 JSON 参数(示例简化,实际可使用 Jackson)return source.replaceAll("\"", "").split(":")[1].trim();}}
}
3.2 启用函数调用
@Configuration
public class ChatConfig {@Beanpublic ChatClient chatClient(OpenAiChatClient chatClient,List<FunctionCallback> functionCallbacks) {// 将函数回调注册到 ChatClientchatClient.setFunctionCallbacks(functionCallbacks);return chatClient;}
}
4. 实现对话接口
@RestController
public class ChatController {@Autowiredprivate ChatClient chatClient;@PostMapping("/chat")public String chat(@RequestBody String userMessage) {// 构造对话请求UserMessage message = new UserMessage(userMessage,OpenAiChatOptions.builder().withFunctionCallbacks(List.of("getCurrentWeather")) // 允许调用的函数.build());// 发送请求并获取响应ChatResponse response = chatClient.call(message);// 处理可能的函数调用结果if (response.getMetadata().containsKey("function_call")) {return handleFunctionCall(response);}return response.getResult().getOutput().getContent();}private String handleFunctionCall(ChatResponse response) {// 解析函数调用请求String functionName = response.getMetadata().get("function_call.name").toString();String functionArgs = response.getMetadata().get("function_call.arguments").toString();// 执行函数(此处实际由 Spring AI 自动处理,此处仅为演示)String result = "执行函数 " + functionName + " 参数: " + functionArgs;// 将结果回传模型生成最终回答ChatResponse finalResponse = chatClient.call(new UserMessage("函数执行结果:" + result));return finalResponse.getResult().getOutput().getContent();}
}
5. 完整流程测试
测试请求 1:直接提问
curl -X POST http://localhost:8080/chat -H "Content-Type: text/plain" -d "北京现在的天气怎么样?"
模型响应流程:
- 模型识别需要调用
getCurrentWeather(location="北京")。 - Spring AI 自动触发
WeatherService.getWeather("北京")。 - 函数返回
"晴,气温 25°C"。 - 模型生成最终回答:
"北京当前的天气是晴,气温 25°C。"
测试请求 2:需要澄清参数
curl -X POST http://localhost:8080/chat -d "帮我查一下天气"
模型响应:
请问您要查询哪个城市的天气?
6. 关键代码解析
6.1 函数元数据的重要性
@Function注解:提供模型理解函数用途的关键信息,影响模型是否决定调用。- 参数描述:清晰的参数描述(如
location类型为城市名称)提升模型参数提取准确性。
6.2 函数执行流程
- 模型决策:根据用户输入,模型决定是否调用函数。
- 参数解析:
WeatherRequestConverter将模型传入的 JSON 参数转为 Java 类型。 - 自动执行:Spring AI 自动调用注册的
WeatherService.getWeather()方法。 - 结果回传:函数返回结果自动注入后续对话上下文,模型生成最终回答。
7. 扩展场景
7.1 多函数协同
定义更多函数并注册:
// 股票查询函数
@Function(name = "getStockPrice", description = "查询股票实时价格")
public String getStockPrice(@RequestParam String symbol) { ... }// 注册
@Bean
public FunctionCallback stockFunction(StockService stockService) { ... }
7.2 动态函数调用列表
根据用户身份动态启用不同函数:
UserMessage message = new UserMessage(input,OpenAiChatOptions.builder().withFunctionCallbacks(getAllowedFunctions(userRole)) // 根据角色返回允许的函数列表.build()
);
8. 调试技巧
- 查看元数据:检查
response.getMetadata()中的function_call.*字段。 - 日志拦截:添加
Advisor记录函数调用请求和响应。 - 模拟测试:使用 Mock 替换真实函数实现,验证参数传递逻辑。
将函数调用无缝集成到 Spring Boot 应用以后,即可实现动态数据获取与业务逻辑触发。如需进一步优化(如异步执行函数),可结合 @Async 或消息队列扩展。
相关文章:
Spring Boot 无缝集成SpringAI的函数调用模块
这是一个 完整的 Spring AI 函数调用实例,涵盖从函数定义、注册到实际调用的全流程,以「天气查询」功能为例,结合代码详细说明: 1. 环境准备 1.1 添加依赖 <!-- Spring AI OpenAI --> <dependency><groupId>o…...
【MQ】探索 Kafka
高性能 消息的顺序性、顺序写磁盘 零拷贝 RocketMQ内部主要是使用基于mmap实现的零拷贝,用来读写文件 减少cpu的拷贝次数和上下文切换次数,实现文件的高效读写操作 Kafka 零拷贝 Kafka 使用到了 mmap 和 sendfile 的方式来实现零拷贝。分别对应 Jav…...
指针(C语言)从0到1掌握指针,为后续学习c++打下基础
目录 一,指针 二,内存地址和指针 1,什么是内存地址 2,指针在不同系统下所占内存 三,指针的声明和初始化以及类型 1,指针的声明 2,指针 的初始化 1, 初始化方式优点及适用场景 4,指针的声明初始化类型…...
项目开发实践——基于SpringBoot+Vue3实现的在线考试系统(九)(完结篇)
文章目录 一、成绩查询模块实现1、学生成绩查询功能实现1.1 页面设计1.2 前端页面实现1.3 后端功能实现2、成绩分段查询功能实现2.1 页面设计2.2 前端页面实现2.3 后端功能实现二、试卷练习模块实现三、我的分数模块实现1、 页面设计2、 前端页面实现3、 后端功能实现四、交流区…...
AI DeepSeek-R1 Windos 10 环境搭建
1、安装: 下载 Python |Python.org CUDA Drivers for MAC Archive | NVIDIA pip 和virtualenv Download Ollama on Windows 如下图 2、下载模型 deepseek-r1 ollama run deepseek-r1 或者可以ollama run deepseek-r1:8b 或 3、安装一个可视化对话Chatbox 下载 …...
搜索与图论复习1
1深度优先遍历DFS 2宽度优先遍历BFS 3树与图的存储 4树与图的深度优先遍历 5树与图的宽度优先遍历 6拓扑排序 1DFS: #include<bits/stdc.h> using namespace std; const int N10; int n; int path[N]; bool st[N]; void dfs(int u){if(nu){for(int i0;…...
10.共享内存 信号量集 消息队列
10.共享内存 信号量集 消息队列 **1. IPC对象操作通用框架****2. 共享内存(Shared Memory)****3. 信号量集(Semaphore)****4. 消息队列(Message Queue)****5. 练习与作业****6. 总结** 1. IPC对象操作通用框…...
每日 Java 面试题分享【第 17 天】
欢迎来到每日 Java 面试题分享栏目! 订阅专栏,不错过每一天的练习 今日分享 3 道面试题目! 评论区复述一遍印象更深刻噢~ 目录 问题一:Java 中的访问修饰符有哪些?问题二:Java 中静态方法和实例方法的区…...
【懒删除堆】力扣2349. 设计数字容器系统
设计一个数字容器系统,可以实现以下功能: 在系统中给定下标处 插入 或者 替换 一个数字。 返回 系统中给定数字的最小下标。 请你实现一个 NumberContainers 类: NumberContainers() 初始化数字容器系统。 void change(int index, int numb…...
【Block总结】OutlookAttention注意力,捕捉细节和局部特征|即插即用
论文信息 标题: VOLO: Vision Outlooker for Visual Recognition作者: Li Yuan, Qibin Hou, Zihang Jiang, Jiashi Feng, Shuicheng Yan代码链接: https://github.com/sail-sg/volo论文链接: https://arxiv.org/pdf/2106.13112 创新点 前景注意力机制: VOLO引入了一种称为“…...
有效运作神经网络
内容来自https://www.bilibili.com/video/BV1FT4y1E74V,仅为本人学习所用。 文章目录 训练集、验证集、测试集偏差、方差正则化正则化参数为什么正则化可以减少过拟合Dropout正则化Inverted Dropout其他的正则化方法数据增广Early stopping 归一化梯度消失与梯度爆…...
Vue 组件开发:构建高效可复用的前端界面要素
1 引言 在现代 Web 开发中,构建高效且可复用的前端界面要素是提升开发效率和用户体验的关键。Vue.js 作为一种轻量级且功能强大的前端框架,提供了丰富的工具和机制,帮助开发者快速构建高质量的应用程序。通过合理设计和封装 Vue 组件,我们可以实现组件的高效复用,提高开发…...
【Python】深入探索Python元类:动态生成类与对象的艺术
《Python OpenCV从菜鸟到高手》带你进入图像处理与计算机视觉的大门! 解锁Python编程的无限可能:《奇妙的Python》带你漫游代码世界 元类是Python中一个高级且强大的特性,允许开发者在类的创建过程中插入自定义逻辑,从而动态生成类和对象。本文将全面介绍Python中的元类概…...
Spring Boot + Facade Pattern : 通过统一接口简化多模块业务
文章目录 Pre概述在编程中,外观模式是如何工作的?外观设计模式 UML 类图外观类和子系统的关系优点案例外观模式在复杂业务中的应用实战运用1. 项目搭建与基础配置2. 构建子系统组件航班服务酒店服务旅游套餐服务 3. 创建外观类4. 在 Controller 中使用外…...
在Linux系统上安装.NET
测试系统:openKylin(开放麒麟) 1.确定系统和架构信息: 打开终端(Ctrl Alt T),输入cat /etc/os-release查看系统版本相关信息。 输入uname -m查看系统架构。确保你的系统和架构符合.NET 的要求,如果架构…...
OpenAI Operator:AI Agent 大战的号角,从 “工具” 到 “助手” 的飞跃
想尝试不同的 AI 模型?不必到处寻找!chatTools 为您集成了 o1、GPT4o、Claude 和 Gemini 等多种选择,一个平台解决您的所有 AI 需求。现在就来体验吧! 各位 AI 爱好者们,今天我们来聊聊 OpenAI 的最新力作——Operator…...
AI大模型开发原理篇-9:GPT模型的概念和基本结构
基本概念 生成式预训练模型 GPT(Generative Pre-trained Transformer)模型 是由 OpenAI 开发的基于 Transformer 架构的自然语言处理(NLP)模型,专门用于文本生成任务。它的设计理念在于通过大规模的预训练来学习语言模…...
Java Swing 基础组件详解 [论文投稿-第四届智能系统、通信与计算机网络]
大会官网:www.icisccn.net Java Swing 是一个功能强大的 GUI 工具包,提供了丰富的组件库用于构建跨平台的桌面应用程序。本文将详细讲解 Swing 的基础组件,包括其作用、使用方法以及示例代码,帮助你快速掌握 Swing 的核心知识。 一…...
vscode+WSL2(ubuntu22.04)+pytorch+conda+cuda+cudnn安装系列
最近在家过年闲的没事,于是研究起深度学习开发工具链的配置和安装,之前欲与天公试比高,尝试在win上用vscodecuda11.6vs2019的cl编译器搭建cuda c编程环境,最后惨败,沦为笑柄,痛定思痛,这次直接和…...
【letta】The Letta Platform LETTA平台
The Letta Platform LETTA平台 The Letta Platform LETTA平台开源网站2023年的论文 论文:MemGPT Towards LLMs as Operating Systems Letta enables developers to build and deploy stateful AI agents - agents that maintain memory and context across long-running conve…...
想品客老师的第九天:原型和继承
原型与继承前置看这里 原型 原型都了解了,但是不是所有对象都有对象原型 let obj1 {}console.log(obj1)let obj2 Object.create(null, {name: {value: 荷叶饭}})console.log(obj2) obj2为什么没有对象原型?obj2是完全的数据字典对象,没有…...
Time Constant | RC、RL 和 RLC 电路中的时间常数
注:本文为 “Time Constant” 相关文章合辑。 机翻,未校。 How To Find The Time Constant in RC and RL Circuits June 8, 2024 💡 Key learnings: 关键学习点: Time Constant Definition: The time constant (τ) is define…...
原码、反码、补码以及lowbit运算
原码、反码、补码以及lowbit运算 原码: 可以用来计算正数加减,正数的原码、反码、补码都一样。 第一位为符号位,符号位0为正数,1为负数(32位字符,这里用4位来举例子,后面皆是用4位来举例子,其…...
芯片AI深度实战:实战篇之vim chat
利用vim-ollama这个vim插件,可以在vim内和本地大模型聊天。 系列文章: 芯片AI深度实战:基础篇之Ollama-CSDN博客 芯片AI深度实战:基础篇之langchain-CSDN博客 芯片AI深度实战:实战篇之vim chat-CSDN博客 芯片AI深度…...
当当网近30日热销图书的数据采集与可视化分析(scrapy+openpyxl+matplotlib)
当当网近30日热销图书的数据采集与可视化分析(scrapy+openpyxl+matplotlib) 当当网近30日热销书籍官网写在前面 实验目的:实现当当网近30日热销图书的数据采集与可视化分析。 电脑系统:Windows 使用软件:Visual Studio Code Python版本:python 3.12.4 技术需求:scrapy、…...
Spring Boot 日志:项目的“行车记录仪”
一、什么是Spring Boot日志 (一)日志引入 在正式介绍日志之前,我们先来看看上篇文章中(Spring Boot 配置文件)中的验证码功能的一个代码片段: 这是一段校验用户输入的验证码是否正确的后端代码,…...
幸运数字——蓝桥杯
1.问题描述 哈沙德数是指在某个固定的进位制当中,可以被各位数字之和整除的正整数。例如 126126 是十进制下的一个哈沙德数,因为 (126)10mod(126)0;126 也是八进制下的哈沙德数,因为 (126)10(176)8,(126)10mod(176)…...
Deepseek本地部署(ollama+open-webui)
ollama 首先是安装ollama,这个非常简单 https://ollama.com/ 下载安装即可 open-webui 这个是为了提供一个ui,毕竟我们也不想在cmd和模型交互,很不方便。 第一,需要安装python3.11,必须是3.11(其他版…...
【QT】 控件 -- 显示类
🔥 目录 [TOC]( 🔥 目录) 1. 前言 2. 显示类控件2.1 Label 1、显示不同文本2、显示图片3、文本对齐、自动换行、缩进、边距4、设置伙伴 3.2 LCD Number 3.3 ProgressBar 3.4 Calendar Widget 3. 共勉 🔥 1. 前言 之前我在上一篇文章【QT】…...
冲刺蓝桥杯之速通vector!!!!!
文章目录 知识点创建增删查改 习题1习题2习题3习题4:习题5: 知识点 C的STL提供已经封装好的容器vector,也可叫做可变长的数组,vector底层就是自动扩容的顺序表,其中的增删查改已经封装好 创建 const int N30; vecto…...
