关于我的服务调用模型工厂推理测试

This commit is contained in:
limin 2025-01-13 10:39:27 +08:00
parent 5a6d95d47c
commit 1618038718
9 changed files with 194 additions and 0 deletions

View File

@ -12,6 +12,9 @@ import org.springframework.web.util.UriComponents;
import org.springframework.web.util.UriComponentsBuilder;
import javax.servlet.http.HttpServletRequest;
import java.io.BufferedReader;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.net.URI;
import java.nio.charset.Charset;
import java.util.Map;
@ -142,6 +145,14 @@ public class HttpUtils {
return response.body();
}
}
public static InputStream postStream(String url, Map<String, String> headers, String requestBody) {
try (HttpResponse response = HttpRequest.post(url)
.addHeaders(headers)
.body(requestBody)
.execute()) {
return response.bodyStream();
}
}
public static String postForm(String url, Map<String, String> headers, Map<String, Object> form) {
try (HttpResponse response = HttpRequest.post(url)

View File

@ -24,4 +24,6 @@ public class ChatReqVO {
private String prompt;
@Schema(description = "对话ID", requiredMode = Schema.RequiredMode.REQUIRED)
private String uuid;
@Schema(description = "系统提示语")
private String systemPrompt;
}

View File

@ -90,4 +90,6 @@ public class LLMBackendProperties {
private String modelFileList;
private String modelFileDownload;
private String aigcModelCompletions;
}

View File

@ -3,6 +3,8 @@ package cn.iocoder.yudao.module.llm.service.conversation;
import cn.iocoder.yudao.framework.common.util.json.JsonUtils;
import cn.iocoder.yudao.module.llm.controller.admin.datarefluxdata.vo.DataRefluxDataSaveReqVO;
import cn.iocoder.yudao.module.llm.dal.dataobject.basemodel.BaseModelDO;
import cn.iocoder.yudao.module.llm.dal.dataobject.modelservice.ModelServiceDO;
import cn.iocoder.yudao.module.llm.dal.mysql.modelservice.ModelServiceMapper;
import cn.iocoder.yudao.module.llm.service.basemodel.BaseModelService;
import cn.iocoder.yudao.module.llm.service.datarefluxdata.DataRefluxDataService;
import cn.iocoder.yudao.module.llm.service.http.ModelService;
@ -28,6 +30,7 @@ import cn.iocoder.yudao.module.llm.dal.mysql.conversation.ConversationMapper;
import static cn.iocoder.yudao.framework.common.exception.util.ServiceExceptionUtil.exception;
import static cn.iocoder.yudao.module.llm.enums.ErrorCodeConstants.*;
import static cn.iocoder.yudao.module.llm.service.http.ModelService.PRIVATE_MODEL_ID;
/**
* 大模型对话记录 Service 实现类
@ -48,6 +51,8 @@ public class ConversationServiceImpl implements ConversationService {
private BaseModelService baseModelService;
@Resource
private DataRefluxDataService dataRefluxDataService;
@Resource
private ModelServiceMapper modelServiceMapper;
// 聊天会话历史记录缓存Key
private final static String CHAT_HIStORY_REDIS_KEY = "llm:chat:history";
@ -98,6 +103,20 @@ public class ConversationServiceImpl implements ConversationService {
@Override
public ChatRespVO chat(ChatReqVO chatReqVO) {
if (Objects.equals(1, chatReqVO.getModelType())){
return publicModelChat(chatReqVO);
}else {
return privateModelChat(chatReqVO);
}
}
/**
* 公共模型聊天
* @param chatReqVO
* @return
*/
public ChatRespVO publicModelChat(ChatReqVO chatReqVO) {
if (StringUtils.isBlank(chatReqVO.getUuid())) {
// 如果没有uuid就生成一个
chatReqVO.setUuid(UUID.randomUUID().toString());
@ -143,4 +162,70 @@ public class ConversationServiceImpl implements ConversationService {
dataRefluxDataService.saveDataRefluxData(dataRefluxDataSaveReqVO);
return chatRespVO;
}
/**
* 私有模型聊天
* @param chatReqVO
* @return
*/
private ChatRespVO privateModelChat(ChatReqVO chatReqVO) {
if (StringUtils.isBlank(chatReqVO.getUuid())) {
// 如果没有uuid就生成一个
chatReqVO.setUuid(UUID.randomUUID().toString());
}
String model = null;
if (Objects.equals(0, chatReqVO.getModelType())) {
// 模型管理
ModelServiceDO modelServiceDO = modelServiceMapper.selectById(chatReqVO.getModelId());
if (modelServiceDO == null) {
throw exception(MODEL_SERVICE_NOT_EXISTS);
}
model = modelServiceDO.getServiceName();
}
ModelCompletionsReqVO.ModelCompletionsMessage message = new ModelCompletionsReqVO.ModelCompletionsMessage();
message.setRole("user");
message.setContent(chatReqVO.getPrompt());
List<String> messageHistoryList = stringRedisTemplate.opsForList().range(CHAT_HIStORY_REDIS_KEY + ":" + chatReqVO.getUuid(), 0, -1);
List<ModelCompletionsReqVO.ModelCompletionsMessage> messages = new ArrayList<>();
if (messageHistoryList != null && !messageHistoryList.isEmpty()) {
for (String messageHistory : messageHistoryList) {
ModelCompletionsReqVO.ModelCompletionsMessage modelCompletionsMessage = JsonUtils.parseObject(messageHistory, ModelCompletionsReqVO.ModelCompletionsMessage.class);
if (modelCompletionsMessage.getRole().equals("system")){
modelCompletionsMessage.setContent(StringUtils.isNotBlank(chatReqVO.getSystemPrompt())? chatReqVO.getSystemPrompt():"");
stringRedisTemplate.opsForList().set(CHAT_HIStORY_REDIS_KEY+ ":" + chatReqVO.getUuid(), 0, JsonUtils.toJsonString(modelCompletionsMessage));
}
messages.add(modelCompletionsMessage);
}
}else {
ModelCompletionsReqVO.ModelCompletionsMessage systemMessage = new ModelCompletionsReqVO.ModelCompletionsMessage();
systemMessage.setRole("system");
systemMessage.setContent(StringUtils.isNotBlank(chatReqVO.getSystemPrompt())? chatReqVO.getSystemPrompt():"");
stringRedisTemplate.opsForList().rightPush(CHAT_HIStORY_REDIS_KEY + ":" + chatReqVO.getUuid(), JsonUtils.toJsonString(systemMessage));
messages.add(systemMessage);
}
messages.add(message);
ModelCompletionsReqVO modelCompletionsReqVO = new ModelCompletionsReqVO();
modelCompletionsReqVO.setMessages(messages);
// TODO 先传固定的内容 后期和后端调通直接修改成 model
modelCompletionsReqVO.setModel(PRIVATE_MODEL_ID);
ModelCompletionsRespVO modelCompletionsRespVO = modelService.modelPrivateCompletions(new HashMap<>(),modelCompletionsReqVO);
if (modelCompletionsRespVO == null) {
throw exception(MODEL_COMPLETIONS_ERROR);
}
ChatRespVO chatRespVO = BeanUtils.toBean(chatReqVO, ChatRespVO.class);
chatRespVO.setResponse(modelCompletionsRespVO.getAnswer());
stringRedisTemplate.opsForList().rightPush(CHAT_HIStORY_REDIS_KEY + ":" + chatReqVO.getUuid(), JsonUtils.toJsonString(message));
ModelCompletionsReqVO.ModelCompletionsMessage responseMessage = new ModelCompletionsReqVO.ModelCompletionsMessage();
responseMessage.setRole("assistant");
responseMessage.setContent(modelCompletionsRespVO.getAnswer());
stringRedisTemplate.opsForList().rightPush(CHAT_HIStORY_REDIS_KEY + ":" + chatReqVO.getUuid(), JsonUtils.toJsonString(responseMessage));
DataRefluxDataSaveReqVO dataRefluxDataSaveReqVO = new DataRefluxDataSaveReqVO();
dataRefluxDataSaveReqVO.setModelServiceId(chatReqVO.getModelId());
dataRefluxDataSaveReqVO.setModelType(chatReqVO.getModelType());
dataRefluxDataSaveReqVO.setPrompt(chatReqVO.getPrompt());
dataRefluxDataSaveReqVO.setResponse(modelCompletionsRespVO.getAnswer());
dataRefluxDataSaveReqVO.setSystem(modelCompletionsRespVO.getSystem());
dataRefluxDataService.saveDataRefluxData(dataRefluxDataSaveReqVO);
return chatRespVO;
}
}

View File

@ -6,11 +6,17 @@ import cn.iocoder.yudao.module.llm.framework.backend.config.LLMBackendProperties
import cn.iocoder.yudao.module.llm.service.http.vo.*;
import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.fasterxml.jackson.core.type.TypeReference;
import com.fasterxml.jackson.databind.ObjectMapper;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.springframework.stereotype.Service;
import javax.annotation.Resource;
import java.io.BufferedReader;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.util.List;
import java.util.Map;
@ -19,9 +25,12 @@ import java.util.Map;
public class ModelService {
public final static String DEFAULT_MODEL_ID = "qwen2.5-instruct";
public final static String PRIVATE_MODEL_ID = "llama3.1";
@Resource
private LLMBackendProperties llmBackendProperties;
@Resource
private TrainHttpService trainHttpService;
/**
* 获取模型列表
@ -87,4 +96,42 @@ public class ModelService {
return JSONArray.parseArray(res, String.class);
}
public ModelCompletionsRespVO modelPrivateCompletions(Map<String, String> headers,ModelCompletionsReqVO req) {
trainHttpService.login(headers);
if (StringUtils.isBlank(req.getModel())) {
req.setModel(PRIVATE_MODEL_ID);
}
log.info("url: {}", llmBackendProperties.getAigcModelCompletions());
log.info("request: {}", req);
/* String result = HttpUtils.postStream(llmBackendProperties.getAigcModelCompletions(), headers, JSON.toJSONString(req));
log.info("response: {}", result);
if (StringUtils.isBlank(result)) {
return null;
}*/
try {
StringBuilder fullContent = new StringBuilder();
try (InputStream inputStream = HttpUtils.postStream(llmBackendProperties.getAigcModelCompletions(), headers, JSON.toJSONString(req));
BufferedReader reader = new BufferedReader(new InputStreamReader(inputStream))) {
String line;
while ((line = reader.readLine()) != null) {
JSONObject jsonObject = JSON.parseObject(line);
if (jsonObject.getBoolean("success")) {
AigcRespChatVO aigcRespVO = jsonObject.toJavaObject(AigcRespChatVO.class);
if (aigcRespVO.getData().size() != 0) {
AigcChatCompletion chatCompletion = aigcRespVO.getData().get(aigcRespVO.getData().size() - 1);
fullContent.append(chatCompletion.getContent());
}
}
}
}
ModelCompletionsRespVO respVO = new ModelCompletionsRespVO();
respVO.setSystem("助手");
respVO.setQuestion(req.getMessages().get(req.getMessages().size() - 1).getContent());
respVO.setAnswer(fullContent.toString());
return respVO;
} catch (Exception e) {
e.printStackTrace();
return null;
}
}
}

View File

@ -0,0 +1,24 @@
package cn.iocoder.yudao.module.llm.service.http.vo;
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;
@Data
@AllArgsConstructor
@NoArgsConstructor
public class AigcChatCompletion {
/**
* 聊天返回内容
*/
private String fullContent;
private String content;
private String createAt;
private String finishReason;
private String contentType;
private String messageId;
private String model;
private Integer topP;
private Integer temperature;
private Integer maxTokens;
}

View File

@ -0,0 +1,19 @@
package cn.iocoder.yudao.module.llm.service.http.vo;
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;
import java.util.List;
@Data
@AllArgsConstructor
@NoArgsConstructor
public class AigcRespChatVO {
private boolean success;
private int code;
private List<AigcChatCompletion> data;
private String message;
private String traceId;
}

View File

@ -259,6 +259,8 @@ llm:
model_completions: http://api.xhllm.xinnuojinzhi.com/model/v1/chat/completions
# aigc表数据查询接口
table_data_query: http://36.133.1.230:5123/table/%s
# aigc模型推理
aigc_model_completions: http://36.133.1.230:8080/api/channels/chat/completions
application_api: http://localhost:48100/admin-app/llm/application/api/apiKey/chat

View File

@ -301,6 +301,8 @@ llm:
model_completions: http://api.xhllm.xinnuojinzhi.com/model/v1/chat/completions
# aigc表数据查询接口
table_data_query: http://36.133.1.230:5123/table/%s
# aigc模型推理
aigc_model_completions: http://36.133.1.230:8080/api/channels/chat/completions
application_api: http://localhost:48080/admin-app/llm/application/api/apiKey/chat