Java SpringBoot调用大模型AI构建AI应用

本文是一个用springboot 结合spring mvc 和spring ai alibaba 调用国产大模型通义千问的具体例子,按照这个做能够快速的搞定Java应用的调用。

然后就可以把这类应用泛化到所有的涉及到非结构化数据结构化的场景中。

Spring AI:简化Java中大模型调用的框架

当前,在Java springboot 中调用大模型时,缺乏优秀的AI应用框架是一个常见问题。

作为老牌的Java应用框架提供商,Spring 在springboot之外提出了解决方案—Spring AI,它借鉴了langchain的核心理念,并结合了Java面向对象编程的特点。

Spring AI最核心的优势在于提供了统一接口,使得开发者能够编写一次代码后仅通过更改配置即可轻松切换不同的AI实现。

此外,得益于专门团队的支持与维护,Spring AI保证了稳定性和持续更新。以本次样例中的Spring AI Alibaba接入阿里云通义大模型为例,用户在完成初步集成后,同样可以方便地更换为自己所需的其他大模型实现。

这种设计极大简化了开发流程,提高了效率,让Java开发者能更专注于业务逻辑本身而非复杂的AI集成工作。

Spring AI Alibaba功能介绍及应用示例

Spring AI Alibaba是Spring AI的一个实现,它基于Spring AI的API完成了阿里云百炼系列云产品的大模型接入。

与Spring Cloud Alibaba一样,Spring AI Alibaba整合了阿里巴巴的最佳实践,是国内最好的Spring AI实现之一。

Spring AI Alibaba提供了一系列强大的功能和能力,包括但不限于模型调用、Prompt模板、RAG(检索增强生成)、文生图以及图像识别等。

通过使用Spring AI Alibaba,开发者可以轻松地开发基于阿里云通义提供的聊天、图片或语音生成AI应用。

框架还提供了诸如OutputParser、Prompt Template、Stuff等实用工具,帮助简化开发流程。本文将以Prompt模板和模型调用两个能力为例,展示如何接入Spring AI Alibaba,以便为项目增添更多AI功能。

通义千问Qwen在MMLU等测试中超越Llama 3 70B,登顶Hugging Face开源模型榜

通义千问Qwen在MMLU、TheoremQA、GPQA等基准测评中表现出色,超越了Llama 3 70B ,在85+分数,与gpt和claude等同属 第一梯队 ,并在Hugging Face开源大模型排行榜Open LLM Leaderboard上荣登榜首。

MMLU 和 GPQA都是 目前客观评分中最公认的两个评测标准,客观评分来说这俩是最好的。

另外,在真人参与评测的arena里面,它不仅在思南平台 上仅次于国际知名的GPT和Claude系列,还在 Hugging Face的视觉模型竞技场 中稳居中国首位。

基于SpringBoot集成Spring AI Alibaba构建对话模型

为了基于SpringBoot集成Spring AI Alibaba完成一个简单的对话模型,并构建一个支持prompt的流返回接口的项目,我们需要按照以下步骤进行操作。首先,确保您的环境满足前置条件,然后通过阿里云申请必要的API Key,接着在项目中添加相应的依赖和配置,最后实现Controller层逻辑以提供所需功能。

前置要求

  • 确保您的JDK版本不低于17。
  • 使用Spring Boot 3.3.x或以上版本。
  • 已经从阿里云申请到了通义千问(Qwen)的API Key。

步骤一:获取并配置API Key

  1. 登录阿里云百炼页面,开通“百炼大模型推理”服务。
  1. 创建新的API Key并记录下来。
  1. 将API Key作为环境变量导出:
export AI_DASHSCOPE_API_KEY=这里替换为你的实际API Key
  1. application.properties文件中设置API Key:
spring.ai.dashscope.api-key=${AI_DASHSCOPE_API_KEY}

步骤二:添加Spring仓库及项目依赖

由于Spring AI Alibaba目前尚未发布到Maven中央仓库,您需要手动添加Spring的仓库配置来获取相关依赖。请在pom.xml文件中的<repositories>标签下加入以下内容:

<repositories><repository><id>sonatype-snapshots</id><url>https://oss.sonatype.org/content/repositories/snapshots</url><snapshots><enabled>true</enabled></snapshots></repository><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>

接着,在<dependencies>部分增加对spring-ai-alibaba-starter的引用:

<dependencies><!-- 其他已存在的依赖项 --><dependency><groupId>com.alibaba.cloud.ai</groupId><artifactId>spring-ai-alibaba-starter</artifactId><version>1.0.0-M2</version></dependency><!-- Spring Boot Starter Web 用于HTTP请求处理 --><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-web</artifactId></dependency><!-- Spring Boot Starter Test 测试库 --><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-test</artifactId><scope>test</scope></dependency></dependencies>

步骤三:创建Chat Controller

在您的Spring Boot应用中,创建一个新的Controller类,该类将负责处理来自客户端的GET请求,利用ChatClient实例发送prompt给AI模型,并返回一个Flux<String>类型的响应。这允许数据以流的形式异步地发送回客户端。

下面是一个示例代码:

@RestController
@RequestMapping("/ai")
@CrossOrigin(origins = "*")  // 启用CORS跨域支持
public class ChatController {private final ChatClient chatClient;public ChatController(ChatClient.Builder builder) {this.chatClient = builder.build();}@GetMapping("/steamChat")public Flux<String> steamChat(@RequestParam String input) {return this.chatClient.prompt().user(input).stream().content();}
}

解释

  • @RestController注解表明这是一个RESTful风格的控制器。
  • @RequestMapping("/ai")定义了所有映射到此类的方法都将使用/ai作为其URL路径前缀。
  • @CrossOrigin(origins = "*")启用跨源资源共享(CORS),允许任何源访问此端点。
  • ChatController构造函数接收一个ChatClient.Builder实例,用来初始化ChatClient
  • @GetMapping("/steamChat")指定了一个GET请求映射至/steamChat路径,并接受名为input的查询参数。
  • 方法steamChat利用chatClient向AI发送用户提供的文本(即input),并通过stream()方法以Flux<String>形式输出AI生成的内容流。

这样,我们就成功搭建了一个基于Spring Boot的应用程序,它能够与阿里云通义千问大模型交互,并通过HTTP GET请求提供一个支持prompt能力的聊天接口。当用户访问http://localhost:8080/ai/steamChat?input=…时,他们将收到由AI模型生成的回答流。

创建React前端应用以支持流式数据输出

构建前端

要基于React构建一个支持流式数据输出的简单项目,你可以按照以下步骤进行。此项目将能够从前端向后端发送消息,并实时显示从后端接收的流式响应。这里假设你的后端已经准备好了一个URL地址http://localhost:8080/ai/steamChat?input=...用于处理请求并返回flux<String>格式的数据。

创建新的React应用

首先,你需要创建一个新的React应用并通过npm安装必要的依赖包。打开终端,运行以下命令:

npx create-react-app frontend
cd frontend
npm install

这将为你设置好一个基础的React项目结构。

修改基本文件配置

接下来,我们只需要对默认生成的一些文件做少量修改或添加自定义组件来实现我们的功能需求。

public/index.html

确保该文件内容如下,它定义了HTML文档的基本结构:

<!DOCTYPE html>
<html lang="en">
<head><meta charset="UTF-8"><meta name="viewport" content="width=device-width, initial-scale=1.0"><title>Stream Chat App</title></head><body><div id="root"></div></body></html>

src/index.js

保持默认即可,这是React应用的入口点:

import React from 'react';
import ReactDOM from 'react-dom';
import App from './App';ReactDOM.render(<React.StrictMode><App /></React.StrictMode>,document.getElementById('root')
);

src/App.js

在这个文件中,我们将导入并渲染ChatComponent组件,它是实际负责与用户交互的部分:

import React from 'react';
import ChatComponent from './components/ChatComponent';function App() {return (<div className="App"><ChatComponent /></div>);
}export default App;

src/components/ChatComponent.js

这是最关键的部分,在这里实现了输入框、发送按钮以及用来展示来自服务器的消息流的功能。请注意替换其中的URL以匹配你实际使用的后端服务地址:

import React, { useState } from 'react';function ChatComponent() {const [input, setInput] = useState('');const [messages, setMessages] = useState('');const handleInputChange = (event) => {setInput(event.target.value);};const handleSendMessage = async () => {try {const response = await fetch(`http://localhost:8080/ai/steamChat?input=${input}`);const reader = response.body.getReader();const decoder = new TextDecoder('utf-8');let done = false;while (!done) {const { value, done: readerDone } = await reader.read();done = readerDone;const chunk = decoder.decode(value, { stream: true });setMessages((prevMessages) => prevMessages + chunk);}// 在每次请求完成后添加换行符setMessages((prevMessages) => prevMessages + '\n\n=============================\n\n');} catch (error) {console.error('Failed to fetch', error);}};const handleClearMessages = () => {setMessages('');};return (<div><inputtype="text"value={input}onChange={handleInputChange}placeholder="Enter your message"/><button onClick={handleSendMessage}>Send</button><button onClick={handleClearMessages}>Clear</button><div><h3>Messages:</h3><pre>{messages}</pre></div></div>);
}export default ChatComponent;

以上代码片段提供了一个完整的聊天界面示例,用户可以输入文本然后点击“Send”按钮发送给服务器。收到的流式响应会被逐段追加到页面上显示出来。

启动应用程序

完成所有这些设置之后,现在可以启动你的React应用了。在项目根目录下执行:

npm start

这会开启开发服务器,默认情况下可以在浏览器访问http://localhost:3000查看效果。确保你的后端服务也已正确配置并且处于运行状态,这样前端就可以成功与其通信了。

通过上述步骤,你就建立了一个简单的基于React的支持流式数据传输的应用程序。

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

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

相关文章

【办公类-04-04】华为助手导出照片视频分类(根据图片、视频的文件名日期导入“年-月-日”文件夹中,并转移到“年-月”文件中整理、转移到“年”文件夹中整理)

背景需求 最近带班&#xff0c;没有时间整理照片&#xff0c;偶尔导一次&#xff0c;几个月的照片。发现用电脑版“华为手机助手“中的WLAN连接”与华为手机的“华为手机助手”连接&#xff0c;速度更快、更稳定&#xff0c;不会出现数据线连接时碰碰就断网的问题 1、先打开电…

电脑没有下载声卡驱动怎么办?电脑声卡驱动安装方法

在日常使用电脑的过程中&#xff0c;我们可能会遇到电脑没有声音的问题&#xff0c;这往往与声卡驱动缺失或损坏有关。声卡驱动是连接电脑硬件&#xff08;声卡&#xff09;与操作系统之间的桥梁&#xff0c;确保音频信号能够正常输入输出。那么&#xff0c;当电脑没有声卡驱动…

MYSQL死锁真实案例

​最近例行巡检时候发现一个死锁,阿里云RDS FOR MYSQL 8.0.X! 虽然阿里云的死锁页面看起来比较友好,不过跟社区版一样只是显示事务最后一条死锁SQL和相关的信息.一不小心对初级MYSQL DBA来说,深深地误导,浪费大量时间研究这两个SQL怎么发生了死锁! 阿里云RDS默认情况下审计没有…

CSS3简介(一)

1、CSS3简介 CSS3&#xff08;层叠样式表3级&#xff09;是用于控制网页外观设计的一种样式表语言&#xff0c;它是CSS2的继承者&#xff0c;并且是目前最为先进的版本之一。CSS3为Web设计师提供了更多功能强大的工具来创建更加动态和美观的网站。 以下是一些CSS3的主要特点和新…

【ShuQiHere】探索等差数列:数学中的基础与应用 ✨

【ShuQiHere】 &#x1f4d0;✨ 在数学的广阔领域中&#xff0c;等差数列&#xff08;Arithmetic Sequence&#xff09;是一个基础而重要的概念。无论是在学术研究、工程应用&#xff0c;还是在日常生活中&#xff0c;等差数列都扮演着关键角色。本博客将深入探讨等差数列的定…

【Spring】Spring Boot 日志(8)

本系列共涉及4个框架&#xff1a;Sping,SpringBoot,Spring MVC,Mybatis。 博客涉及框架的重要知识点&#xff0c;根据序号学习即可。 目录 本系列共涉及4个框架&#xff1a;Sping,SpringBoot,Spring MVC,Mybatis。 博客涉及框架的重要知识点&#xff0c;根据序号学习即可。 …

Flink处理乱序的数据的最佳实践

目录 网络延迟和分布式系统 事件时间与处理时间的差异 事件时间和水位线(Watermark) 时间窗口(TimeWindow) 滚动窗口(Tumbling Window) 滑动窗口(Sliding Window) 会话窗口(Session Window) 自定义Watermark生成策略 设置允许延迟和侧输出 设置允许的最大延迟时间 使…

饿了么数据库表设计

有商家表、商品表、商品规格表、购物车表&#xff0c;不难分析出表是不够全面的。 (1)首先分析需要补充的表 1.对于购物车而言肯定有对应的用户&#xff0c;因此要添加一个用户表。 2.商品规格是冷&#xff0c;热&#xff0c;半分糖、全糖&#xff0c;对于冷热和半分糖是可以分…

C02S04-Ubuntu基本使用

一、Ubuntu初始配置 1. 使用root用户 Ubuntu系统默认只能使用普通用户&#xff0c;要想使用root用户&#xff0c;需要先设置root用户密码。 进入终端&#xff0c;配置root用户密码。按照提示输入密码。 sudo passwd root配置完成后&#xff0c;执行下面的密码&#xff0c;切换…

C++模拟实现list

C教学总目录 C模拟实现list 1、成员变量2、迭代器3、insert函数4、erase函数5、pop_back、push_front、pop_front函数6、size和clear函数7、析构函数8、拷贝构造函数9、赋值运算符重载完整代码&#xff08;包含测试代码&#xff09; 1、成员变量 先来看看SGI版本STL中list的实…

【STM32】SD卡

(一)常用卡的认识 在学习这个内容之前&#xff0c;作为生活小白的我对于SD卡、TF卡、SIM卡毫无了解&#xff0c;晕头转向。 SD卡&#xff1a;Secure Digital Card的英文缩写&#xff0c;直译就是“安全数字卡”。一般用于大一些的电子设备比如&#xff1a;电脑、数码相机、AV…

品牌怎么找到用户发的优质内容,进行加热、复制?

在&#xff0c;相对传统媒体来说&#xff0c;社交媒体营销具有更高的成本效益。品牌可以通过相对较低的成本达到大量潜在客户&#xff0c;尤其是通过口碑营销和内容分享&#xff0c;可以实现倍增的传播效果。在社媒营销的过程中&#xff0c;去找到与品牌有关的优质、正向内容&a…

【云原生】云原生后端:案例研究与最佳实践

目录 引言案例一&#xff1a;Netflix的云原生转型1.1 背景1.2 转型过程1.3 成果1.4 经验总结 案例二&#xff1a;Spotify的云原生实践2.1 背景2.2 转型过程2.3 成果2.4 经验总结 案例三&#xff1a;Alibaba的云原生架构3.1 背景3.2 转型过程3.3 成果3.4 经验总结 总结 引言 在…

物联网设备如何助力实现高效远程老人监护

在发达国家&#xff0c;老龄化进程加速&#xff0c;老年人常需医疗、行动辅助、安全保障及个人卫生护理&#xff0c;费用高昂。传统老人监护依赖护士或助理现场照料&#xff0c;而物联网远程监控方案能有效改进此模式。它通过运用传感器等技术&#xff0c;实现全天候低成本实时…

如何使用和打开jconsole

配置: spring.jmx.enabledtrue spring.jmx.default-domainmybatiesdemo management.endpoints.jmx.exposure.include* 启动参数: -Dcom.sun.management.jmxremote.port9000 -Dcom.sun.management.jmxremote.authenticatefalse -Dcom.sun.management.jmxremote.sslfalse 启动项…

残差块(Residual Block)

1. **残差块的定义与作用**&#xff1a; 残差块通过引入跳跃连接&#xff08;skip-connection&#xff09;或称为快捷连接&#xff08;shortcut connection&#xff09;&#xff0c;允许网络学习输入与输出之间的残差映射&#xff0c;即学习函数&#xff0c;其中 是期望的底层映…

Sigrity Power SI VR noise Metrics check模式如何进行电源噪声耦合分析操作指导

SSigrity Power SI VR noise Metrics check模式如何进行电源噪声耦合分析操作指导 Sigrity Power SI的VR noise Metrics check模式本质上是用来评估和观测器件的电源网络的耦合对于信号的影响,输出S参数以及列出具体的贡献值。 以下图为例

讲个故事-HTTP/HTTPS 协议访问逻辑

一、HTTP/HTTPS 协议基本概念 1、协议 HTTP与 HTTPS 协议都是客户端 浏览器和服务器间的一种约定,约定如何将服务器中的信息下载到本地 ,并通过浏览器显示出来。 不同的是, HTTP 协议是一种明文传输协议,其对传输的数据不提供任何加密措施。而HTTPS 协议则是通过 SSL/TL…

javaScript-----一维数组和数组对象去重的多种方法

在JavaScript中&#xff0c;可以使用多种方法对一维数组和数组对象进行去重。以下是一些常见的方法&#xff1a; 一维数组去重 1. 使用 Set Set 只允许唯一值&#xff0c;可以直接用于一维数组的去重。 const arr [1, 2, 3, 1, 2]; const uniqueArr [...new Set(arr)]; c…

生信入门第八课:RNA-seq比对、定量和差异分析

生信入门合集&#xff1a; 生信入门第一课&#xff1a;VirtualBox安装Ubuntu虚拟机 生信入门第二课&#xff1a;RNA-seq生信分析环境搭建-conda及常用软件安装 生信入门第三课&#xff1a;Linux操作系统简介及生信分析常用30个命令 生信入门第四课&#xff1a;生物信息学常…