当前位置: 首页 > news >正文

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 "北京现在的天气怎么样?"

模型响应流程

  1. 模型识别需要调用 getCurrentWeather(location="北京")
  2. Spring AI 自动触发 WeatherService.getWeather("北京")
  3. 函数返回 "晴,气温 25°C"
  4. 模型生成最终回答:"北京当前的天气是晴,气温 25°C。"
测试请求 2:需要澄清参数
curl -X POST http://localhost:8080/chat -d "帮我查一下天气"

模型响应

请问您要查询哪个城市的天气?

6. 关键代码解析

6.1 函数元数据的重要性
  • @Function 注解:提供模型理解函数用途的关键信息,影响模型是否决定调用。
  • 参数描述:清晰的参数描述(如 location 类型为城市名称)提升模型参数提取准确性。
6.2 函数执行流程
  1. 模型决策:根据用户输入,模型决定是否调用函数。
  2. 参数解析WeatherRequestConverter 将模型传入的 JSON 参数转为 Java 类型。
  3. 自动执行:Spring AI 自动调用注册的 WeatherService.getWeather() 方法。
  4. 结果回传:函数返回结果自动注入后续对话上下文,模型生成最终回答。

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. 调试技巧

  1. 查看元数据:检查 response.getMetadata() 中的 function_call.* 字段。
  2. 日志拦截:添加 Advisor 记录函数调用请求和响应。
  3. 模拟测试:使用 Mock 替换真实函数实现,验证参数传递逻辑。

将函数调用无缝集成到 Spring Boot 应用以后,即可实现动态数据获取与业务逻辑触发。如需进一步优化(如异步执行函数),可结合 @Async 或消息队列扩展。

相关文章:

Spring Boot 无缝集成SpringAI的函数调用模块

这是一个 完整的 Spring AI 函数调用实例&#xff0c;涵盖从函数定义、注册到实际调用的全流程&#xff0c;以「天气查询」功能为例&#xff0c;结合代码详细说明&#xff1a; 1. 环境准备 1.1 添加依赖 <!-- Spring AI OpenAI --> <dependency><groupId>o…...

Ansible自动化运维实战--yaml的使用和配置(7/8)

文章目录 一、YAML 基本语法1.1. 缩进1.2. 注释1.3. 列表1.4. 字典 二、Ansible 中 YAML 的应用2.1. Ansible 剧本&#xff08;Playbooks&#xff09;2.2. 变量定义2.3. 角色&#xff08;Roles&#xff09;2.4. Inventory 文件2.5. 数据类型2.6. 引用变量 在 Ansible 里&#x…...

kamailio-5.8.4-centos9编译

安装必要的依赖包 在开始编译之前&#xff0c;你需要安装编译 Kamailio 所需的一些基础依赖包&#xff1a; dnf install -y make gcc gcc-c flex bison libxml2-devel openssl-devel sqlite-devel mysql-devel pcre-devel libcurl-devel下载并解压 Kamailio 源码包 假设你已经…...

单例模式 - 单例模式的实现与应用

引言 单例模式&#xff08;Singleton Pattern&#xff09;是设计模式中最简单且最常用的模式之一。它确保一个类只有一个实例&#xff0c;并提供一个全局访问点来访问该实例。单例模式常用于需要全局唯一对象的场景&#xff0c;如配置管理、日志记录、线程池等。 本文将详细介…...

hadoop==docker desktop搭建hadoop

hdfs map readuce yarn https://medium.com/guillermovc/setting-up-hadoop-with-docker-and-using-mapreduce-framework-c1cd125d4f7b 清理资源 docker-compose down docker system prune -f...

zookeeper的介绍和简单使用

1 zookerper介绍 zookeeper是一个开源的分布式协调服务&#xff0c;由Apache软件基金会提供&#xff0c;主要用于解决分布式应用中的数据管理、状态同步和集群协调等问题。通过提供一个高性能、高可用的协调服务&#xff0c;帮助构建可靠的分布式系统。 Zookeeper的特点和功能…...

DiffuEraser: 一种基于扩散模型的视频修复技术

视频修复算法结合了基于流的像素传播与基于Transformer的生成方法&#xff0c;利用光流信息和相邻帧的信息来恢复纹理和对象&#xff0c;同时通过视觉Transformer完成被遮挡区域的修复。然而&#xff0c;这些方法在处理大范围遮挡时常常会遇到模糊和时序不一致的问题&#xff0…...

CentOS/Linux Python 2.7 离线安装 Requests 库解决离线安装问题。

root@mwcollector1 externalscripts]# cat /etc/os-release NAME=“Kylin Linux Advanced Server” VERSION=“V10 (Sword)” ID=“kylin” VERSION_ID=“V10” PRETTY_NAME=“Kylin Linux Advanced Server V10 (Sword)” ANSI_COLOR=“0;31” 这是我系统的版本,由于是公司内网…...

World of Warcraft [CLASSIC] Jewelcrafting Gemstone 2

World of Warcraft [CLASSIC] Jewelcrafting & Gemstone 2 珠宝加工与常用宝石列表&#xff08;紫色史诗级&#xff09;&#xff1a; World of Warcraft [CLASSIC] Jewelcrafting & Gemstone_wlk宝石属性一览表-CSDN博客...

AI刷题-最小化团建熟悉程度和

目录 问题描述 输入格式 输出格式 解题思路&#xff1a; 状态表示 状态转移 动态规划数组 预处理 实现&#xff1a; 1.初始化&#xff1a; 2.动态规划部分&#xff1a; &#xff08;1&#xff09;对于已分组状态的&#xff0c;跳过&#xff1a; &#xff08;2&…...

一文详解Filter类源码和应用

背景 在日常开发中&#xff0c;经常会有需要统一对请求做一些处理&#xff0c;常见的比如记录日志、权限安全控制、响应处理等。此时&#xff0c;ServletApi中的Filter类&#xff0c;就可以很方便的实现上述效果。 Filter类 是一个接口&#xff0c;属于 Java Servlet API 的一部…...

应用层协议 HTTP 讲解实战:从0实现HTTP 服务器

&#x1f308; 个人主页&#xff1a;Zfox_ &#x1f525; 系列专栏&#xff1a;Linux 目录 一&#xff1a;&#x1f525; HTTP 协议 &#x1f98b; 认识 URL&#x1f98b; urlencode 和 urldecode 二&#xff1a;&#x1f525; HTTP 协议请求与响应格式 &#x1f98b; HTTP 请求…...

DDD-全面理解领域驱动设计中的各种“域”

一、DDD-领域 在领域驱动设计&#xff08;Domain-Driven Design&#xff0c;DDD&#xff09;中&#xff0c;**领域&#xff08;Domain&#xff09;**指的是软件系统所要解决的特定业务问题的范围。它涵盖了业务知识、规则和逻辑&#xff0c;是开发团队与领域专家共同关注的核心…...

PHP防伪溯源一体化管理系统小程序

&#x1f50d; 防伪溯源一体化管理系统&#xff0c;品质之光&#xff0c;根源之锁 &#x1f680; 引领防伪技术革命&#xff0c;重塑品牌信任基石 我们自豪地站在防伪技术的前沿&#xff0c;为您呈现基于ThinkPHP和Uniapp精心锻造的多平台&#xff08;微信小程序、H5网页&…...

纯css实现div宽度可调整

<!DOCTYPE html> <html lang"en"><head><meta charset"UTF-8" /><meta name"viewport" content"widthdevice-width, initial-scale1.0" /><title>纯css实现div尺寸可调整</title><style…...

C# 中使用Hash用于密码加密

通过一定的哈希算法&#xff08;典型的有MD5&#xff0c;SHA-1等&#xff09;&#xff0c;将一段较长的数据映射为较短小的数据&#xff0c;这段小数据就是大数据的哈希值。他最大的特点就是唯一性&#xff0c;一旦大数据发生了变化&#xff0c;哪怕是一个微小的变化&#xff0…...

如何建设一个企业级的数据湖

建设一个企业级的数据湖是一项复杂且系统化的工程&#xff0c;需要从需求分析、技术选型、架构设计到实施运维等多个方面进行综合规划和实施。以下是基于我搜索到的资料&#xff0c;详细阐述如何建设企业级数据湖的步骤和关键要点&#xff1a; 一、需求分析与规划 明确业务需…...

目标跟踪之sort算法(3)

这里写目录标题 1 流程1 预处理2 跟踪 2 代码 参考&#xff1a;sort代码 https://github.com/abewley/sort 1 流程 1 预处理 1.1 获取离线检测数据。1.2 实例化跟踪器。2 跟踪 2.1 轨迹处理。根据上一帧的轨迹预测当前帧的轨迹&#xff0c;剔除到当前轨迹中为空的轨迹得到当前…...

【java数据结构】HashMapOJ练习题

【java数据结构】HashMapOJ练习题 一、只出现一次的数字二 、随机链表的复制三 、宝石与石头四、坏键盘打字五、前K个高频单词 博客最后附有整篇博客的全部代码&#xff01;&#xff01;&#xff01; 一、只出现一次的数字 只出现一次的数字 思路&#xff1a; 先遍历一遍数组…...

Nginx前端后端共用一个域名如何配置

在 Nginx 中配置前端和后端共用一个域名的情况&#xff0c;通常是通过路径或子路径将请求转发到不同的服务。以下是一个示例配置&#xff0c;假设&#xff1a; 前端静态文件在 /var/www/frontend/。 后端 API 服务运行在 http://127.0.0.1:5000。 域名是 example.com&#xff…...

从零搭建WebRTC信令服务:SpringBoot WebSocket与Vue3的实战协同

1. WebRTC信令服务基础认知 第一次接触WebRTC时&#xff0c;我被它直接建立P2P连接的能力惊艳到了——就像两个陌生人突然跳过所有中间环节直接开始面对面交流。但很快我发现&#xff0c;这种"魔法"背后需要一套精密的协调机制&#xff0c;这就是信令服务的用武之地。…...

springboot-vue+nodejs的旅游个性化定制平台的设计与实现

目录技术栈选型系统架构设计数据库设计核心功能实现推荐算法实现前端界面设计测试部署方案项目进度安排项目技术支持源码获取详细视频演示 &#xff1a;文章底部获取博主联系方式&#xff01;同行可合作技术栈选型 后端采用Spring Boot框架&#xff0c;提供RESTful API接口。数…...

【深度学习】RoBERTa:BERT的优化升级与实战应用

1. RoBERTa&#xff1a;BERT的全面进化 第一次接触RoBERTa时&#xff0c;我正为一个电商评论情感分析项目发愁。当时用BERT模型效果总是不稳定&#xff0c;直到尝试了RoBERTa&#xff0c;准确率直接提升了5个百分点。这个经历让我意识到&#xff0c;看似细微的技术改进在实际应…...

ACE协议实战:如何通过AxDOMAIN信号优化多核SoC的缓存一致性?

ACE协议实战&#xff1a;AxDOMAIN信号在多核SoC缓存一致性中的深度优化 1. 多核SoC缓存一致性的工程挑战 在现代嵌入式系统设计中&#xff0c;多核处理器架构已成为提升性能的主流方案。当我们把多个ARM Cortex-A系列核心集成到同一芯片时&#xff0c;缓存一致性管理立即成为系…...

从动漫生成到金融风控:LSGAN损失函数在5个行业的落地对比(附数据集下载)

从动漫生成到金融风控&#xff1a;LSGAN损失函数在5个行业的落地对比 当生成对抗网络&#xff08;GAN&#xff09;遇上最小二乘损失函数&#xff08;LSGAN&#xff09;&#xff0c;会擦出怎样的火花&#xff1f;这个看似简单的数学改进&#xff0c;正在悄然改变多个行业的AI应用…...

正铲单斗液压挖掘机工作装置设计【课程设计说明书+CAD图纸+Creo三维】

正铲单斗液压挖掘机工作装置是土方工程中的核心执行部件&#xff0c;其设计质量直接影响挖掘效率、作业稳定性及设备寿命。该装置主要由动臂、斗杆、铲斗及液压缸等关键零件构成&#xff0c;通过液压系统驱动实现挖掘、提升、卸料等动作。设计过程中需重点考虑力学性能优化、结…...

awk实战:从基础语法到高效文本处理技巧

1. 为什么你应该掌握awk文本处理 第一次接触awk是在处理服务器日志的时候&#xff0c;当时我需要从几GB的访问日志中统计每个IP的出现次数。同事随手写了个awk命令&#xff0c;一行代码就解决了让我头疼半天的问题。从那时起&#xff0c;我就把这个"文本处理瑞士军刀&quo…...

计算机网络传输优化LingBot-Depth实时数据的方案

计算机网络传输优化LingBot-Depth实时数据的方案 1. 引言 想象一下&#xff0c;你正在使用LingBot-Depth处理实时深度数据&#xff0c;突然间网络开始卡顿&#xff0c;关键帧丢失&#xff0c;整个系统就像在泥沼中挣扎。这不是科幻场景&#xff0c;而是许多开发者在处理大规模…...

网页时光机:如何用浏览器扩展拯救消失的互联网记忆

网页时光机&#xff1a;如何用浏览器扩展拯救消失的互联网记忆 【免费下载链接】wayback-machine-webextension A web browser extension for Chrome, Firefox, Edge, and Safari 14. 项目地址: https://gitcode.com/gh_mirrors/wa/wayback-machine-webextension 当你精…...

从海报生成实战出发:深度解析Canvas文本绘制的那些“坑”与高效解决方案

从海报生成实战出发&#xff1a;深度解析Canvas文本绘制的那些“坑”与高效解决方案 在数字化营销盛行的今天&#xff0c;一张精美的海报往往能成为内容传播的"门面担当"。无论是文章分享、活动推广还是品牌展示&#xff0c;视觉化呈现的效果直接影响用户点击意愿。…...