Spring AI实战之一:快速体验(OpenAI)

欢迎访问我的GitHub

这里分类和汇总了欣宸的全部原创(含配套源码):https://github.com/zq2599/blog_demos

关于Spring AI

  • Spring Boot、Spring Cloud、Spring Data,作为一名Java程序员,相信您对这些概览早已耳熟能详,或者天天在用,在Spring体系中,它们都被称为project,而本系列的核心Spring AI,也是个project,和 Spring Boot、Spring Cloud属于同一级别的存在,其定位是面向人工智能的应用框架
    在这里插入图片描述

  • Spring AI有以下特点:

  1. 在AI的聊天、文生图、嵌入模型等方面提供API级别的支持
  2. 与模型之间支持同步式和流式交互(还记得ChatGPT返回内容时,是逐字生成的吗,这就是流式交互的效果)
  3. 多种模型支持

关于《SpringAI实战》系列

  • 这是欣宸作为一名Java程序员在LLM应用领域的原创,目标是与广大Java爱好者共同学习和进步,以编码实战的方式逐渐熟悉如何将AI应用在工程中,去实现业务功能

环境信息

  • 首先是JDK版本,整个实战系列使用了JDK17,您也可以考虑使用更高版本
  • maven版本是3.8.6
  • SpringBoot版本是3.2.4
  • Spring AI版本是0.8.1,这是目前最新的稳定版
    在这里插入图片描述
  • 另外就是开发环境,我的本地电脑上并未安装java、maven这些开发工具,而是通过GitHub提供的codespace功能,直接在浏览器上用web版的vscode实现了开发和运行的全部过程,自己的电脑只要有浏览器就行,无所谓windows还是mac,安卓平板一样能用

本篇概览

  • 作为《SpringAI实战》系列的开篇,本文打算以最快的速度写一个demo并且运行成功,通过这种方法对LLM有个初步的认识
  • 这个demo的功能是使用SpringAI提供的openai的starter,来实现对OpenAI接口的调用,得益于Spring框架的良好设计,使整个开发过程也非常简单
  • 如果您对OpenAI有所了解,就应该质疑本篇实战的内容:OpenAI的服务就是http接口调用,所以本篇实战不就是调用了http接口吗?这也太水了吧
  • 您说的没错,本质上就是写代码进行http调用,但具体的实现方式并不是写http请求和响应的代码,而是使用了SpringAI中和OpenAI相关的API和配置,在《SpringAI实战》系列的后续中,还会使用SpringAI去调用更多的大模型服务,它们并非全部都像OpenAI那样提供http接口,有的甚至是本地部署,这时候,SpringAI的优势就体现出来了:以一致的统一的风格使用各类LLM的能力

准备工作

  • 实际上,要想使用OpenAI的服务还是有一定难度的,例如账号里要有钱,对应的API Key才能使用,否则收到的响应就是失败信息
  • 如果只是学习用途,也能在网上发现一些免费使用ChatGPT的方法,本篇用的是这个项目提供的免费服务:https://gitcode.com/chatanywhere/GPT_API_free,真心感谢项目作者为我们的学习提供的宝贵帮助
  • 上述项目可以为你提供访问OpenAI的地址和API Key,前提是你要有个GitHub账号,具体操作如下
    在这里插入图片描述

源码下载

  • 准备工作完成,接下来开始编码,如果您不想写代码,也可以从GitHub下载代码直接运行,地址和链接信息如下表所示(https://github.com/zq2599/blog_demos):
名称链接备注
项目主页https://github.com/zq2599/blog_demos该项目在GitHub上的主页
git仓库地址(https)https://github.com/zq2599/blog_demos.git该项目源码的仓库地址,https协议
git仓库地址(ssh)git@github.com:zq2599/blog_demos.git该项目源码的仓库地址,ssh协议
  • 这个git项目中有多个文件夹,本篇的源码在leader-tutorials文件夹下,如下图红色箭头所示:
    在这里插入图片描述
  • tutorials目录下有多个项目,整个《SpringAI实战》系列的源码在springai-tutorials,这是个maven工程,里面有多个子工程,今天的实战就是子工程hello-openai

编码:《SpringAI实战》系列的父工程

  • 首先是创建一个maven工程,这是《SpringAI实战》系列的父工程,作用是方便对所有实战源码的管理,另外对依赖库的版本管理也可以在这里统一处理,pom.xml内容如下
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"><modelVersion>4.0.0</modelVersion><modules><module>hello-openai</module></modules><parent><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-parent</artifactId><version>3.2.4</version><relativePath/> <!-- lookup parent from repository --></parent><groupId>com.bolingcavalry</groupId><artifactId>springai-tutorials</artifactId><version>1.0-SNAPSHOT</version><name>springai-tutorials</name><description>Simple AI Application demos</description><packaging>pom</packaging><properties><java.version>17</java.version><maven.compiler.source>17</maven.compiler.source><maven.compiler.target>17</maven.compiler.target></properties><dependencyManagement><dependencies><dependency><groupId>org.springframework.ai</groupId><artifactId>spring-ai-bom</artifactId><version>0.8.1</version><type>pom</type><scope>import</scope></dependency></dependencies></dependencyManagement><repositories><repository><id>spring-milestones</id><name>Spring Milestones</name><url>https://repo.spring.io/milestone</url><snapshots><enabled>false</enabled></snapshots></repository><repository><id>spring-snapshots</id><name>Spring Snapshots</name><url>https://repo.spring.io/snapshot</url><releases><enabled>false</enabled></releases></repository></repositories>
</project>
  • 这个父工程只有这么一个pom.xml文件

编码:快速体验SpringAI的子工程hello-openai

  • 接下来的内容就是今天的核心:使用SpringAI来调用
  • 在父工程里面创建名为hello-openai的子工程,pom.xml如下,这里面最重要的就是spring-ai-openai-spring-boot-starter这个包的依赖,它给我们带来了
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"><parent><artifactId>springai-tutorials</artifactId><groupId>com.bolingcavalry</groupId><version>1.0-SNAPSHOT</version></parent><modelVersion>4.0.0</modelVersion><artifactId>hello-openai</artifactId><dependencies><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-web</artifactId></dependency><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-actuator</artifactId></dependency><dependency><groupId>org.springframework.ai</groupId><artifactId>spring-ai-openai-spring-boot-starter</artifactId></dependency><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-test</artifactId><scope>test</scope></dependency></dependencies><build><plugins><plugin><groupId>org.springframework.boot</groupId><artifactId>spring-boot-maven-plugin</artifactId></plugin></plugins></build></project>
  • 通过命令看一下这个starter的依赖情况,看起来spring-ai-core是关键(后面会有专门的文章讲述),其他的都是工具性质的依赖
[INFO] |  \- org.springframework.ai:spring-ai-openai:jar:0.8.1:compile
[INFO] |     +- org.springframework.ai:spring-ai-core:jar:0.8.1:compile
[INFO] |     |  +- io.swagger.core.v3:swagger-annotations:jar:2.2.20:compile
[INFO] |     |  +- com.github.victools:jsonschema-module-swagger-2:jar:4.33.1:compile
[INFO] |     |  +- org.springframework.cloud:spring-cloud-function-context:jar:4.1.0:compile
[INFO] |     |  |  +- net.jodah:typetools:jar:0.6.2:compile
[INFO] |     |  |  \- org.springframework.cloud:spring-cloud-function-core:jar:4.1.0:compile
[INFO] |     |  +- org.antlr:stringtemplate:jar:4.0.2:compile
[INFO] |     |  |  \- org.antlr:antlr-runtime:jar:3.3:compile
[INFO] |     |  +- org.antlr:antlr4-runtime:jar:4.13.1:compile
[INFO] |     |  +- io.projectreactor:reactor-core:jar:3.6.4:compile
[INFO] |     |  |  \- org.reactivestreams:reactive-streams:jar:1.0.4:compile
[INFO] |     |  +- org.springframework:spring-messaging:jar:6.1.5:compile
[INFO] |     |  \- com.knuddels:jtokkit:jar:1.0.0:compile
[INFO] |     +- org.springframework.ai:spring-ai-retry:jar:0.8.1:compile
[INFO] |     |  +- org.springframework.retry:spring-retry:jar:2.0.5:compile
[INFO] |     |  \- org.springframework:spring-webflux:jar:6.1.5:compile
[INFO] |     +- io.rest-assured:json-path:jar:5.3.2:compile
[INFO] |     |  +- org.apache.groovy:groovy-json:jar:4.0.20:compile
[INFO] |     |  +- org.apache.groovy:groovy:jar:4.0.20:compile
[INFO] |     |  \- io.rest-assured:rest-assured-common:jar:5.3.2:compile
[INFO] |     |     \- org.apache.commons:commons-lang3:jar:3.13.0:compile
[INFO] |     +- com.github.victools:jsonschema-generator:jar:4.31.1:compile
[INFO] |     |  \- com.fasterxml:classmate:jar:1.6.0:compile
[INFO] |     +- com.github.victools:jsonschema-module-jackson:jar:4.31.1:compile
[INFO] |     \- org.springframework:spring-context-support:jar:6.1.5:compile
  • 配置文件spring-ai-core,这是hello-openai工程的配置文件,内容如下,您在运行的时候,一定要将sk-xxxxxx改为您自己的API Key:
# 调用OpenAI接口时表明身份的API Key,前面的章节有提到如何生成一个免费的
spring.ai.openai.api-key=sk-xxxxxx
# 调用OpenAI接口时的基础地址,如果用的是chatanywhere的API Key,这里就要用chatanywhere提供的地址,
# 如果用的是OpenAI的原生API Key,就不用配置这个参数
spring.ai.openai.base-url=https://api.chatanywhere.tech
# 用到的模型
spring.ai.openai.chat.options.model=gpt-3.5-turbo
# temperature越小,回答的内容越严谨,temperature越大,回答的内容越有创造性
spring.ai.openai.chat.options.temperature=0.7
  • 一共有两个java文件,第一个是普通的application类,负责启动服务
package com.bolingcavalry.helloopenai;import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;@SpringBootApplication
public class Application {public static void main(String[] args) {SpringApplication.run(Application.class, args);}}
  • 另一个是controller类,收到请求后调用OpenAI的接口,将聊天内容发过去,并将OpenAI响应的内容返回,这也是本文的核心内容,completion方法负责接受post请求,并将请求通过chatClinet发送到OpenAI,而call的返回值就是OpenAI的返回内容
package com.bolingcavalry.helloopenai.controller;import org.springframework.ai.chat.ChatClient;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RestController;import java.util.Map;@RestController
public class SimpleAiController {// 负责处理OpenAI的bean,所需参数来自properties文件private final ChatClient chatClient;public SimpleAiController(ChatClient chatClient) {this.chatClient = chatClient;}@PostMapping("/ai/simple")public Map<String, String> completion(@RequestBody Map<String,String> map) {return Map.of("generation", chatClient.call(map.get("message")));}
}
  • 至此,编码完成,把服务运行起来试试吧

运行验证

  • 启动服务后,执行以下命令即可发送请求调用服务的/ai/simple接口,我这边问了一个三国有关的问题
curl --request POST \--url http://127.0.0.1:8080/ai/simple \--header 'content-type: application/json' \--data '{"message":"你是精通中国历史的专家,请回答:三国时期,魏延的子午谷奇谋是否可行?能在潼关把魏国的援兵堵住吗?如果魏国援兵走武关进入,整个计划是否还有意义?"
}'
  • 稍等数秒,控制台就会显示返回内容,这就是OpenAI服务返回的内容了
{"generation":"作为专家,我可以告诉你,魏延的子午谷奇谋在理论上是可行的。子午谷是一个地势险要的地方,如果能够在那里设下埋伏,堵住魏国的援兵是有可能的。但是,这需要充分的准备和合理的部署,同时也需要对魏国援兵的行动有准确的情报。\n\n如果魏国援兵走武关进入,整个计划的意义可能会有所减弱。因为子午谷的奇谋是建立在堵住潼关的前提下,如果援兵绕道武关进入,那么计划的效果可能会受到影响。在这种情况下,需要及时调整计划,采取其他措施来应对敌人的行动。\n\n总的来说,魏延的子午谷奇谋在三国时期是一个具有一定可行性的战术计划,但是在实际执行过程中需要根据敌军的行动及时调整和变通。"}
  • 至此,本篇实战已经完成,第一次使用SpringAI,似乎…没啥感觉,无非是几个配置,一个client bean,整个过程和接入数据库、消息服务一样简单,但是这样也挺好,可以让咱们的注意力集中到对LLM的使用上
  • 接下来的章节,会有更多实战陪大家,一起投入大精彩纷呈的大模型时代,感谢Spring,这一次咱们不掉队

你不孤单,欣宸原创一路相伴

  1. Java系列
  2. Spring系列
  3. Docker系列
  4. kubernetes系列
  5. 数据库+中间件系列
  6. DevOps系列

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/834227.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

Django中如何让页面之间建立关系

今天给大家讲解两种让页面建立联系的方式 一、重定向 二、表单提交 先看第一种方式&#xff0c;重定向 首先需要了解客户端发起请求的过程 1、客户端向服务端发起请求,比如请求地址是&#xff1a;http://127.0.0.1:8000/lili/submit/ 2、程序根据路由找到视图函数 3、执行视…

sqlserver中替换空格和换行

sqlserver 中换行符&#xff0c;如下&#xff1a; sql语句如下&#xff08;只是在window系统中&#xff09;&#xff1a; //替换换行-使用char(10)或者char(13) select REPLACE(F_CNKITitle ,char(10),) title from tzkj_CNKIContent tc where --F_CnkiContentID ffdc7412-41…

AI智剪新风尚:一键操作,批量视频剪辑轻松入门

随着科技的飞速进步&#xff0c;人工智能(AI)已逐渐渗透到我们生活的各个领域&#xff0c;其中&#xff0c;AI视频剪辑技术的出现&#xff0c;为视频制作带来了革命性的变革。如今&#xff0c;一键操作、批量处理的AI智剪正成为视频剪辑的新风尚&#xff0c;让剪辑工作变得前所…

Mysql进阶-索引篇

Mysql进阶 存储引擎前言特点对比 索引介绍常见的索引结构索引分类索引语法sql分析索引使用原则索引失效的几种情况sql提示覆盖索引前缀索引索引设计原则 存储引擎 前言 Mysql的体系结构&#xff1a; 连接层 最上层是一些客户端和链接服务&#xff0c;主要完成一些类似于连接…

访问网络附加存储:nfs

文章目录 访问网络附加存储一、网络附加存储1.1、存储类型1.3、通过NFS挂载NAS1.4、NFS挂载过程服务端客户端 二、实验&#xff1a;搭建NFS服务端及挂载到nfs客户端服务端客户端测试命令合集服务端客户端 访问网络附加存储 一、网络附加存储 1.1、存储类型 DAS&#xff1a;Di…

零代码编程:用Kimichat从PDF文件中批量提取图片

一个PDF文件中&#xff0c;有很多图片&#xff0c;想批量提取出来&#xff0c;可以借助kimi智能助手。 在借助kimi智能助手中输入提示词&#xff1a; 你是一个Python编程专家&#xff0c;要完成一个网页爬取Python脚本的任务&#xff0c;具体步骤如下&#xff1a; 打开文件夹…

2024年融资融券利率最新变化,又降低了?

最近有很多朋友在问我问融资融券的业务&#xff0c;都是比较关心这个利率的问题。确实&#xff0c;做融资融券最重要的利率&#xff0c;利率低会节省很大一笔资金&#xff0c;今天在这边给大家对接一个上市券商&#xff0c;可以给到大家万一的交易佣金和5%的融资利率&#xff0…

乡村振兴规划设计一站式资料大全,能为乡村振兴从业者带来什么帮助?

乡村振兴规划设计一站式资料大全对于乡村振兴从业者来说&#xff0c;具有非常重要的帮助作用。这种资料大全通常包含了从政策解读、市场分析、规划设计、到实施策略等各个方面的详尽信息&#xff0c;能够极大地提升从业者的工作效率和专业能力。 具体来说&#xff0c;乡村振兴规…

Python selenium

1.搭建环境 1.安装&#xff1a; pip install msedge-selenium-tools 不要使用pip install selenium&#xff0c;我的电脑上没法运行 2.下载驱动 Microsoft Edge WebDriver |Microsoft Edge 开发人员 edge浏览器点设置---关于即可找到版本号&#xff0c;一定要下载对应版…

实践精益理念:精益生产培训助力企业持续增长

在日益激烈的市场竞争中&#xff0c;企业如何寻找持续增长的动力&#xff0c;提升整体创新能力和核心竞争力&#xff1f;张驰咨询通过多年来的深入研究和实践&#xff0c;结合众多企业的实际情况&#xff0c;带来了精益生产培训的全新视角。 在近期举办的一次精益生产培训中&am…

五种算法(BWO、RUN、SO、HO、GWO)求解复杂城市地形下无人机路径规划,可以修改障碍物及起始点(MATLAB)

一、算法介绍 &#xff08;1&#xff09;白鲸优化算法BWO 参考文献&#xff1a;Zhong C, Li G, Meng Z. Beluga whale optimization: A novel nature-inspired metaheuristic algorithm[J]. Knowledge-Based Systems, 2022, 109215. &#xff08;2&#xff09;龙格-库塔优化…

服务器数据恢复—RAID5磁盘阵列两块盘离线的数据恢复过程

服务器故障&#xff1a; 服务器中有一组由多块硬盘组建的raid5磁盘阵列&#xff0c;服务器阵列中2块硬盘先后掉线导致服务器崩溃。 服务器数据恢复过程&#xff1a; 1、将故障服务器中所有磁盘编号后取出&#xff0c;由硬件工程师对掉线的两块磁盘进行物理故障检测&#xff0c…

二层交换机与路由器连通上网实验

华为二层交换机与路由器连通上网实验 二层交换机是一种网络设备&#xff0c;用于在局域网&#xff08;LAN&#xff09;中转发数据帧。它工作在OSI模型的第二层&#xff0c;即数据链路层。二层交换机通过学习和维护MAC地址表&#xff0c;实现了数据的快速转发和广播域的隔离。 实…

java数据结构之数组系统了解

1.数组介绍 数组就是一个存储数据的容器&#xff0c;容器的长度固定、存储元素的数据类型固定。 跟变量加以区分&#xff1a;变量也可以存储数据&#xff0c;但是只能存一个值。当要存的数据比较多的时候&#xff0c;用变量就不方便了。我们就可以使用数组来存储。 1.1数组…

并发编程实现

一、并行编程 1、Parallel 类 Parallel类是System.Threading.Tasks命名空间中的一个重要类&#xff0c;它提供数据并行和任务并行的高级抽象。 For和ForEach Parallel类下的For和ForEach对应着普通的循环和遍历(普通的for和foreach)&#xff0c;但执行时会尝试在多个线程上…

安防视频/视频汇聚系统EasyCVR视频融合云平台助力智能化酒店安防体系的搭建

一、背景需求 2024年“五一”假期&#xff0c;全国文化和旅游市场总体平稳有序。文化和旅游部6日发布数据显示&#xff0c;据文化和旅游部数据中心测算&#xff0c;全国国内旅游出游合计2.95亿人次。“五一”假期县域市场酒店预订订单同比增长68%&#xff0c;而酒店作为一个高…

SpringCloudAlibaba:4.3云原生网关higress的JWT 认证

概述 简介 JWT是一种用于双方之间传递安全信息的简洁的、URL安全的声明规范。 定义了一种简洁的&#xff0c;自包含的方法用于通信双方之间以Json对象的形式安全的传递信息&#xff0c;特别适用于分布式站点的单点登录&#xff08;SSO&#xff09;场景 session认证的缺点 1.安…

简单数据结构——栈和队列1(栈超全)(初始化,销毁,出栈入栈销毁实现,例题运用)

知识特点 类似数据表链表&#xff0c;在逻辑上依次存储&#xff0c;但对比顺序表和链表有所限制&#xff0c;不能随便存储 一定要先掌握顺序表的实现&#xff0c;本人博客有顺序表专栏大家可以自行查看&#xff0c;看懂顺序表专栏之后再来了解栈的实现会更容易懂。 如果还没…

使用DBeaver连接postgreSql提示缺少驱动

重新安装电脑之后用dbeaver链接数据库的时候&#xff0c;链接PG库一直提示缺少驱动&#xff0c;当选择下载驱动的时候又非常非常慢经常失败&#xff0c;尝试了一下更改源然后下载库驱动就非常快了&#xff0c;当然也包括dbeaver的自动更新。 方法&#xff1a;点击菜单栏【窗口…

闲来装个虚拟机Ubuntu24.04和硬盘分区及挂载

简述 最近ubuntu出新版本了&#xff0c;ubuntu24.04&#xff0c; 俗称高贵食蚁兽。5年前进行Android或者linux开发基本是在windows下的虚拟机中进行。目前&#xff0c;虽然物质基础提高了&#xff0c;功能有独立进行编译、代码管理的服务器了。可以通过ssh登录&#xff0c;但是…