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

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

一、项目介绍

本项目是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类:

import lombok.Data;@Data
public class RequestData {private String msg;
}

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

 /*** 通过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文件

pnpm create vue@latest

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

 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

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

相关文章:

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

一、项目介绍 本项目是Spring AI第三方调用整合智谱请言&#xff08;官网是&#xff1a;https://open.bigmodel.cn&#xff09;的案例&#xff0c;回答响应流式输出显示&#xff0c;这里使用的是免费模型&#xff0c;需要其他模型可以去 https://www.bigmodel.cn/pricing 切换…...

计算机网络(涵盖OSI,TCP/IP,交换机,路由器,局域网)

一、网络通信基础 &#xff08;一&#xff09;网络通信的概念 网络通信是指终端设备之间通过计算机网络进行的信息传递与交流。它类似于现实生活中的物品传递过程&#xff1a;数据&#xff08;物品&#xff09;被封装成报文&#xff08;包裹&#xff09;&#xff0c;通过网络…...

云计算架构学习之Ansible-playbook实战、Ansible-流程控制、Ansible-字典循环-roles角色

一、Ansible-playbook实战 1.Ansible-playbook安装软件 bash #编写yml [rootansible ansible]# cat wget.yml - hosts: backup tasks: - name: Install wget yum: name: wget state: present #检查playbook的语法 [rootansible ansible]…...

《运维工程师如何利用DeepSeek实现智能运维:分级实战指南》

目录 智能运维革命:DeepSeek带来的范式转变DeepSeek核心运维能力全景解析分级实战场景与解决方案 3.1 初级工程师:自动化运维入门3.2 中级工程师:复杂系统诊断与优化3.3 高级工程师:架构级智能运维典型项目案例深度剖析 4.1 金融系统全链路监控体系构建4.2 电商大促资源弹性…...

windows事件倒计时器与提醒组件

widgets 这是桌面组件前端开源组件&#xff0c;作者称&#xff1a;项目还在持续完善中&#xff0c;目前包含键盘演示、抖音热榜、喝水提醒、生日列表、待办事项、倒计时、灵动通知、打工进度等多个组件 有vue编程能力的可以自己做组件 百度网盘 夸克网盘 桌面组件 | Ca…...

Mac OS JAVA_HOME设置

个人博客地址&#xff1a;Mac OS JAVA_HOME设置 | 一张假钞的真实世界 在MacOS上使用DMG文件安装了Jdk8 之后&#xff0c;在默认路径下找不到JDK的HOME路径&#xff1a; $ which java /usr/bin/java $ ls -l /usr/bin/java lrwxr-xr-x 1 root wheel 74 12 6 2015 /usr/b…...

6.3 DBMS的功能和特征

文章目录 DBMS的6大功能DBMS的3个特征DBMS的分类 DBMS的6大功能 DBMS包含数据定义&#xff0c;数据库操作&#xff08;检索、插入、修改、删除&#xff09;&#xff0c;数据库运行管理&#xff08;保证多用户环境下正常运行&#xff09;&#xff0c;数据组织、存储、管理&…...

C# ConcurrentQueue 使用详解

总目录 前言 在C#多线程编程中&#xff0c;数据共享如同走钢丝——稍有不慎就会引发竞态条件&#xff08;Race Condition&#xff09;或死锁。传统Queue<T>在并发场景下需要手动加锁&#xff0c;而ConcurrentQueue<T>作为.NET Framework 4.0 引入的线程安全集合&a…...

python脚本文件设置进程优先级(在.py文件中实现)

在 Python 代码中可以直接通过 psutil 模块或 系统调用 来设置进程优先级&#xff0c;无需依赖终端命令。以下是具体方法和示例&#xff1a; 1. 使用 psutil 模块&#xff08;跨平台推荐&#xff09; psutil 是一个跨平台库&#xff0c;支持 Windows、Linux 和 macOS。通过其 …...

基于Django快递物流管理可视化分析系统(完整系统源码+数据库+详细开发文档+万字详细论文+答辩PPT+详细部署教程等资料)

文章目录 基于Django快递物流管理可视化分析系统&#xff08;完整系统源码数据库详细开发文档万字详细论文答辩PPT详细部署教程等资料&#xff09;一、项目概述二、项目说明三、研究意义四、系统设计技术架构 五、功能实现六、完整系统源码数据库详细开发文档万字详细论文答辩P…...

el-table树状表格,默认展开第一个节点的每一层

效果如图 <template><el-table:data"tableData"style"width: 100%":tree-props"{ children: children, hasChildren: hasChildren }":expand-row-keys"expandRowKeys"row-key"id"expand-change"handleExpan…...

【雅思博客05】New Guy in Town

Daily Life ‐ New Guy in Town 原文&#xff1a; A: Oh, I don’t know if you heard, but someone moved into that old house down the road. B: Yeah, I know. I met the owner of the house yesterday as he was moving in. His name is Armand. A: Really? What’s h…...

【Spring详解三】默认标签的解析

三、默认标签的解析 Spring的标签中有 默认标签和 自定义标签&#xff0c;两者的解析有着很大的不同&#xff0c;这次重点说默认标签的解析过程。 DefaultBeanDefinitionDocumentReader.class 默认标签的解析是在 DefaultBeanDefinitionDocumentReader.parseDefaultElement()函…...

Windows 图形显示驱动开发-IoMmu 模型

输入输出内存管理单元 (IOMMU) 是一个硬件组件&#xff0c;它将支持具有 DMA 功能的 I/O 总线连接到系统内存。 它将设备可见的虚拟地址映射到物理地址&#xff0c;使其在虚拟化中很有用。 在 WDDM 2.0 IoMmu 模型中&#xff0c;每个进程都有一个虚拟地址空间&#xff0c;即&a…...

简单易懂,解析Go语言中的Channel管道

Channel 管道 1 初始化 可用var声明nil管道&#xff1b;用make初始化管道&#xff1b; len()&#xff1a; 缓冲区中元素个数&#xff0c; cap()&#xff1a; 缓冲区大小 //变量声明 var a chan int //使用make初始化 b : make(chan int) //不带缓冲区 c : make(chan stri…...

STM32 USB 设备的描述信息作用

在使用 STM32 USB 功能时 usbd_desc.c 文件中定义了一段宏&#xff0c;以下解每段宏的用途。 #define USBD_VID 1155 #define USBD_LANGID_STRING 1033 #define USBD_MANUFACTURER_STRING "STMicroelectronics" #define US…...

Redis字符串常见命令(String)

字符串常见命令&#xff08;String&#xff09; Redis 中的字符串类型是一种非常基础且常用的数据类型&#xff0c;它不仅可以存储任何形式的字符串&#xff08;包括文本数据&#xff09;&#xff0c;还可以对数字字符串进行自增、自减等操作。以下是对 Redis 字符串类型常见命…...

Educational Codeforces Round 174 (Rated for Div. 2)(ABCD)

A. Was there an Array? 翻译&#xff1a; 对于整数数组 ​&#xff0c;我们将其相等特征定义为数组 &#xff0c;其中&#xff0c;如果数组 a 的第 i 个元素等于其两个相邻元素&#xff0c;则 &#xff1b;如果数组 a 的第 i 个元素不等于其至少一个相邻元素&#xff0c;则 …...

基于知识图谱的问答系统:后端Python+Flask,数据库Neo4j,前端Vue3(提供源码)

基于知识图谱的问答系统&#xff1a;后端PythonFlask&#xff0c;数据库Neo4j&#xff0c;前端Vue3 引言 随着人工智能技术的不断发展&#xff0c;知识图谱作为一种结构化的知识表示方式&#xff0c;逐渐成为问答系统的重要组成部分。本文将介绍如何构建一个基于知识图谱的问答…...

面试知识点2

文章目录 1. Linux 与 DockerLinux 基本指令VMware 安装 CentOSDocker 拉取镜像创建容器、部署 Spring Boot 项目 2. 关系型数据库 MySQL数据库语法多表关联查询数据库索引 3. 事务与死锁事务的隔离级别死锁的原因和避免方法 4. 排序算法与数据结构二分查找快速排序常见数据结构…...

【基于 macOS 虚拟机的 iMessage 批量消息处理技术实践】

一、研究背景与技术意义iMessage 作为苹果生态内置的原生通讯服务&#xff0c;依托系统底层优势&#xff0c;具备端到端加密、无运营商拦截、原生展示等特性&#xff0c;常用于企业内部事务提醒、授权用户服务告知等合规场景。在技术研究过程中&#xff0c;手动单条发送消息效率…...

网络工程师实战:用iperf3给你的内网做个“体检”,排查带宽瓶颈(附常用命令模板)

网络工程师实战&#xff1a;用iperf3给你的内网做个“体检”&#xff0c;排查带宽瓶颈&#xff08;附常用命令模板&#xff09; 当内网应用响应迟缓、文件传输卡顿时&#xff0c;网络工程师的第一反应往往是&#xff1a;"到底是服务器性能问题还是网络带宽瓶颈&#xff1…...

2026最权威的降重复率网站实际效果

Ai论文网站排名&#xff08;开题报告、文献综述、降aigc率、降重综合对比&#xff09; TOP1. 千笔AI TOP2. aipasspaper TOP3. 清北论文 TOP4. 豆包 TOP5. kimi TOP6. deepseek 基于自然语言处理技术的智能辅助系统即是 AI 写作工具。它能够快速生成各类文本。其核心功能…...

php内核 内核后门防护、代码执行拦截底层加固

一个直接能落地的“防后门 拦截代码执行”方案。先说结论&#xff1a;最佳方式不是只改一个点&#xff0c;而是 4 层一起上&#xff1a;编译裁剪层 内核拦截层 运行时策略层 系统隔离层。 单点防护一定会漏。---一、先讲大白话&#xff1a;后门最…...

lvgl_v8.1.0-dev之修复渐变效果不生效的bug

根据codex-5.3模型分析,定位到是lvgl源码有问题,在lv_draw_rect.c 183行处 源码为: grad_map[i] = grad_get(dsc, coords_w, i - coords_bg.x1);修改为: grad_map[i...

FPGA工程师的JESD204B通关指南:从Subclass1链路建立到调试避坑(附Xilinx/Intel IP核使用心得)

FPGA工程师的JESD204B实战指南&#xff1a;从参数配置到链路调试全解析 在高速数据采集与处理系统中&#xff0c;JESD204B接口已成为连接FPGA与高速ADC/DAC的事实标准。这个看似简单的串行接口背后&#xff0c;却隐藏着复杂的配置参数和严格的时序要求。作为FPGA工程师&#xf…...

Windows上直接安装APK文件:告别安卓模拟器的终极指南

Windows上直接安装APK文件&#xff1a;告别安卓模拟器的终极指南 【免费下载链接】APK-Installer An Android Application Installer for Windows 项目地址: https://gitcode.com/GitHub_Trending/ap/APK-Installer 你是否曾经想在Windows电脑上运行安卓应用&#xff0c…...

3分钟搭建完整KIMI AI免费API:解锁智能对话接口的终极解决方案

3分钟搭建完整KIMI AI免费API&#xff1a;解锁智能对话接口的终极解决方案 【免费下载链接】kimi-free-api &#x1f680; KIMI AI 长文本大模型逆向API【特长&#xff1a;长文本解读整理】&#xff0c;支持高速流式输出、智能体对话、联网搜索、探索版、K1思考模型、长文档解读…...

别再只会用open和close了!Tcl文件读写实战:从读取日志到批量处理文本的5个真实场景

Tcl文件操作实战&#xff1a;5个真实场景提升你的脚本工程能力 如果你已经掌握了Tcl中open和close的基本用法&#xff0c;那么是时候将这些知识应用到实际工作场景中了。本文将带你深入五个真实世界的文件操作案例&#xff0c;从日志分析到批量处理&#xff0c;每个技巧都能立即…...

玻尔兹曼脑伦理:测试从业者的哲学镜像与技术思辨

一个来自物理学的“Bug”报告在软件测试的日常中&#xff0c;我们习惯于追踪缺陷、验证逻辑、确保系统行为符合预期。我们深信&#xff0c;在一个确定性的输入下&#xff0c;系统应给出确定性的输出&#xff0c;世界的运行建立在可观测、可复现的规律之上。然而&#xff0c;物理…...