SpringBoot 接入讯飞星火大模型实现对话

申请地址

https://xinghuo.xfyun.cn/sparkapi?scr=price
免费申请200万Token

开发文档

https://www.xfyun.cn/doc/spark/Web.html#_1-接口说明

页面最下面有相关demo可以参考

在这里插入图片描述

介绍

接口是以套接字的形式分段返回,而且非http请求,比较繁琐,官方也只给了比较简单的deom。

依赖项

  <!--okhttp3--><dependency><groupId>com.squareup.okhttp3</groupId><artifactId>okhttp</artifactId></dependency><!-- 阿里JSON解析器 --><dependency><groupId>com.alibaba.fastjson2</groupId><artifactId>fastjson2</artifactId></dependency>

配置文件

xunfei:ai:hostUrl: https://spark-api.xf-yun.com/v3.5/chatappId: xxxapiSecret: xxxapiKey: xxx

控制台上可以查看 API认证字符串

在这里插入图片描述

读取配置文件

@Value("${xunfei.ai.hostUrl}")
private  String  hostUrl;@Value("${xunfei.ai.appId}")
private  String appId;@Value("${xunfei.ai.apiSecret}")
private  String apiSecret;@Value("${xunfei.ai.apiKey}")
private  String apiKey;

权限校验

得到的是一个url,需要将http替换成ws

/*** 权限校验* @return String* @throws NoSuchAlgorithmException* @throws InvalidKeyException* @throws MalformedURLException*/private String getAuthUrl() throws NoSuchAlgorithmException, InvalidKeyException, MalformedURLException {URL url = new URL(hostUrl);// 时间SimpleDateFormat format = new SimpleDateFormat("EEE, dd MMM yyyy HH:mm:ss z", Locale.US);format.setTimeZone(TimeZone.getTimeZone("GMT"));String date = format.format(new Date());// 拼接String preStr = "host: " + url.getHost() + "\n" +"date: " + date + "\n" +"GET " + url.getPath() + " HTTP/1.1";// System.err.println(preStr);// SHA256加密Mac mac = Mac.getInstance("hmacsha256");SecretKeySpec spec = new SecretKeySpec(apiSecret.getBytes(StandardCharsets.UTF_8), "hmacsha256");mac.init(spec);byte[] hexDigits = mac.doFinal(preStr.getBytes(StandardCharsets.UTF_8));// Base64加密String sha = Base64.getEncoder().encodeToString(hexDigits);// System.err.println(sha);// 拼接String authorization = String.format("api_key=\"%s\", algorithm=\"%s\", headers=\"%s\", signature=\"%s\"", apiKey, "hmac-sha256", "host date request-line", sha);// 拼接地址HttpUrl httpUrl = Objects.requireNonNull(HttpUrl.parse("https://" + url.getHost() + url.getPath())).newBuilder().addQueryParameter("authorization", Base64.getEncoder().encodeToString(authorization.getBytes(StandardCharsets.UTF_8))).addQueryParameter("date", date).addQueryParameter("host", url.getHost()).build();return httpUrl.toString();}

构建请求参数

请求参数是与json格式进行发送,如果需要结合之前的信息继续回答需要携带历史记录。在官方的api文档也可以查看

#参数构造示例如下

{"header": {"app_id": "12345","uid": "12345"},"parameter": {"chat": {"domain": "generalv3.5","temperature": 0.5,"max_tokens": 1024, }},"payload": {"message": {# 如果想获取结合上下文的回答,需要开发者每次将历史问答信息一起传给服务端,如下示例# 注意:text里面的所有content内容加一起的tokens需要控制在8192以内,开发者如有较长对话需求,需要适当裁剪历史信息"text": [{"role":"system","content":"你现在扮演李白,你豪情万丈,狂放不羁;接下来请用李白的口吻和用户对话。"} #设置对话背景或者模型角色{"role": "user", "content": "你是谁"} # 用户的历史问题{"role": "assistant", "content": "....."}  # AI的历史回答结果# ....... 省略的历史对话{"role": "user", "content": "你会做什么"}  # 最新的一条问题,如无需上下文,可只传最新一条问题]}}
}

JAVA构建

private    String buildBody(String text,String uid){JSONObject body =new JSONObject();JSONObject header =new JSONObject();header.put("app_id",appId);header.put("uid",uid);body.put("header",header);JSONObject parameter =new JSONObject();JSONObject chat =new JSONObject();chat.put("domain","generalv3.5");parameter.put("chat",chat);body.put("parameter",parameter);JSONObject history =JSONObject.parseObject(text);body.put("payload",history);JSONObject back =new JSONObject();back.put("role","system");back.put("content","请回答我关于一些生产安全的内容");//定义会话背景history.getJSONObject("message").getJSONArray("text").add(0,back);return body.toJSONString();}

回复消息

基于OKHTTP3的请求库,连接websocket

 /*** 回复消息* @param text* @return* @throws MalformedURLException* @throws NoSuchAlgorithmException* @throws InvalidKeyException*/public String answer(String text,String uid) throws MalformedURLException, NoSuchAlgorithmException, InvalidKeyException, ExecutionException, InterruptedException, TimeoutException {String authUrl =getAuthUrl().replace("http://", "ws://").replace("https://", "wss://");Request request = new Request.Builder().url(authUrl).build();OkHttpClient client = new OkHttpClient.Builder().build();StringBuilder sb =new StringBuilder();CompletableFuture<String> messageReceived = new CompletableFuture<>();String body = buildBody(text,uid);WebSocket webSocket =client.newWebSocket(request, new WebSocketListener() {@Overridepublic void onOpen(WebSocket webSocket, Response response) {webSocket.send(body);//发送消息}@Overridepublic void onMessage(WebSocket webSocket, String text) {JSONObject obj = JSON.parseObject(text);String str= obj.getJSONObject("payload").getJSONObject("choices").getJSONArray("text").getJSONObject(0).getString("content");sb.append(str);if(obj.getJSONObject("header").getLong("status")==2){webSocket.close(1000, "Closing WebSocket connection");messageReceived.complete(text); // 将收到的消息传递给 CompletableFuture}}} );String result = messageReceived.get(30, TimeUnit.SECONDS);; // 阻塞等待消息返回webSocket.close(1000, "Closing WebSocket connection");return sb.toString();}

Controller

   @PostMapping("/chat")public AjaxResult chat(String text,String uid) throws MalformedURLException, NoSuchAlgorithmException, InvalidKeyException, ExecutionException, InterruptedException, TimeoutException {return  success( model.answer(text,uid));}

运行效果

在这里插入图片描述

完整代码

Controller层

@RestController
@RequestMapping("/course")
public class QueryController extends BaseController {@Autowiredprivate CognitiveMode model;@PostMapping("/chat")public AjaxResult chat(String text,String uid) throws MalformedURLException, NoSuchAlgorithmException, InvalidKeyException, ExecutionException, InterruptedException, TimeoutException {return  success( model.answer(text,uid));}}
package com.ruoyi.framework.ai;
import com.alibaba.fastjson2.JSON;
import com.alibaba.fastjson2.JSONObject;
import okhttp3.*;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Component;
import javax.crypto.Mac;
import javax.crypto.spec.SecretKeySpec;
import java.net.MalformedURLException;
import java.net.URL;
import java.nio.charset.StandardCharsets;
import java.security.InvalidKeyException;
import java.security.NoSuchAlgorithmException;
import java.text.SimpleDateFormat;
import java.util.*;
import java.util.concurrent.CompletableFuture;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.TimeoutException;@Component
public class CognitiveMode {@Value("${xunfei.ai.hostUrl}")private  String  hostUrl;@Value("${xunfei.ai.appId}")private  String appId;@Value("${xunfei.ai.apiSecret}")private  String apiSecret;@Value("${xunfei.ai.apiKey}")private  String apiKey;/*** 回复消息* @param text* @return* @throws MalformedURLException* @throws NoSuchAlgorithmException* @throws InvalidKeyException*/public String answer(String text,String uid) throws MalformedURLException, NoSuchAlgorithmException, InvalidKeyException, ExecutionException, InterruptedException, TimeoutException {String authUrl =getAuthUrl().replace("http://", "ws://").replace("https://", "wss://");Request request = new Request.Builder().url(authUrl).build();OkHttpClient client = new OkHttpClient.Builder().build();StringBuilder sb =new StringBuilder();CompletableFuture<String> messageReceived = new CompletableFuture<>();String body = buildBody(text,uid);WebSocket webSocket =client.newWebSocket(request, new WebSocketListener() {@Overridepublic void onOpen(WebSocket webSocket, Response response) {webSocket.send(body);}@Overridepublic void onMessage(WebSocket webSocket, String text) {JSONObject obj = JSON.parseObject(text);String str= obj.getJSONObject("payload").getJSONObject("choices").getJSONArray("text").getJSONObject(0).getString("content");sb.append(str);if(obj.getJSONObject("header").getLong("status")==2){webSocket.close(1000, "Closing WebSocket connection");messageReceived.complete(text); // 将收到的消息传递给 CompletableFuture}}} );String result = messageReceived.get(30, TimeUnit.SECONDS);; // 阻塞等待消息返回webSocket.close(1000, "Closing WebSocket connection");return sb.toString();}private    String buildBody(String text,String uid){JSONObject body =new JSONObject();JSONObject header =new JSONObject();header.put("app_id",appId);header.put("uid",uid);body.put("header",header);JSONObject parameter =new JSONObject();JSONObject chat =new JSONObject();chat.put("domain","generalv3.5");parameter.put("chat",chat);body.put("parameter",parameter);JSONObject history =JSONObject.parseObject(text);body.put("payload",history);JSONObject back =new JSONObject();back.put("role","system");back.put("content","请回答我关于一些xxx的内容");history.getJSONObject("message").getJSONArray("text").add(0,back);return body.toJSONString();}/*** 权限校验* @return String* @throws NoSuchAlgorithmException* @throws InvalidKeyException* @throws MalformedURLException*/private String getAuthUrl() throws NoSuchAlgorithmException, InvalidKeyException, MalformedURLException {URL url = new URL(hostUrl);// 时间SimpleDateFormat format = new SimpleDateFormat("EEE, dd MMM yyyy HH:mm:ss z", Locale.US);format.setTimeZone(TimeZone.getTimeZone("GMT"));String date = format.format(new Date());// 拼接String preStr = "host: " + url.getHost() + "\n" +"date: " + date + "\n" +"GET " + url.getPath() + " HTTP/1.1";// System.err.println(preStr);// SHA256加密Mac mac = Mac.getInstance("hmacsha256");SecretKeySpec spec = new SecretKeySpec(apiSecret.getBytes(StandardCharsets.UTF_8), "hmacsha256");mac.init(spec);byte[] hexDigits = mac.doFinal(preStr.getBytes(StandardCharsets.UTF_8));// Base64加密String sha = Base64.getEncoder().encodeToString(hexDigits);// System.err.println(sha);// 拼接String authorization = String.format("api_key=\"%s\", algorithm=\"%s\", headers=\"%s\", signature=\"%s\"", apiKey, "hmac-sha256", "host date request-line", sha);// 拼接地址HttpUrl httpUrl = Objects.requireNonNull(HttpUrl.parse("https://" + url.getHost() + url.getPath())).newBuilder().addQueryParameter("authorization", Base64.getEncoder().encodeToString(authorization.getBytes(StandardCharsets.UTF_8))).addQueryParameter("date", date).addQueryParameter("host", url.getHost()).build();return httpUrl.toString();}}

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

如若内容造成侵权/违法违规/事实不符,请联系瞎胡闹网进行投诉反馈,一经查实,立即删除!

相关文章

fast.ai 深度学习笔记(三)

深度学习 2&#xff1a;第 1 部分第 6 课 原文&#xff1a;medium.com/hiromi_suenaga/deep-learning-2-part-1-lesson-6-de70d626976c 译者&#xff1a;飞龙 协议&#xff1a;CC BY-NC-SA 4.0 来自 fast.ai 课程的个人笔记。随着我继续复习课程以“真正”理解它&#xff0c;这…

模型蒸馏distill /模型剪枝 论文汇总

文章目录 引言1. 蒸馏1&#xff09;白盒蒸馏DistilBERTPatient Knowledge DistillationTinyBERT 2020MiniLLM 2&#xff09;黑盒蒸馏Stanford alpacaVicunaWizardlmInstruction tuning with gpt-4Minigpt-4 2. 剪枝16个注意力头比一个好吗Movement pruning 1&#xff09;结构化…

【实习】深信服防火墙网络安全生产实习

一、实习概况 1.1实习目的 1.掌握防火墙规则的作用2.掌握代理上网功能的作用3.掌握端口映射功能的作用 1.2实习任务 1.防火墙的WEB控制台 2.需要在防火墙上配置dnat …

【设计模式】23中设计模式笔记

设计模式分类 模板方法模式 核心就是设计一个部分抽象类。 这个类具有少量具体的方法&#xff0c;和大量抽象的方法&#xff0c;具体的方法是为外界提供服务的点&#xff0c;具体方法中定义了抽象方法的执行序列 装饰器模式 现在有一个对象A&#xff0c;希望A的a方法被修饰 …

CVE-2021-44915 漏洞复现

CVE-2021-44915 路由/admin/admin.php是后台&#xff0c;登录账号和密码默认是admin、tao&#xff0c;选择管理栏目菜单。 点击编辑&#xff0c;然后随便改点内容&#xff0c;提交时候抓包。 id是注入点。直接拿sqlmap跑就行了。

20240210使用剪映识别字幕的时候的GPU占比RX580-RTX4090

20240210使用剪映识别字幕的时候的GPU占比RX580-RTX4090 2024/2/10 17:54 【使用剪映识别不同的封装格式&#xff0c;不同的音视频编码&#xff0c;对GPU的占用率可能会有比较大的不同&#xff01;】 很容易发现在在WIN10下使用剪映的时候&#xff0c;X99RX550组合。 GPU部分&…

探索C语言的内存魔法:动态内存管理解析

✨✨ 欢迎大家来到贝蒂大讲堂✨✨ &#x1f388;&#x1f388;养成好习惯&#xff0c;先赞后看哦~&#x1f388;&#x1f388; 所属专栏&#xff1a;C语言学习 贝蒂的主页&#xff1a;Betty‘s blog 1. 静态开辟内存 通过前面的学习&#xff0c;我们已经掌握了两种开辟内存的方…

ChatGPT高效提问—prompt常见用法(续篇八)

ChatGPT高效提问—prompt常见用法(续篇八) 1.1 对抗 ​ 对抗是一个重要主题,深入探讨了大型语言模型(LLM)的安全风险。它不仅反映了人们对LLM可能出现的风险和安全问题的理解,而且能够帮助我们识别这些潜在的风险,并通过切实可行的技术手段来规避。 ​ 截至目前,网络…

4核8g服务器能支持多少人访问?2024新版测评

腾讯云轻量4核8G12M轻量应用服务器支持多少人同时在线&#xff1f;通用型-4核8G-180G-2000G&#xff0c;2000GB月流量&#xff0c;系统盘为180GB SSD盘&#xff0c;12M公网带宽&#xff0c;下载速度峰值为1536KB/s&#xff0c;即1.5M/秒&#xff0c;假设网站内页平均大小为60KB…

酷开系统 | 拓展内容营销边界,酷开科技大屏价值全面升维

丰富的内容是智能大屏吸引消费者的关键。随着智能大屏各类垂直应用的增多&#xff0c;和长、短视频等多元内容的加入&#xff0c;使消费者的使用需求进一步激发和释放&#xff0c;这些流量的加入&#xff0c;也使大屏成为了营销的天然宝藏。酷开科技一直致力于OTT大屏营销&…

《杨绛传:生活不易,保持优雅》读书摘录

目录 书简介 作者成就 书中内容摘录 良好的家世背景&#xff0c;书香门第为求学打基础 求学相关 念大学 清华研究生 自费英国留学 法国留学自学文学 战乱时期回国 当校长 当小学老师 创造话剧 支持钱锺书写《围城》 出任震旦女子文理学院的教授 接受清华大学的…

分享关闭Windows自动更新的六种方法。

方法一&#xff1a;禁用Windows Update服务 同时按下键盘的“WinR”键&#xff0c;打开“运行”窗口&#xff0c;输入“services.msc”并点击“确定”。 在打开的服务列表中找到“Windows Update”选项&#xff0c;双击打开其属性窗口。 在“启动类型”下拉菜单中选择“禁用”…

Linux系统基础 03 IP地址虚拟网络、Linux软件包管理、ssh服务、apache服务和samba服务的简单搭建

文章目录 一、IP地址虚拟网络二、Linux软件包管理1、rpm包管理器2、yum包管理器3、源码安装 三、ssh服务四、apache服务五、samba服务 一、IP地址虚拟网络 1、IP地址格式是点分十进制&#xff0c;例&#xff1a;172.16.45.10。即4段8位二进制 2、IP地址分为网络位和主机位。网…

备战蓝桥杯---动态规划(基础3)

本专题主要介绍在求序列的经典问题上dp的应用。 我们上次用前缀和来解决&#xff0c;这次让我们用dp解决把 我们参考不下降子序列的思路&#xff0c;可以令f[i]为以i结尾的最大字段和&#xff0c;易得&#xff1a; f[i]max(a[i],a[i]f[i-1]); 下面是AC代码&#xff1a; #in…

Linux应用 进程间通信之共享内存(System V)

1、定义 System V共享内存是一种在Unix和类Unix操作系统上用于进程间通信的机制。它允许多个进程共享同一块物理内存区域&#xff0c;从而可以在这些进程之间传递数据。 应用场景&#xff1a; 数据共享&#xff1a;多个进程需要共享大量数据&#xff0c;如数据库缓存、图像处…

队列---数据结构

定义 队列&#xff08;Queue&#xff09;简称队&#xff0c;也是一种操作受限的线性表&#xff0c;只允许在表的一端进行插入&#xff0c;而在表的另一端进行删除。向队列中插入元素称为入队或进队&#xff1b;删除元素称为出队或离队。 队头&#xff08;Front&#xff09;&a…

上位机图像处理和嵌入式模块部署(利用python开发软件)

【 声明&#xff1a;版权所有&#xff0c;欢迎转载&#xff0c;请勿用于商业用途。 联系信箱&#xff1a;feixiaoxing 163.com】 开发windows和linux软件的时候&#xff0c;大家一般都是习惯于用c/c语言进行开发&#xff0c;但是目前来说很多的开发板都是支持python语言开发的。…

防火墙USG6000V配置接口实验

要求:防火墙向下使用子接口分别对应生产区和办公区,所有分区设备可以ping通网关 最终效果部分示例:client1,Server1,PC2都能ping通网关 实现流程: 云要添加虚拟网卡ip(此处用的是创建的虚拟环回ip),更改端口映射为双向通道且更改编号 SW1:#要先登录防火墙初始账号和密码,然后…

尝新果未熟,探新途未尽。寒冬凝锐气,雷鸣蓄神力——小康师兄的2023年度总结

文章目录 一、前言二、工作总结2.1 我期望的&#xff0c;而公司想要的2.2 公司利益VS员工利益2.3 这个问题问得很有问题 三、生活总结3.1 一胎3.2 二胎 四、其他总结4.1 博客4.2 无人自助台球馆4.3 我要出书了 五、OKR 一、前言 又是一年除夕夜&#xff0c;万家灯火同团圆。 老…

|Python新手小白低级教程|第十九章:函数(1)

文章目录 前言一、概说二、方法def简介1.示例&#xff1a;使用def关键字制作功能函数——找最大最小2.代码剖析示例代码Part 1示例代码Part 2示例代码Part 3练习1.1制作函数 三、灵活使用函数1.制作一种函数&#xff0c;函数名和格式为even_num(a,b)&#xff0c;输入a&#xff…