package com.njuzr.eaibackend.service; import com.fasterxml.jackson.annotation.JsonProperty; import com.njuzr.eaibackend.exception.MyException; import com.njuzr.eaibackend.po.AIEntry; import com.njuzr.eaibackend.utils.WebClientUtil; import lombok.AllArgsConstructor; import lombok.Data; import lombok.extern.slf4j.Slf4j; import org.springframework.beans.factory.annotation.Value; import org.springframework.http.HttpStatus; import org.springframework.stereotype.Service; import java.util.List; /** * @author: Leonezhurui * @Date: 2024/3/2 - 00:00 * @Package: EAI-Backend */ @Slf4j @Service public class AIRequestService { @Value("${openai.chatgpt.model}") private String model; @Value("${openai.chatgpt.api.key}") private String key; private final WebClientUtil chatgptClient; private final WebClientUtil chatglmClient; private final WebClientUtil qwenClient; private final String prefix = "/v1/chat/completions"; @Value("${config.llm.ChatGLM3.url}") private String glm3Url; @Value("${config.llm.ChatGLM4.url}") private String glm4Url; @Value("${config.llm.ChatGLM4.token}") private String glm4Token; @Value("${config.llm.ChatGLM4.modelName}") private String glm4ModelName; @Value("${config.llm.QWen14B.url}") private String qWen14BUrl; @Value("${config.llm.PreSentenceWorkflowChatGLM4.url}") private String preSentenceWorkflowglm4Url; @Value("${config.llm.PreSentenceWorkflowChatGLM4.token}") private String preSentenceWorkflowglm4Token; public AIRequestService(WebClientUtil chatgptClient, WebClientUtil chatglmClient, WebClientUtil qwenClient) { this.chatgptClient = chatgptClient; this.chatglmClient = chatglmClient; this.qwenClient = qwenClient; } public AIResponse requestChatGPT(List messages) { MyRequestObject requestObject = new MyRequestObject(model, messages,0.7); String chatgptUrl = "https://api.openai.com"; try { return chatgptClient.postWithToken(chatgptUrl+prefix, requestObject, AIResponse.class, key); } catch (Exception e) { log.error("WebClient请求失败,AI请求失败~"); throw new MyException(HttpStatus.INTERNAL_SERVER_ERROR.value(), HttpStatus.INTERNAL_SERVER_ERROR.getReasonPhrase()+":"+"服务器请求AI出错"); } } public AIResponse requestChatGLM(List messages) { MyRequestObject requestObject = new MyRequestObject("ChatGLM3", messages,0.7); String url = glm3Url; try { return chatglmClient.post(url+prefix, requestObject, AIResponse.class); } catch (Exception e) { log.error("WebClient请求失败,AI请求失败~"); throw new MyException(HttpStatus.INTERNAL_SERVER_ERROR.value(), HttpStatus.INTERNAL_SERVER_ERROR.getReasonPhrase()+":"+"服务器请求AI出错"); } } public AIResponse requestChatGLM4(List messages) { MyRequestObject requestObject = new MyRequestObject(glm4ModelName, messages,0.7); String url = glm4Url; try { return chatglmClient.postWithToken(url+prefix, requestObject, AIResponse.class, glm4Token); } catch (Exception e) { e.printStackTrace(); log.error("WebClient请求失败,AI请求失败~"+e.getMessage()); throw new MyException(HttpStatus.INTERNAL_SERVER_ERROR.value(), HttpStatus.INTERNAL_SERVER_ERROR.getReasonPhrase()+":"+"服务器请求AI出错"); } } public AIResponse requestQWen(List messages) { MyRequestObject requestObject = new MyRequestObject("QWen14B", messages,0.7); String url = qWen14BUrl; try { return qwenClient.post(url+prefix, requestObject, AIResponse.class); } catch (Exception e) { log.error("WebClient请求失败,AI请求失败~"); throw new MyException(HttpStatus.INTERNAL_SERVER_ERROR.value(), HttpStatus.INTERNAL_SERVER_ERROR.getReasonPhrase()+":"+"服务器请求AI出错"); } } public WorkflowRunResponse requestPreSentenceWorkflowWithRetry(String content, String assignmentDescription, String sentence) { int retry = 0; while (retry < 3) { WorkflowRunResponse response = requestPreSentenceWorkflow(content, assignmentDescription, sentence); if (response == null) { log.error("requestPreSentenceWorkflowWithRetry failed, retry: {}/{}", retry+1, 3); retry++; continue; } return response; } throw new MyException(HttpStatus.INTERNAL_SERVER_ERROR.value(), HttpStatus.INTERNAL_SERVER_ERROR.getReasonPhrase()+"AI请求失败"); } public WorkflowRunResponse requestPreSentenceWorkflow(String content, String assignmentDescription, String sentence) { MyWorkflowRequestInput input = new MyWorkflowRequestInput(content, assignmentDescription,sentence); MyWorkflowRequestObject requestObject = new MyWorkflowRequestObject("abc-1234", "blocking", input); String url = preSentenceWorkflowglm4Url; try { return chatglmClient.postWithToken(url, requestObject, WorkflowRunResponse.class, preSentenceWorkflowglm4Token); } catch (Exception e) { log.error("requestPreSentenceWorkflow failed, reason: {}", e.getMessage()); return null; } } @Data @AllArgsConstructor static class MyWorkflowRequestObject { private String user; private String response_mode; private MyWorkflowRequestInput inputs; } @Data @AllArgsConstructor static class MyWorkflowRequestInput { private String content; private String assignment_description; private String sentence; } @Data static class WorkflowRunResponse { private String task_id; private String workflow_run_id; private WorkflowRunData data; } @Data static class WorkflowRunData { private String id; private String workflow_id; private String status; private Outputs outputs; private Object error; private double elapsed_time; private int total_tokens; private int total_steps; private long created_at; private long finished_at; } @Data static class Outputs { private String result_type; private String result_category; private String result_content; } @Data @AllArgsConstructor static class MyRequestObject { private String model; private List messages; private Double temperature; } @Data public static class AIResponse { private String id; private List choices; private Long created; private String model; private String object; private String system_fingerprint; private Usage usage; } @Data public static class Choice { private String finish_reason; private int index; private String logprobs; private ResponseMessage message; } @Data public static class ResponseMessage { private String content; // AI生成的回复 private String role; private String function_call; private List tool_calls; } @Data public static class Usage { private int completion_tokens; private int prompt_tokens; private int total_tokens; } }