diff --git a/src/main/java/cn/teammodel/ai/deepseek/DeepSeekClient.java b/src/main/java/cn/teammodel/ai/deepseek/DeepSeekClient.java index 1a3edd5..8fb16ad 100644 --- a/src/main/java/cn/teammodel/ai/deepseek/DeepSeekClient.java +++ b/src/main/java/cn/teammodel/ai/deepseek/DeepSeekClient.java @@ -2,18 +2,16 @@ package cn.teammodel.ai.deepseek; import cn.teammodel.common.ErrorCode; import cn.teammodel.config.exception.ServiceException; -import cn.teammodel.model.dto.ai.deepseek.ChatRequestDto; +import cn.teammodel.model.dto.ai.deepseek.ChatRequestOKHttpDto; import cn.teammodel.model.dto.ai.deepseek.ChatResponseDto; -import cn.teammodel.model.dto.ai.deepseek.MessageDto; +import cn.teammodel.model.dto.ai.deepseek.ChatReqDto; import cn.teammodel.utils.JsonUtil; -import com.alibaba.fastjson.JSON; -import com.alibaba.fastjson.TypeReference; import com.fasterxml.jackson.databind.ObjectMapper; import com.fasterxml.jackson.databind.type.TypeFactory; import com.google.gson.Gson; +import lombok.extern.slf4j.Slf4j; import okhttp3.*; import org.apache.http.HttpEntity; -import org.apache.http.client.HttpClient; import org.apache.http.client.methods.CloseableHttpResponse; import org.apache.http.client.methods.HttpPost; import org.apache.http.entity.ContentType; @@ -21,13 +19,16 @@ import org.apache.http.entity.StringEntity; import org.apache.http.impl.client.CloseableHttpClient; import org.apache.http.impl.client.HttpClients; import org.apache.http.util.EntityUtils; + import java.util.HashMap; import java.util.Map; import java.io.IOException; import java.io.InputStream; import java.util.*; +import java.util.concurrent.TimeUnit; +@Slf4j public class DeepSeekClient { private static final String API_Key; private static final String API_Url; @@ -52,15 +53,15 @@ public class DeepSeekClient { * 提问题 测试使用 * @param mssage */ - private static Map ask(MessageDto mssage) + private static Map ask(ChatReqDto mssage) { Map mapper = new HashMap<>(); //创建消息列表 - List msg = new ArrayList<>(); + List msg = new ArrayList<>(); msg.add(mssage); //构建请求头 - ChatRequestDto requestBody = new ChatRequestDto(); + ChatRequestOKHttpDto requestBody = new ChatRequestOKHttpDto(); requestBody.setModel(API_Model); requestBody.setMessages(msg); requestBody.setTemperature(0); @@ -84,10 +85,13 @@ public class DeepSeekClient { * @param requestBody * @return */ - public static ChatResponseDto SendRequests(ChatRequestDto requestBody) + public static ChatResponseDto SendRequests(ChatRequestOKHttpDto requestBody) { ChatResponseDto chatResponse = new ChatResponseDto(); - OkHttpClient client = new OkHttpClient().newBuilder().build(); + //OkHttpClient client = new OkHttpClient().newBuilder().connectTimeout(60, TimeUnit.SECONDS).build();//设置连接超时时间 1分钟 + OkHttpClient client = new OkHttpClient().newBuilder().build();//设置连接超时时间 1分钟 + + MediaType mediaType = MediaType.parse("application/json"); //String content = "{\n \"messages\": [\n {\n \"content\": \"You are a helpful assistant\",\n \"role\": \"system\"\n },\n {\n \"content\": \"Hi\",\n \"role\": \"user\"\n }\n ],\n \"model\": \"deepseek-chat\",\n \"frequency_penalty\": 0,\n \"max_tokens\": 2048,\n \"presence_penalty\": 0,\n \"response_format\": {\n \"type\": \"text\"\n },\n \"stop\": null,\n \"stream\": false,\n \"stream_options\": null,\n \"temperature\": 1,\n \"top_p\": 1,\n \"tools\": null,\n \"tool_choice\": \"none\",\n \"logprobs\": false,\n \"top_logprobs\": null\n}"; String content = JsonUtil.convertToJson(requestBody); @@ -133,7 +137,7 @@ public class DeepSeekClient { * @param requestBody * @return */ - public static Map SendRequest(ChatRequestDto requestBody) { + public static Map SendRequest(ChatRequestOKHttpDto requestBody) { Map mapper = new HashMap<>(); try (CloseableHttpClient httpClient = HttpClients.createDefault()) { // 创建HttpPost对象 diff --git a/src/main/java/cn/teammodel/controller/frontend/AiDeepSeekController.java b/src/main/java/cn/teammodel/controller/frontend/AiDeepSeekController.java index b0e3651..697fd18 100644 --- a/src/main/java/cn/teammodel/controller/frontend/AiDeepSeekController.java +++ b/src/main/java/cn/teammodel/controller/frontend/AiDeepSeekController.java @@ -1,15 +1,11 @@ package cn.teammodel.controller.frontend; import cn.teammodel.common.IdRequest; -import cn.teammodel.model.dto.ai.UpdateSessionDto; import cn.teammodel.model.dto.ai.deepseek.ChatResponseDto; -import cn.teammodel.model.dto.ai.deepseek.MessageDto; +import cn.teammodel.model.dto.ai.deepseek.ChatReqDto; import cn.teammodel.model.entity.TmdUserDetail; -import cn.teammodel.model.entity.ai.ChatSession; import cn.teammodel.model.entity.ai.DeepSeekSession; import cn.teammodel.model.entity.ai.DeepSeekSession.DeepSeekMessage; -import cn.teammodel.repository.ChatSessionRepository; -import cn.teammodel.repository.DeepSeekRepository; import cn.teammodel.security.utils.SecurityUtil; import cn.teammodel.service.DeepSeekService; import cn.teammodel.common.R; @@ -17,6 +13,7 @@ import cn.teammodel.service.DeepSeekSessionService; import io.swagger.annotations.Api; import io.swagger.annotations.ApiOperation; import org.springframework.web.bind.annotation.*; +import org.springframework.web.servlet.mvc.method.annotation.SseEmitter; import javax.annotation.Resource; import javax.validation.Valid; @@ -122,8 +119,19 @@ public class AiDeepSeekController { */ @PostMapping("chat") @ApiOperation("与deepseek的对话") - public R ChatCompletion(@RequestBody @Valid MessageDto messageDto) { + public R ChatCompletion(@RequestBody @Valid ChatReqDto messageDto) { ChatResponseDto chatResponse = deepSeekChatService.ChatAsk(messageDto); return R.success(chatResponse); } + + @PostMapping("chat/completion") + @ApiOperation("与 spark 的流式对话") + public SseEmitter chatCompletion(@RequestBody @Valid ChatReqDto messageDto) { + String userId = SecurityUtil.getLoginUser().getId(); + SseEmitter sseEmitter = new SseEmitter(); + return sseEmitter; + //return deepSeekChatService.ChatSeeEmitterAsk(messageDto, userId); + } + + } diff --git a/src/main/java/cn/teammodel/model/dto/ai/comment/ChatTeacherCommentDto.java b/src/main/java/cn/teammodel/model/dto/ai/comment/ChatTeacherCommentDto.java index c9412ff..54f85de 100644 --- a/src/main/java/cn/teammodel/model/dto/ai/comment/ChatTeacherCommentDto.java +++ b/src/main/java/cn/teammodel/model/dto/ai/comment/ChatTeacherCommentDto.java @@ -29,9 +29,24 @@ public class ChatTeacherCommentDto */ private String type; + /** + * 评语返回字数 + */ + private int size; + + /** + * 限制评语 + */ + private List limitTexts; + /** * 输入的文本 */ private String text; + /** + * 评语数据 + */ + private Object data; + } diff --git a/src/main/java/cn/teammodel/model/dto/ai/deepseek/MessageDto.java b/src/main/java/cn/teammodel/model/dto/ai/deepseek/ChatReqDto.java similarity index 85% rename from src/main/java/cn/teammodel/model/dto/ai/deepseek/MessageDto.java rename to src/main/java/cn/teammodel/model/dto/ai/deepseek/ChatReqDto.java index 9606fd8..1770b91 100644 --- a/src/main/java/cn/teammodel/model/dto/ai/deepseek/MessageDto.java +++ b/src/main/java/cn/teammodel/model/dto/ai/deepseek/ChatReqDto.java @@ -1,27 +1,30 @@ package cn.teammodel.model.dto.ai.deepseek; import io.swagger.annotations.ApiModelProperty; +import lombok.AllArgsConstructor; import lombok.Data; /** * 内部类定义请求/响应结构 */ @Data -public class MessageDto { - /** - * 角色 - */ - @ApiModelProperty("角色") - private String role; +@AllArgsConstructor +public class ChatReqDto { /** * 会话id */ @ApiModelProperty("会话id,没有则为空") private String sessionId; + + /** + * 角色 + */ + @ApiModelProperty("角色") + private String role; + /** * 提问内容 */ @ApiModelProperty("提问内容") private String content; - } diff --git a/src/main/java/cn/teammodel/model/dto/ai/deepseek/ChatRequestDto.java b/src/main/java/cn/teammodel/model/dto/ai/deepseek/ChatRequestOKHttpDto.java similarity index 92% rename from src/main/java/cn/teammodel/model/dto/ai/deepseek/ChatRequestDto.java rename to src/main/java/cn/teammodel/model/dto/ai/deepseek/ChatRequestOKHttpDto.java index 83784c7..20b845f 100644 --- a/src/main/java/cn/teammodel/model/dto/ai/deepseek/ChatRequestDto.java +++ b/src/main/java/cn/teammodel/model/dto/ai/deepseek/ChatRequestOKHttpDto.java @@ -2,8 +2,6 @@ package cn.teammodel.model.dto.ai.deepseek; import io.swagger.annotations.ApiModelProperty; import lombok.Data; -import lombok.Builder; -import lombok.Builder.Default; import java.util.List; @@ -39,11 +37,11 @@ import java.util.List; * } */ @Data -public class ChatRequestDto { +public class ChatRequestOKHttpDto { @ApiModelProperty("会话模型") private String model; @ApiModelProperty("会话内容") - private List messages; + private List messages; /** * 采样温度,介于 0 和 2 之间。更高的值,如 0.8,会使输出更随机,而更低的值,如 0.2,会使其更加集中和确定。 * 我们通常建议可以更改这个值或者更改 top_p,但不建议同时对两者进行修改。 diff --git a/src/main/java/cn/teammodel/model/dto/ai/deepseek/ChatResponseDto.java b/src/main/java/cn/teammodel/model/dto/ai/deepseek/ChatResponseDto.java index 6dbb681..82ffd8f 100644 --- a/src/main/java/cn/teammodel/model/dto/ai/deepseek/ChatResponseDto.java +++ b/src/main/java/cn/teammodel/model/dto/ai/deepseek/ChatResponseDto.java @@ -1,5 +1,9 @@ package cn.teammodel.model.dto.ai.deepseek; +import io.swagger.annotations.ApiModelProperty; +import lombok.AllArgsConstructor; +import lombok.Builder; +import lombok.Builder.Default; import lombok.Data; import java.util.List; @@ -25,9 +29,10 @@ public class ChatResponseDto { private List choices; private String system_fingerprint; @Data + @AllArgsConstructor public static class Choice { private int index; - private MessageDto message; + private DeepSeekMessage message; private String logprobs; private String finish_reason; } @@ -44,4 +49,18 @@ public class ChatResponseDto { public static class Prompt_Tokens_Details { private int cached_tokens; } + + @Data + public static class DeepSeekMessage{ + + /** + * 角色 + */ + private String role; + + /** + * 提问内容 + */ + private String content; + } } diff --git a/src/main/java/cn/teammodel/service/DeepSeekService.java b/src/main/java/cn/teammodel/service/DeepSeekService.java index 4184d42..5d53c70 100644 --- a/src/main/java/cn/teammodel/service/DeepSeekService.java +++ b/src/main/java/cn/teammodel/service/DeepSeekService.java @@ -1,10 +1,8 @@ package cn.teammodel.service; import cn.teammodel.model.dto.ai.deepseek.ChatResponseDto; -import cn.teammodel.model.dto.ai.deepseek.MessageDto; -import cn.teammodel.model.entity.ai.DeepSeekSession; - -import java.util.List; +import cn.teammodel.model.dto.ai.deepseek.ChatReqDto; +import reactor.core.publisher.Flux; /** * 访问DeepSeek方法 @@ -16,5 +14,5 @@ public interface DeepSeekService { * @param message * @return */ - ChatResponseDto ChatAsk(MessageDto message); + ChatResponseDto ChatAsk(ChatReqDto message); } diff --git a/src/main/java/cn/teammodel/service/impl/ChatMessageServiceImpl.java b/src/main/java/cn/teammodel/service/impl/ChatMessageServiceImpl.java index f29b430..ec3a9f0 100644 --- a/src/main/java/cn/teammodel/service/impl/ChatMessageServiceImpl.java +++ b/src/main/java/cn/teammodel/service/impl/ChatMessageServiceImpl.java @@ -115,7 +115,14 @@ public class ChatMessageServiceImpl implements ChatMessageService { // 目前仅使用讯飞星火大模型 String appId = chatTeacherCommentDto.getAppId(); // 获取模板文本 - String text = chatTeacherCommentDto.getText(); + String text = null; + if (chatTeacherCommentDto.getType().equals("text")) + { + text = chatTeacherCommentDto.getText(); + }else { + text = TeacherCommentTemplate(chatTeacherCommentDto); + } + if (!StringUtils.isEmpty(text)) { //chatCommentsDto.setText(text); } else { @@ -830,4 +837,62 @@ public class ChatMessageServiceImpl implements ChatMessageService { } } + /** + * 教师评语模版 + * @param chatTeacherCommentDto + * @return + */ + private String TeacherCommentTemplate(ChatTeacherCommentDto chatTeacherCommentDto) + { + try { + StringBuilder builder = new StringBuilder(); + String strData = JSON.toJSONString(chatTeacherCommentDto.getData()); + builder.append("请按照以下格式回复:\n"); + builder.append("1. 评语内容:\n"); + builder.append("2. 评语星级(1~5星):\n"); + + switch (chatTeacherCommentDto.getType()) { + //Ai评价 + case "AiAppraise": + break; + //专家评价 + case "ExpertAppraise": + builder.append(""); + break; + default: return ""; + + } + + + String limitChat = "。限制条件如下:##依据提供的数据做一个在%s字左右的评价;##直接返回评价的内容;##评价开头不允许出现特殊字符"; + int size = chatTeacherCommentDto.getSize() > 0 ? chatTeacherCommentDto.getSize() : 200; + builder.append(String.format(limitChat, size)); + + //用户自定义限制条件 + if (chatTeacherCommentDto.getLimitTexts() != null && !chatTeacherCommentDto.getLimitTexts().isEmpty()) { + int serialNumber = 5; //用户自定义限制条件数量标识 + List limitTexts = chatTeacherCommentDto.getLimitTexts(); //获取自定义限制条件内容 + int length = limitTexts.size(); //数组大小 + for (int i = 0; i < length; i++) { + String str = limitTexts.get(i); + //builder.append(serialNumber).append(".").append(str); + builder.append(";##").append(str); + if (i < length - 1) { + builder.append(";"); + }else { + builder.append("。"); + } + serialNumber += 1; + } + }else { + builder.append("。"); + } + + return builder.toString(); + }catch (Exception e) { + log.info(Arrays.toString(e.getStackTrace())); + log.error("{}-{}", e.getMessage(), Arrays.toString(e.getStackTrace())); + throw new ServiceException(ErrorCode.OPERATION_ERROR.getCode(), Arrays.toString(e.getStackTrace())); + } + } } diff --git a/src/main/java/cn/teammodel/service/impl/DeepSeekServiceImpl.java b/src/main/java/cn/teammodel/service/impl/DeepSeekServiceImpl.java index 9df8dfa..4d51c17 100644 --- a/src/main/java/cn/teammodel/service/impl/DeepSeekServiceImpl.java +++ b/src/main/java/cn/teammodel/service/impl/DeepSeekServiceImpl.java @@ -2,16 +2,15 @@ package cn.teammodel.service.impl; import cn.teammodel.ai.deepseek.DeepSeekClient; import cn.teammodel.common.PK; -import cn.teammodel.model.dto.ai.deepseek.ChatRequestDto; +import cn.teammodel.model.dto.ai.deepseek.ChatRequestOKHttpDto; import cn.teammodel.model.dto.ai.deepseek.ChatResponseDto; -import cn.teammodel.model.dto.ai.deepseek.MessageDto; +import cn.teammodel.model.dto.ai.deepseek.ChatReqDto; import cn.teammodel.model.entity.ai.DeepSeekSession; import cn.teammodel.model.entity.ai.DeepSeekSession.DeepSeekMessage; import cn.teammodel.repository.DeepSeekRepository; import cn.teammodel.security.utils.SecurityUtil; import cn.teammodel.service.DeepSeekService; import cn.teammodel.service.DeepSeekSessionService; -import lombok.extern.slf4j.Slf4j; import org.springframework.stereotype.Service; import javax.annotation.Resource; @@ -23,7 +22,6 @@ import java.util.*; * 描述:访问DeepSeek方法 */ @Service -@Slf4j public class DeepSeekServiceImpl implements DeepSeekService { @Resource private DeepSeekSessionService deepSeekService; @@ -37,13 +35,13 @@ public class DeepSeekServiceImpl implements DeepSeekService { * @return */ @Override - public ChatResponseDto ChatAsk(MessageDto message) { + public ChatResponseDto ChatAsk(ChatReqDto message) { //创建消息列表 - List msg = new ArrayList<>(); + List msg = new ArrayList<>(); msg.add(message); //构建请求头 - ChatRequestDto requestBody = new ChatRequestDto(); + ChatRequestOKHttpDto requestBody = new ChatRequestOKHttpDto(); requestBody.setModel(DeepSeekClient.API_Model); requestBody.setMessages(msg); requestBody.setTemperature(0); @@ -87,7 +85,7 @@ public class DeepSeekServiceImpl implements DeepSeekService { * @param savaMessage * @param response */ - private void UpdateSession(MessageDto message, DeepSeekSession session, DeepSeekMessage savaMessage, ChatResponseDto response) { + private void UpdateSession(ChatReqDto message, DeepSeekSession session, DeepSeekMessage savaMessage, ChatResponseDto response) { if (session.getId() == null){ List history = Collections.singletonList(savaMessage); String userId = SecurityUtil.getLoginUser().getId();