Spring-GPT智谱清言AI项目(附源码)

news/2025/2/21 8:44:40/
aidu_pl">

一、项目介绍

本项目是Spring AI第三方调用整合智谱请言(官网是:https://open.bigmodel.cn)的案例,回答响应流式输出显示,这里使用的是免费模型,需要其他模型可以去 https://www.bigmodel.cn/pricing 切换。

在这里主要是完整地描述前后端开发和第三方调用的过程,SSE流式请求响应,MD稳定渲染显示等。

二、后端开发

后端使用的是Java,版本是JDK17,spring-boot版本是3.0.2,下面是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 https://maven.apache.org/xsd/maven-4.0.0.xsd"><modelVersion>4.0.0</modelVersion><groupId>com</groupId><artifactId>spring-gpt-service</artifactId><version>0.0.9</version><name>spring-gpt-service</name><description>spring-gpt-service</description><!-- 版本信息 --><properties><java.version>17</java.version><project.build.sourceEncoding>UTF-8</project.build.sourceEncoding><project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding><spring-boot.version>3.0.2</spring-boot.version></properties><!-- 依赖 --><dependencies><!-- web --><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-web</artifactId></dependency><!-- lombok --><dependency><groupId>org.projectlombok</groupId><artifactId>lombok</artifactId><optional>true</optional></dependency><!-- test --><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-test</artifactId><scope>test</scope></dependency><!-- oapi --><dependency><groupId>cn.bigmodel.openapi</groupId><artifactId>oapi-java-sdk</artifactId><version>release-V4-2.3.0</version></dependency><!-- okhttp --><dependency><groupId>com.squareup.okhttp3</groupId><artifactId>okhttp</artifactId><version>4.9.3</version></dependency><!-- gson --><dependency><groupId>com.google.code.gson</groupId><artifactId>gson</artifactId><version>2.8.8</version></dependency><dependency><groupId>com.alibaba</groupId><artifactId>fastjson</artifactId><version>1.2.75</version></dependency><!-- flux --><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-webflux</artifactId></dependency></dependencies><dependencyManagement><dependencies><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-dependencies</artifactId><version>${spring-boot.version}</version><type>pom</type><scope>import</scope></dependency></dependencies></dependencyManagement><build><plugins><!--打包jar插件配置--><plugin><groupId>org.apache.maven.plugins</groupId><artifactId>maven-compiler-plugin</artifactId><version>3.8.1</version><configuration><source>17</source><target>17</target><encoding>UTF-8</encoding></configuration></plugin><plugin><groupId>org.springframework.boot</groupId><artifactId>spring-boot-maven-plugin</artifactId><version>${spring-boot.version}</version><executions><execution><goals><goal>repackage</goal></goals></execution></executions></plugin></plugins></build></project>

 

​​​​​​​由于Get请求参数直接在链接上会受到换行符\n或\r的限制,改用Post请求,使用json封装请求参数,下面是RequestData类:

java language-md-end-block">import lombok.Data;@Data
public class RequestData {private String msg;
}

接口层accumulator.getDelta().getContent()这句代码是返回每次的具体结果

java language-md-end-block"> /*** 通过ModelApiResponse.getFlowable()获取流式数据,最后通过blockingGet()获取最终结果* System.out.print(accumulator.getDelta().getContent());  // 这句代码是返回的具体结果* 因为直接SSE传text,受结束符\n影响,可以使用base64传输*/ 
@PostMapping(value = "/zp2", produces = MediaType.TEXT_EVENT_STREAM_VALUE)public Flux<String> testSseInvoke(@RequestBody RequestData requestData) {String msg = requestData.getMsg();List<ChatMessage> messages = new ArrayList<>();ChatMessage chatMessage = new ChatMessage(ChatMessageRole.USER.value(), msg);messages.add(chatMessage);String requestId = String.format(requestIdTemplate, System.currentTimeMillis());ChatCompletionRequest chatCompletionRequest = ChatCompletionRequest.builder().model(Constants.ModelChatGLM4).stream(Boolean.TRUE).messages(messages).requestId(requestId).build();Flux<String> flux = Flux.create(emitter -> {ModelApiResponse sseModelApiResp = client.invokeModelApi(chatCompletionRequest);if (sseModelApiResp.isSuccess()) {AtomicBoolean isFirst = new AtomicBoolean(true);mapStreamToAccumulator(sseModelApiResp.getFlowable()).doOnNext(accumulator -> {
//                            if (isFirst.getAndSet(false)) {
//                                String base64Msg = Base64.getEncoder().encodeToString("Response: ".getBytes(StandardCharsets.UTF_8));
//                                emitter.next(base64Msg);
//                            }if (accumulator.getDelta() != null && accumulator.getDelta().getTool_calls() != null) {try {String jsonString = mapper.writeValueAsString(accumulator.getDelta().getTool_calls());String tool = "tool_calls: " + jsonString;String base64Msg = Base64.getEncoder().encodeToString(tool.getBytes(StandardCharsets.UTF_8));emitter.next(base64Msg);} catch (Exception e) {String err = "Error converting tool_calls to JSON: " + e.getMessage();String base64Msg = Base64.getEncoder().encodeToString(err.getBytes(StandardCharsets.UTF_8));emitter.next(base64Msg);}}if (accumulator.getDelta() != null && accumulator.getDelta().getContent() != null) {String content = accumulator.getDelta().getContent();String base64Msg = Base64.getEncoder().encodeToString(content.getBytes(StandardCharsets.UTF_8));// 具体结果// System.out.print(content);emitter.next(base64Msg);}}).doOnComplete(() -> {emitter.next("\n");emitter.complete();}).subscribe();} else {emitter.next("Error: " + sseModelApiResp.getError() + "\n");emitter.complete();}});return flux;}

三、前端实现

前端使用Vue3,具体其他库详见项目的package.json文件

java language-md-end-block">pnpm create vue@latest

其中使用md-editor-v3来做MD文档格式显示

java language-md-end-block"> pnpm add md-editor-v3

下面是在组件中的具体使用:

<script lang="ts" setup>
import { MdPreview } from 'md-editor-v3';
import 'md-editor-v3/lib/preview.css';
</script><LayoutContent class="content"><!-- 聊天列表 --><ul class="chat-list" ref="messageListRef"><li class="chat-item" :class="`chat-item--${msg.role}`" v-for="msg in chatMessages"><MdPreview style="padding: 0; background-color: transparent;" type="String" :model-value="msg.content"/></li><li class="chat-item chat-item--system" :class="{ hidden: !isLoading }"><MdPreview :model-value="messagePlaceholder"/><Spin/></li></ul>
</LayoutContent>

四、源码仓库

=======================================================================

联系开发者:2013994940@qq.com

Gitee源码地址:https://gitee.com/BuLiangShuai01033/spring-gpt

=======================================================================


http://www.ppmy.cn/news/1573389.html

相关文章

Linux配置SSH公钥认证与Jenkins远程登录进行自动发布

问题描述&#xff1a;在使用jenkins进行自动化部署时&#xff0c;其中一步是使用jenkins向目标服务器推送文件时&#xff0c;需要先在jenkins的系统配置中进行配置&#xff08;事先安装好对应插件&#xff09;&#xff0c;配置远程服务器时&#xff0c;报错&#xff1a; 检查以…

Linux 教程合集

Linux 简介 Linux是一种自由和开放源代码的操作系统,最初由芬兰程序员Linus Torvalds于1991年创造并发布。Linux操作系统是基于UNIX的设计理念和原则,是一个强大、稳定且可定制的操作系统。 Linux操作系统的核心组件是Linux内核,它是操作系统的核心部分,负责管理计算机硬…

DeepSeek教unity------UI框架

/****************************************************文件&#xff1a;BasePanel.cs作者&#xff1a;Edision日期&#xff1a;#CreateTime#功能&#xff1a;面板基类 *****************************************************/using UnityEngine;public class BasePanel : Mo…

AI提示词进阶:RTGO与CO-STAR框架实战指南

掌握提示词设计是解锁AI生产力的关键。本文将深入解析两大顶尖框架RTGO与CO-STAR&#xff0c;通过程序员视角拆解技术原理&#xff0c;配合真实案例演示如何根据场景精准选型。 一、框架定位与技术特性对比 维度RTGO框架CO-STAR框架架构四层递进式结构六维网状结构响应速度0.8…

mysql查询判断函数,类似decode

mysql中没有decode函数&#xff0c;如果使用的话&#xff0c;会报如下错误&#xff1a;Error Code: 1305. FUNCTION stockdb.decode does not exist 如果要实现像 Oracle 数据库那样原生的 DECODE 函数&#xff0c;可以通过以下几种方式来实现类似 DECODE 函数的功能。 -- 创建…

计算机毕业设计Tensorflow+LSTM空气质量监测及预测系统 天气预测系统 Spark Hadoop 深度学习 机器学习 人工智能

温馨提示&#xff1a;文末有 CSDN 平台官方提供的学长联系方式的名片&#xff01; 温馨提示&#xff1a;文末有 CSDN 平台官方提供的学长联系方式的名片&#xff01; 温馨提示&#xff1a;文末有 CSDN 平台官方提供的学长联系方式的名片&#xff01; 作者简介&#xff1a;Java领…

cs*n 网页内容转为html 加入 onenote

csdn上有好用的内容&#xff0c;我们怎么将它们加到 onenote 里吃灰呢。 一、创建 新html create_html.py import sysdef create_html_file(filename):# 检查是否提供了文件名if not filename:print("请提供HTML文件名")return# 创建HTML内容html_content f"…

Python 日志记录全解析:从入门到进阶的实用指南

本文全面深入地介绍了 Python 的日志记录功能&#xff0c;从基础概念、何时使用日志&#xff0c;到如何进行基础日志操作&#xff08;如记录到文件、记录变量数据、更改消息格式等&#xff09;&#xff0c;再到进阶的日志组件&#xff08;记录器、处理器、过滤器和格式器&#…