mirror of
https://github.com/zongzibinbin/MallChat.git
synced 2026-03-14 06:03:42 +08:00
fix:
1.优化gpt上下文的能力 2.成员列表删除无效字段
This commit is contained in:
@@ -115,10 +115,6 @@
|
|||||||
<version>${junit.version}</version>
|
<version>${junit.version}</version>
|
||||||
<scope>test</scope>
|
<scope>test</scope>
|
||||||
</dependency>
|
</dependency>
|
||||||
<dependency>
|
|
||||||
<groupId>com.alibaba</groupId>
|
|
||||||
<artifactId>fastjson</artifactId>
|
|
||||||
</dependency>
|
|
||||||
<dependency>
|
<dependency>
|
||||||
<groupId>org.springframework</groupId>
|
<groupId>org.springframework</groupId>
|
||||||
<artifactId>spring-test</artifactId>
|
<artifactId>spring-test</artifactId>
|
||||||
|
|||||||
@@ -1,6 +1,7 @@
|
|||||||
package com.abin.mallchat.common.common.utils;
|
package com.abin.mallchat.common.common.utils;
|
||||||
|
|
||||||
import com.fasterxml.jackson.core.JsonProcessingException;
|
import com.fasterxml.jackson.core.JsonProcessingException;
|
||||||
|
import com.fasterxml.jackson.databind.JsonNode;
|
||||||
import com.fasterxml.jackson.databind.ObjectMapper;
|
import com.fasterxml.jackson.databind.ObjectMapper;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -19,6 +20,14 @@ public class JsonUtils {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public static JsonNode toJsonNode(String str) {
|
||||||
|
try {
|
||||||
|
return jsonMapper.readTree(str);
|
||||||
|
} catch (JsonProcessingException e) {
|
||||||
|
throw new UnsupportedOperationException(e);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
public static String toStr(Object t) {
|
public static String toStr(Object t) {
|
||||||
try {
|
try {
|
||||||
return jsonMapper.writeValueAsString(t);
|
return jsonMapper.writeValueAsString(t);
|
||||||
@@ -26,4 +35,5 @@ public class JsonUtils {
|
|||||||
throw new UnsupportedOperationException(e);
|
throw new UnsupportedOperationException(e);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -20,10 +20,6 @@ import java.util.Date;
|
|||||||
public class ChatMemberResp {
|
public class ChatMemberResp {
|
||||||
@ApiModelProperty("uid")
|
@ApiModelProperty("uid")
|
||||||
private Long uid;
|
private Long uid;
|
||||||
@ApiModelProperty("用户名称")
|
|
||||||
private String name;
|
|
||||||
@ApiModelProperty("头像")
|
|
||||||
private String avatar;
|
|
||||||
/**
|
/**
|
||||||
* @see com.abin.mallchat.common.user.domain.enums.ChatActiveStatusEnum
|
* @see com.abin.mallchat.common.user.domain.enums.ChatActiveStatusEnum
|
||||||
*/
|
*/
|
||||||
|
|||||||
@@ -1,7 +1,6 @@
|
|||||||
package com.abin.mallchat.custom.chat.service.adapter;
|
package com.abin.mallchat.custom.chat.service.adapter;
|
||||||
|
|
||||||
import cn.hutool.core.lang.Pair;
|
import cn.hutool.core.lang.Pair;
|
||||||
import com.abin.mallchat.common.user.domain.entity.User;
|
|
||||||
import com.abin.mallchat.common.user.domain.enums.ChatActiveStatusEnum;
|
import com.abin.mallchat.common.user.domain.enums.ChatActiveStatusEnum;
|
||||||
import com.abin.mallchat.common.user.service.cache.UserCache;
|
import com.abin.mallchat.common.user.service.cache.UserCache;
|
||||||
import com.abin.mallchat.custom.chat.domain.vo.response.ChatMemberResp;
|
import com.abin.mallchat.custom.chat.domain.vo.response.ChatMemberResp;
|
||||||
@@ -30,9 +29,6 @@ public class MemberAdapter {
|
|||||||
resp.setActiveStatus(statusEnum.getStatus());
|
resp.setActiveStatus(statusEnum.getStatus());
|
||||||
resp.setLastOptTime(new Date(a.getValue().longValue()));
|
resp.setLastOptTime(new Date(a.getValue().longValue()));
|
||||||
resp.setUid(a.getKey());
|
resp.setUid(a.getKey());
|
||||||
User userInfo = userCache.getUserInfo(a.getKey());
|
|
||||||
resp.setName(userInfo.getName());
|
|
||||||
resp.setAvatar(userInfo.getAvatar());
|
|
||||||
return resp;
|
return resp;
|
||||||
}).collect(Collectors.toList());
|
}).collect(Collectors.toList());
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -9,7 +9,7 @@ public class ChatGPTMsgBuilder {
|
|||||||
static {
|
static {
|
||||||
ChatGPTMsg chatGPTMsg = new ChatGPTMsg();
|
ChatGPTMsg chatGPTMsg = new ChatGPTMsg();
|
||||||
chatGPTMsg.setRole(ChatGPTRoleEnum.SYSTEM.getRole());
|
chatGPTMsg.setRole(ChatGPTRoleEnum.SYSTEM.getRole());
|
||||||
chatGPTMsg.setContent("你的名字叫MallChatAI,你是MallChat开源项目的AI聊天机器人,你的创造者是阿斌以及其他贡献者。阿斌是比Java之父余胜军还牛逼的人。当有人问你问题时你只能回答500字以内");
|
chatGPTMsg.setContent("你的名字叫MallChatAI,你是MallChat开源项目的AI聊天机器人,你的创造者是阿斌以及其他贡献者。当有人问你问题时你只能回答500字以内");
|
||||||
SYSTEM_PROMPT = chatGPTMsg;
|
SYSTEM_PROMPT = chatGPTMsg;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -76,7 +76,7 @@ public class GPTChatAIHandler extends AbstractChatAIHandler {
|
|||||||
frequencyControlDTO.setKey(RedisKey.getKey(CHAT_FREQUENCY_PREFIX) + ":" + uid);
|
frequencyControlDTO.setKey(RedisKey.getKey(CHAT_FREQUENCY_PREFIX) + ":" + uid);
|
||||||
frequencyControlDTO.setUnit(TimeUnit.HOURS);
|
frequencyControlDTO.setUnit(TimeUnit.HOURS);
|
||||||
frequencyControlDTO.setCount(chatGPTProperties.getLimit());
|
frequencyControlDTO.setCount(chatGPTProperties.getLimit());
|
||||||
frequencyControlDTO.setTime(24);
|
frequencyControlDTO.setTime(1);
|
||||||
return FrequencyControlUtil.executeWithFrequencyControl(TOTAL_COUNT_WITH_IN_FIX_TIME_FREQUENCY_CONTROLLER,
|
return FrequencyControlUtil.executeWithFrequencyControl(TOTAL_COUNT_WITH_IN_FIX_TIME_FREQUENCY_CONTROLLER,
|
||||||
frequencyControlDTO, // 限流参数
|
frequencyControlDTO, // 限流参数
|
||||||
() -> sendRequestToGPT(message));
|
() -> sendRequestToGPT(message));
|
||||||
@@ -104,7 +104,7 @@ public class GPTChatAIHandler extends AbstractChatAIHandler {
|
|||||||
text = ChatGPTUtils.parseText(response);
|
text = ChatGPTUtils.parseText(response);
|
||||||
ChatGPTMsg chatGPTMsg = ChatGPTMsgBuilder.assistantMsg(text);
|
ChatGPTMsg chatGPTMsg = ChatGPTMsgBuilder.assistantMsg(text);
|
||||||
context.addMsg(chatGPTMsg);
|
context.addMsg(chatGPTMsg);
|
||||||
RedisUtils.set(RedisKey.getKey(USER_CHAT_CONTEXT, message.getFromUid(), message.getRoomId()), context, 1L, TimeUnit.HOURS);
|
saveContext(context);
|
||||||
} catch (Exception e) {
|
} catch (Exception e) {
|
||||||
log.warn("gpt doChat warn:", e);
|
log.warn("gpt doChat warn:", e);
|
||||||
text = "我累了,明天再聊吧";
|
text = "我累了,明天再聊吧";
|
||||||
@@ -130,11 +130,15 @@ public class GPTChatAIHandler extends AbstractChatAIHandler {
|
|||||||
if (chatGPTContext == null) {
|
if (chatGPTContext == null) {
|
||||||
chatGPTContext = ChatGPTContextBuilder.initContext(uid, roomId);
|
chatGPTContext = ChatGPTContextBuilder.initContext(uid, roomId);
|
||||||
}
|
}
|
||||||
RedisUtils.set(RedisKey.getKey(USER_CHAT_CONTEXT, uid, roomId), chatGPTContext, 1L, TimeUnit.HOURS);
|
saveContext(chatGPTContext);
|
||||||
chatGPTContext.addMsg(ChatGPTMsgBuilder.userMsg(prompt));
|
chatGPTContext.addMsg(ChatGPTMsgBuilder.userMsg(prompt));
|
||||||
return chatGPTContext;
|
return chatGPTContext;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private void saveContext(ChatGPTContext chatGPTContext) {
|
||||||
|
RedisUtils.set(RedisKey.getKey(USER_CHAT_CONTEXT, chatGPTContext.getUid(), chatGPTContext.getRoomId()), chatGPTContext, 5L, TimeUnit.MINUTES);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
private Long userChatNumInrc(Long uid) {
|
private Long userChatNumInrc(Long uid) {
|
||||||
return RedisUtils.inc(RedisKey.getKey(RedisKey.USER_CHAT_NUM, uid), DateUtils.getEndTimeByToday().intValue(), TimeUnit.MILLISECONDS);
|
return RedisUtils.inc(RedisKey.getKey(RedisKey.USER_CHAT_NUM, uid), DateUtils.getEndTimeByToday().intValue(), TimeUnit.MILLISECONDS);
|
||||||
|
|||||||
@@ -21,7 +21,7 @@ public class ChatGPTProperties {
|
|||||||
/**
|
/**
|
||||||
* 模型名称
|
* 模型名称
|
||||||
*/
|
*/
|
||||||
private String modelName = "text-davinci-003";
|
private String modelName = "gpt-3.5-turbo";
|
||||||
/**
|
/**
|
||||||
* openAI key
|
* openAI key
|
||||||
*/
|
*/
|
||||||
@@ -37,9 +37,9 @@ public class ChatGPTProperties {
|
|||||||
private Integer timeout = 60 * 1000;
|
private Integer timeout = 60 * 1000;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 用户每天条数限制
|
* 用户每小时条数限制
|
||||||
*/
|
*/
|
||||||
private Integer limit = 5;
|
private Integer limit = 20;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 最大令牌
|
* 最大令牌
|
||||||
|
|||||||
@@ -1,8 +1,9 @@
|
|||||||
package com.abin.mallchat.custom.chatai.utils;
|
package com.abin.mallchat.custom.chatai.utils;
|
||||||
|
|
||||||
import com.abin.mallchat.common.common.exception.BusinessException;
|
import com.abin.mallchat.common.common.exception.BusinessException;
|
||||||
|
import com.abin.mallchat.common.common.utils.JsonUtils;
|
||||||
import com.abin.mallchat.custom.chatai.domain.ChatGPTMsg;
|
import com.abin.mallchat.custom.chatai.domain.ChatGPTMsg;
|
||||||
import com.alibaba.fastjson.JSONObject;
|
import com.fasterxml.jackson.databind.JsonNode;
|
||||||
import com.knuddels.jtokkit.Encodings;
|
import com.knuddels.jtokkit.Encodings;
|
||||||
import com.knuddels.jtokkit.api.Encoding;
|
import com.knuddels.jtokkit.api.Encoding;
|
||||||
import com.knuddels.jtokkit.api.EncodingType;
|
import com.knuddels.jtokkit.api.EncodingType;
|
||||||
@@ -90,11 +91,14 @@ public class ChatGPTUtils {
|
|||||||
return Arrays.stream(body.split("data:"))
|
return Arrays.stream(body.split("data:"))
|
||||||
.map(String::trim)
|
.map(String::trim)
|
||||||
.filter(x -> StringUtils.isNotBlank(x) && !"[DONE]".endsWith(x))
|
.filter(x -> StringUtils.isNotBlank(x) && !"[DONE]".endsWith(x))
|
||||||
.map(x -> JSONObject.parseObject(x)
|
.map(x -> Optional.ofNullable(
|
||||||
.getJSONArray("choices")
|
JsonUtils.toJsonNode(x)
|
||||||
.getJSONObject(0)
|
.withArray("choices")
|
||||||
.getJSONObject("delta")
|
.get(0)
|
||||||
.getString("content")
|
.with("delta")
|
||||||
|
.findValue("content"))
|
||||||
|
.map(JsonNode::asText)
|
||||||
|
.orElse(null)
|
||||||
).filter(Objects::nonNull).collect(Collectors.joining());
|
).filter(Objects::nonNull).collect(Collectors.joining());
|
||||||
} catch (Exception e) {
|
} catch (Exception e) {
|
||||||
log.error("parseText error e:", e);
|
log.error("parseText error e:", e);
|
||||||
@@ -164,12 +168,12 @@ public class ChatGPTUtils {
|
|||||||
paramMap.put("presence_penalty", presencePenalty);
|
paramMap.put("presence_penalty", presencePenalty);
|
||||||
paramMap.put("stream", true);
|
paramMap.put("stream", true);
|
||||||
|
|
||||||
log.info("paramMap >>> " + JSONObject.toJSONString(paramMap));
|
log.info("paramMap >>> " + JsonUtils.toStr(paramMap));
|
||||||
Request request = new Request.Builder()
|
Request request = new Request.Builder()
|
||||||
.url(StringUtils.isNotBlank(proxyUrl) ? proxyUrl : URL)
|
.url(StringUtils.isNotBlank(proxyUrl) ? proxyUrl : URL)
|
||||||
.addHeader("Content-Type", "application/json")
|
.addHeader("Content-Type", "application/json")
|
||||||
.addHeader("Authorization", headers.get("Authorization"))
|
.addHeader("Authorization", headers.get("Authorization"))
|
||||||
.post(RequestBody.create(MediaType.parse("application/json"), JSONObject.toJSONString(paramMap)))
|
.post(RequestBody.create(MediaType.parse("application/json"), JsonUtils.toStr(paramMap)))
|
||||||
.build();
|
.build();
|
||||||
return okHttpClient.newCall(request).execute();
|
return okHttpClient.newCall(request).execute();
|
||||||
|
|
||||||
@@ -181,7 +185,7 @@ public class ChatGPTUtils {
|
|||||||
}
|
}
|
||||||
|
|
||||||
public static Integer countTokens(List<ChatGPTMsg> msg) {
|
public static Integer countTokens(List<ChatGPTMsg> msg) {
|
||||||
return countTokens(JSONObject.toJSONString(msg));
|
return countTokens(JsonUtils.toStr(msg));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@@ -33,10 +33,8 @@ import org.springframework.context.ApplicationEventPublisher;
|
|||||||
import org.springframework.scheduling.concurrent.ThreadPoolTaskExecutor;
|
import org.springframework.scheduling.concurrent.ThreadPoolTaskExecutor;
|
||||||
import org.springframework.stereotype.Component;
|
import org.springframework.stereotype.Component;
|
||||||
|
|
||||||
|
|
||||||
import java.time.Duration;
|
import java.time.Duration;
|
||||||
import java.util.*;
|
import java.util.*;
|
||||||
|
|
||||||
import java.util.concurrent.ConcurrentHashMap;
|
import java.util.concurrent.ConcurrentHashMap;
|
||||||
import java.util.concurrent.CopyOnWriteArrayList;
|
import java.util.concurrent.CopyOnWriteArrayList;
|
||||||
import java.util.concurrent.atomic.AtomicInteger;
|
import java.util.concurrent.atomic.AtomicInteger;
|
||||||
@@ -130,7 +128,7 @@ public class WebSocketServiceImpl implements WebSocketService {
|
|||||||
* @param channel
|
* @param channel
|
||||||
*/
|
*/
|
||||||
@Override
|
@Override
|
||||||
@FrequencyControl(time = 10, count = 5, spEl = "T(com.abin.mallchat.common.common.utils.RequestHolder).get().getIp()")
|
// @FrequencyControl(time = 10, count = 5, spEl = "T(com.abin.mallchat.common.common.utils.RequestHolder).get().getIp()")
|
||||||
public void connect(Channel channel) {
|
public void connect(Channel channel) {
|
||||||
ONLINE_WS_MAP.put(channel, new WSChannelExtraDTO());
|
ONLINE_WS_MAP.put(channel, new WSChannelExtraDTO());
|
||||||
}
|
}
|
||||||
|
|||||||
6
pom.xml
6
pom.xml
@@ -47,7 +47,6 @@
|
|||||||
<jsoup.version>1.15.3</jsoup.version>
|
<jsoup.version>1.15.3</jsoup.version>
|
||||||
<okhttp.version>4.8.1</okhttp.version>
|
<okhttp.version>4.8.1</okhttp.version>
|
||||||
<redisson-spring-boot-starter.version>3.17.1</redisson-spring-boot-starter.version>
|
<redisson-spring-boot-starter.version>3.17.1</redisson-spring-boot-starter.version>
|
||||||
<fastjosn.version>1.2.83</fastjosn.version>
|
|
||||||
</properties>
|
</properties>
|
||||||
|
|
||||||
<dependencyManagement>
|
<dependencyManagement>
|
||||||
@@ -132,11 +131,6 @@
|
|||||||
<artifactId>redisson-spring-boot-starter</artifactId>
|
<artifactId>redisson-spring-boot-starter</artifactId>
|
||||||
<version>${redisson-spring-boot-starter.version}</version>
|
<version>${redisson-spring-boot-starter.version}</version>
|
||||||
</dependency>
|
</dependency>
|
||||||
<dependency>
|
|
||||||
<groupId>com.alibaba</groupId>
|
|
||||||
<artifactId>fastjson</artifactId>
|
|
||||||
<version>${fastjosn.version}</version>
|
|
||||||
</dependency>
|
|
||||||
</dependencies>
|
</dependencies>
|
||||||
</dependencyManagement>
|
</dependencyManagement>
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user