配置模块,加写完后台

master
sikadi 2023-09-28 11:24:48 +08:00
parent 88d4dba7ee
commit 7b1492be0a
12 changed files with 329 additions and 126 deletions

View File

@ -0,0 +1,6 @@
<component name="InspectionProjectProfileManager">
<profile version="1.0">
<option name="myName" value="Project Default" />
<inspection_tool class="AliAccessStaticViaInstance" enabled="true" level="WARNING" enabled_by_default="true" />
</profile>
</component>

View File

@ -1,29 +1,13 @@
package com.sikadi.user;
import com.bwie.common.domain.XfXhConfig;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.context.annotation.Bean;
import top.hualuo.XhStreamClient;
@SpringBootApplication
public class GTPApplication {
@Autowired
private XfXhConfig xfXhConfig;
public static void main(String[] args) {
SpringApplication.run(GTPApplication.class, args);
}
@Bean
public XhStreamClient xhStreamClient (){
return XhStreamClient.builder()
.apiHost(xfXhConfig.getApiHost())
.apiPath(xfXhConfig.getApiPath())
.appId(xfXhConfig.getAppId())
.apiKey(xfXhConfig.getApiKey())
.apiSecret(xfXhConfig.getApiSecret())
.build();
}
}

View File

@ -1,12 +1,15 @@
package com.sikadi.user.controller;
import com.bwie.common.domain.StringAppGTP;
import com.sikadi.user.listener.XfXhStreamClient;
import com.sikadi.user.mapper.XfXhConfig;
import com.sikadi.user.service.GTPService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;
import top.hualuo.XhStreamClient;
import javax.annotation.Resource;
@RestController
public class GTPController {
@ -16,10 +19,19 @@ public class GTPController {
@PostMapping("/chat")
public String chat(@RequestBody StringAppGTP stringAppGTP){
return gtpService.chat(stringAppGTP);
/**
*
*
* @param question
* @return
*/
@GetMapping("/sendQuestion")
public String sendQuestion(@RequestParam("question") String question) {
return gtpService.sendQuestion(question);
}
}

View File

@ -0,0 +1,50 @@
package com.sikadi.user.dto;
import com.fasterxml.jackson.annotation.JsonInclude;
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;
/**
*
*
* @author
* @create 2023-09-15 0:42
*/
/**
*
*
* @author
* @create 2023-09-15 0:42
*/
@Data
@AllArgsConstructor
@NoArgsConstructor
@JsonInclude(JsonInclude.Include.NON_NULL)
public class MsgDTO {
/**
*
*/
private String role;
/**
*
*/
private String content;
/**
* [0,10];
*/
private Integer index;
public static final String ROLE_USER = "user";
public static final String ROLE_ASSISTANT = "assistant";
public static MsgDTO createUserMsg(String content) {
return new MsgDTO(ROLE_USER, content, null);
}
public static MsgDTO createAssistantMsg(String content) {
return new MsgDTO(ROLE_ASSISTANT, content, null);
}
}

View File

@ -0,0 +1,97 @@
package com.sikadi.user.dto.request;
import com.alibaba.fastjson.annotation.JSONField;
import com.fasterxml.jackson.annotation.JsonProperty;
import com.sikadi.user.dto.MsgDTO;
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;
import java.util.List;
/**
* @description:
* @author:
* @date: 2023/9/28 10:12
* @param:
* @return:
**/
/**
*
* JSON resources/demo-json/request.json
*
* @author
* @create 2023-09-15 0:42
*/
@NoArgsConstructor
@Data
public class RequestDTO {
@JsonProperty("header")
private HeaderDTO header;
@JsonProperty("parameter")
private ParameterDTO parameter;
@JsonProperty("payload")
private PayloadDTO payload;
@NoArgsConstructor
@Data
@AllArgsConstructor
public static class HeaderDTO {
/**
* appid
*/
@JSONField(name = "app_id")
private String appId;
/**
* id32
*/
@JSONField(name = "uid")
private String uid;
}
@NoArgsConstructor
@Data
@AllArgsConstructor
public static class ParameterDTO {
private ChatDTO chat;
@NoArgsConstructor
@Data
@AllArgsConstructor
public static class ChatDTO {
/**
* 访,generalV1.5 generalv2V2url
*/
@JsonProperty("domain")
private String domain;
/**
*
*/
@JsonProperty("temperature")
private Float temperature;
/**
* tokens
*/
@JSONField(name = "max_tokens")
private Integer maxTokens;
}
}
@NoArgsConstructor
@Data
@AllArgsConstructor
public static class PayloadDTO {
@JsonProperty("message")
private MessageDTO message;
@NoArgsConstructor
@Data
@AllArgsConstructor
public static class MessageDTO {
@JsonProperty("text")
private List<MsgDTO> text;
}
}
}

View File

@ -0,0 +1,48 @@
package com.sikadi.user.mapper;
import lombok.Data;
import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.context.annotation.Configuration;
/**
* @author
* @create 2023-09-15 0:46
*/
@Configuration
@ConfigurationProperties(prefix = "xfxh")
@Data
public class XfXhConfig {
/**
* 使 V2.0使 V1.5 hostUrl https://spark-api.xf-yun.com/v1.1/chat
*/
private String hostUrl;
/**
* 访 V1.5 general V2 generalv2
*/
private String domain;
/**
* [0,1]
*/
private Float temperature;
/**
* tokensV1.5[1,4096]V2.0[1,8192]
*/
private Integer maxTokens;
/**
* s
*/
private Integer maxResponseTime;
/**
*
*/
private String appId;
/**
*
*/
private String apiKey;
/**
*
*/
private String apiSecret;
}

View File

@ -1,7 +1,6 @@
package com.sikadi.user.service;
import com.bwie.common.domain.StringAppGTP;
public interface GTPService {
String chat(StringAppGTP stringAppGTP);
String sendQuestion(String question);
}

View File

@ -1,27 +1,74 @@
package com.sikadi.user.service.impl;
import com.bwie.common.domain.StringAppGTP;
import com.bwie.common.utils.XfXhListener;
import cn.hutool.core.util.StrUtil;
import com.sikadi.user.dto.MsgDTO;
import com.sikadi.user.listener.XfXhStreamClient;
import com.sikadi.user.listener.XfXhWebSocketListener;
import com.sikadi.user.mapper.XfXhConfig;
import com.sikadi.user.service.GTPService;
import lombok.extern.log4j.Log4j2;
import okhttp3.WebSocket;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import top.hualuo.XhStreamClient;
import top.hualuo.dto.MsgDTO;
import java.util.Arrays;
import javax.annotation.Resource;
import java.util.Collections;
import java.util.UUID;
@Service
@Log4j2
public class GTPServiceImpl implements GTPService {
@Autowired
private XhStreamClient xhStreamClient;
@Resource
private XfXhStreamClient xfXhStreamClient;
@Resource
private XfXhConfig xfXhConfig;
@Override
public String chat(StringAppGTP stringAppGTP) {
public String sendQuestion(String question) {
// 如果是无效字符串,则不对大模型进行请求
if (StrUtil.isBlank(question)) {
return "无效问题,请重新输入";
}
MsgDTO dto = MsgDTO.builder().role(MsgDTO.Role.USER.getName()).content(stringAppGTP.getProblem()).build();
return xhStreamClient.sendMsg("123", Arrays.asList(dto),new XfXhListener());;
// 创建消息对象
MsgDTO msgDTO = MsgDTO.createUserMsg(question);
// 创建监听器
XfXhWebSocketListener listener = new XfXhWebSocketListener();
// 发送问题给大模型,生成 websocket 连接
WebSocket webSocket = xfXhStreamClient.sendMsg(UUID.randomUUID().toString().substring(0, 10), Collections.singletonList(msgDTO), listener);
if (webSocket == null) {
// 归还令牌
xfXhStreamClient.operateToken(XfXhStreamClient.BACK_TOKEN_STATUS);
return "系统内部错误,请联系管理员";
}
try {
int count = 0;
// 为了避免死循环,设置循环次数来定义超时时长
int maxCount = xfXhConfig.getMaxResponseTime() * 5;
while (count <= maxCount) {
Thread.sleep(200);
if (listener.isWsCloseFlag()) {
break;
}
count++;
}
if (count > maxCount) {
return "大模型响应超时,请联系管理员";
}
// 响应大模型的答案
return listener.getAnswer().toString();
} catch (InterruptedException e) {
log.error("错误:" + e.getMessage());
return "系统内部错误,请联系管理员";
} finally {
// 关闭 websocket 连接
webSocket.close(1000, "");
// 归还令牌
xfXhStreamClient.operateToken(XfXhStreamClient.BACK_TOKEN_STATUS);
}
}
}

View File

@ -29,8 +29,21 @@ spring:
- application-${spring.profiles.active}.${spring.cloud.nacos.config.file-extension}
namespace: Sikadi
xfxh:
apiHost: spark-api.xf-yun.com
apiPath: /v1.1/chat
# 服务引擎使用 讯飞星火认知大模型V2.0,如果使用 V1.5 需要将 hostUrl 修改为 https://spark-api.xf-yun.com/v1.1/chat
hostUrl: https://spark-api.xf-yun.com/v2.1/chat
# 发送请求时指定的访问领域,如果是 V1.5版本 设置为 general如果是 V2版本 设置为 generalv2
domain: generalv2
# 核采样阈值。用于决定结果随机性,取值越高随机性越强即相同的问题得到的不同答案的可能性越高。取值 [0,1]
temperature: 0.5
# 模型回答的tokens的最大长度V1.5取值为[1,4096]V2.0取值为[1,8192]。
maxTokens: 2048
# 大模型回复问题的最大响应时长,单位 s
maxResponseTime: 30
# 允许同时连接大模型的 websocket 数,如果是普通(免费)用户为 2超过这个数连接响应会报错具体参考官网。
QPS: 2
# 用于权限验证,从服务接口认证信息中获取
appId: 9f22c545
apiKey: N2NjMDU3ZTQwYjBkODI5ZGM3ZTVjYWY3
apiSecret: a8e17cdcbc9addd7f21e81dff71bc177
# 用于权限验证,从服务接口认证信息中获取
apiKey: a8e17cdcbc9addd7f21e81dff71bc177
# 用于权限验证,从服务接口认证信息中获取
apiSecret: N2NjMDU3ZTQwYjBkODI5ZGM3ZTVjYWY3

View File

@ -125,9 +125,37 @@
</dependency>
<dependency>
<groupId>io.github.a812086325</groupId>
<artifactId>xfxh-java</artifactId>
<version>1.0</version>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-configuration-processor</artifactId>
<optional>true</optional>
</dependency>
<dependency>
<groupId>cn.hutool</groupId>
<artifactId>hutool-all</artifactId>
<version>5.8.18</version>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>com.alibaba</groupId>
<artifactId>fastjson</artifactId>
<version>1.2.67</version>
</dependency>
<dependency>
<groupId>org.java-websocket</groupId>
<artifactId>Java-WebSocket</artifactId>
<version>1.3.8</version>
</dependency>
<dependency>
<groupId>com.squareup.okhttp3</groupId>
<artifactId>okhttp</artifactId>
<version>4.10.0</version>
</dependency>
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
</dependency>
</dependencies>

View File

@ -1,24 +0,0 @@
package com.bwie.common.domain;
import lombok.Data;
import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.context.annotation.Configuration;
@Configuration
@ConfigurationProperties(prefix = "xfxh")
@Data
public class XfXhConfig {
private StringAppGTP apiHost;
private StringAppGTP apiPath;
private StringAppGTP appId;
private StringAppGTP apiKey;
private StringAppGTP apiSecret;
}

View File

@ -1,57 +0,0 @@
package com.bwie.common.utils;
import com.alibaba.fastjson.JSONObject;
import com.alibaba.nacos.shaded.org.checkerframework.checker.nullness.qual.Nullable;
import okhttp3.Response;
import okhttp3.WebSocket;
import okhttp3.WebSocketListener;
import top.hualuo.dto.MsgDTO;
import top.hualuo.dto.ResponseDTO;
import javax.validation.constraints.NotNull;
import java.util.List;
public class XfXhListener extends WebSocketListener {
@Override
public void onOpen(@NotNull WebSocket webSocket, @NotNull Response response) {
super.onOpen(webSocket, response);
}
@Override
public void onMessage(@NotNull WebSocket webSocket, @NotNull String text) {
super.onMessage(webSocket, text);
System.out.println("text:\n" + text);
ResponseDTO responseData = JSONObject.parseObject(text, ResponseDTO.class);
if(0 == responseData.getHeader().getCode()){
ResponseDTO.PayloadDTO pl = responseData.getPayload();
List<MsgDTO> tests = pl.getChoices().getText();
MsgDTO textDTO = tests.stream().findFirst().orElse(new MsgDTO());
System.out.println(textDTO.toString());
if(2 == responseData.getHeader().getStatus()){
ResponseDTO.PayloadDTO.UsageDTO.TextDTO testDto = pl.getUsage().getText();
Integer totalTokens = testDto.getTotalTokens();
System.out.println("本次花费:"+totalTokens + " tokens");
webSocket.close(3,"客户端主动断开链接");
}
}else{
System.out.println("返回结果错误:\n" + responseData.getHeader().getCode()+ responseData.getHeader().getMessage() );
}
}
@Override
public void onFailure(@NotNull WebSocket webSocket, @NotNull Throwable t, @Nullable Response response) {
super.onFailure(webSocket, t, response);
}
@Override
public void onClosed(@NotNull WebSocket webSocket, int code, @NotNull String reason) {
super.onClosed(webSocket, code, reason);
}
}