| @ -0,0 +1,15 @@ | |||
| package com.inspect.simulator.domain.bigmodelr; | |||
| import lombok.Data; | |||
| @Data | |||
| public class ApiResponse { | |||
| private String code; | |||
| private String message; | |||
| private Object data; | |||
| public ApiResponse(String code, String message) { | |||
| this.code = code; | |||
| this.message = message; | |||
| } | |||
| } | |||
| @ -0,0 +1,14 @@ | |||
| package com.inspect.simulator.domain.bigmodelr; | |||
| import com.fasterxml.jackson.annotation.JsonInclude; | |||
| import lombok.Data; | |||
| import java.util.List; | |||
| @Data | |||
| @JsonInclude(JsonInclude.Include.NON_NULL) | |||
| public class ChatCompletionRequest { | |||
| private String model; | |||
| private List<Message> messages; | |||
| private int maxTokens; | |||
| } | |||
| @ -0,0 +1,33 @@ | |||
| package com.inspect.simulator.domain.bigmodelr; | |||
| import com.fasterxml.jackson.annotation.JsonIgnoreProperties; | |||
| import com.fasterxml.jackson.annotation.JsonProperty; | |||
| import lombok.AllArgsConstructor; | |||
| import lombok.Data; | |||
| import lombok.NoArgsConstructor; | |||
| import java.util.List; | |||
| @Data | |||
| @AllArgsConstructor | |||
| @NoArgsConstructor | |||
| @JsonIgnoreProperties(ignoreUnknown = true) | |||
| public class ChatCompletionResponse { | |||
| private String id; | |||
| private String object; | |||
| private long created; | |||
| private List<Choice> choices; | |||
| private String info; | |||
| private Usage usage; | |||
| @JsonProperty("model") | |||
| private String model; | |||
| //存数据库 | |||
| private String content; | |||
| private String picPath; | |||
| } | |||
| @ -0,0 +1,13 @@ | |||
| package com.inspect.simulator.domain.bigmodelr; | |||
| import com.fasterxml.jackson.annotation.JsonIgnoreProperties; | |||
| import lombok.Data; | |||
| @Data | |||
| @JsonIgnoreProperties(ignoreUnknown = true) // 忽略所有未定义的字段 | |||
| public class Choice { | |||
| private int index; | |||
| private Message message; | |||
| private String finish_reason; | |||
| } | |||
| @ -0,0 +1,17 @@ | |||
| package com.inspect.simulator.domain.bigmodelr; | |||
| import com.fasterxml.jackson.annotation.JsonInclude; | |||
| import com.fasterxml.jackson.annotation.JsonProperty; | |||
| import lombok.Data; | |||
| @Data | |||
| public class Content { | |||
| private String type; // text/image_url | |||
| @JsonInclude(JsonInclude.Include.NON_NULL) | |||
| private String text; // type=text时使用 | |||
| @JsonInclude(JsonInclude.Include.NON_NULL) | |||
| @JsonProperty("image_url") | |||
| private ImageUrl imageUrl; // type=image_url时使用 | |||
| } | |||
| @ -0,0 +1,15 @@ | |||
| package com.inspect.simulator.domain.bigmodelr; | |||
| import com.fasterxml.jackson.annotation.JsonProperty; | |||
| import lombok.Data; | |||
| @Data | |||
| public class ContentItem { | |||
| private String type; // text/image_url/image_base64 | |||
| private String text; // type=text时使用 | |||
| @JsonProperty("image_url") | |||
| private ImageUrl imageUrl; // type=image_url时使用 | |||
| private String image; // type=image_base64时使用 | |||
| } | |||
| @ -0,0 +1,9 @@ | |||
| package com.inspect.simulator.domain.bigmodelr; | |||
| import lombok.Data; | |||
| @Data | |||
| public class ImageUrl { | |||
| private String url; | |||
| } | |||
| @ -0,0 +1,23 @@ | |||
| package com.inspect.simulator.domain.bigmodelr; | |||
| import com.fasterxml.jackson.annotation.JsonSetter; | |||
| import lombok.Data; | |||
| import java.util.List; | |||
| @Data | |||
| public class Message { | |||
| private String role; | |||
| // private List<Content> content; | |||
| private Object content; // 可以是 String 或 List<Content> | |||
| @JsonSetter("content") | |||
| public void setContent(Object content) { | |||
| if (content instanceof String) { | |||
| this.content = (String) content; | |||
| } else if (content instanceof List) { | |||
| this.content = (List<ContentItem>) content; | |||
| } | |||
| } | |||
| } | |||
| @ -0,0 +1,20 @@ | |||
| package com.inspect.simulator.domain.bigmodelr; | |||
| import lombok.AllArgsConstructor; | |||
| import lombok.Data; | |||
| import lombok.NoArgsConstructor; | |||
| @Data | |||
| @NoArgsConstructor | |||
| @AllArgsConstructor | |||
| public class Multimodal { | |||
| private String role; | |||
| private String imageType; | |||
| private String imageData; | |||
| private String model; | |||
| private String text; | |||
| private String imageName; | |||
| private int maxTokens; | |||
| } | |||
| @ -0,0 +1,10 @@ | |||
| package com.inspect.simulator.domain.bigmodelr; | |||
| import lombok.Data; | |||
| @Data | |||
| public class Usage { | |||
| private int prompt_tokens; | |||
| private int completion_tokens; | |||
| private int total_tokens; | |||
| } | |||
| @ -0,0 +1,26 @@ | |||
| package com.inspect.simulator.domain.bigmodelr; | |||
| import lombok.AllArgsConstructor; | |||
| import lombok.Data; | |||
| import lombok.NoArgsConstructor; | |||
| @Data | |||
| @NoArgsConstructor | |||
| @AllArgsConstructor | |||
| public class VisualModel { | |||
| //照片类型(url ,base64) | |||
| private String image_type; | |||
| //照片名称 | |||
| private String image_name; | |||
| //照片地址(http,https无鉴权) | |||
| private String image_url; | |||
| //照片base64 | |||
| private String image_base64; | |||
| private String stringData; | |||
| } | |||
| @ -0,0 +1,16 @@ | |||
| package com.inspect.simulator.service; | |||
| import com.inspect.simulator.domain.bigmodelr.Multimodal; | |||
| import com.inspect.simulator.domain.bigmodelr.VisualModel; | |||
| import java.util.List; | |||
| public interface ModelService { | |||
| //语义大模型 | |||
| public String semanticsModel(Multimodal multimodal); | |||
| } | |||
| @ -0,0 +1,142 @@ | |||
| package com.inspect.simulator.service.impl; | |||
| import com.fasterxml.jackson.annotation.JsonInclude; | |||
| import com.fasterxml.jackson.core.JsonProcessingException; | |||
| import com.fasterxml.jackson.databind.ObjectMapper; | |||
| import com.google.gson.Gson; | |||
| import com.inspect.simulator.domain.bigmodelr.*; | |||
| import com.inspect.simulator.service.ModelService; | |||
| import okhttp3.*; | |||
| import org.apache.commons.lang3.StringUtils; | |||
| import org.springframework.beans.factory.annotation.Value; | |||
| import org.springframework.stereotype.Service; | |||
| import javax.annotation.Resource; | |||
| import java.io.IOException; | |||
| import java.net.SocketTimeoutException; | |||
| import java.nio.file.Files; | |||
| import java.nio.file.Path; | |||
| import java.nio.file.Paths; | |||
| import java.text.SimpleDateFormat; | |||
| import java.util.*; | |||
| import java.util.concurrent.TimeUnit; | |||
| import java.util.stream.Collectors; | |||
| import java.util.stream.Stream; | |||
| @Service | |||
| public class ModelServiceImpl implements ModelService { | |||
| // 设置支持的图片文件扩展名 | |||
| private static final List<String> IMAGE_EXTENSIONS = Arrays.asList(".jpg", ".jpeg", ".png"); | |||
| private final ObjectMapper objectMapper = new ObjectMapper(); | |||
| private final OkHttpClient httpClient = new OkHttpClient.Builder() | |||
| .connectTimeout(40, TimeUnit.SECONDS) // 连接超时 | |||
| .readTimeout(60, TimeUnit.SECONDS) // 读取超时 | |||
| .writeTimeout(30, TimeUnit.SECONDS) // 写入超时 | |||
| .build(); | |||
| public ModelServiceImpl() { | |||
| // 设置JSON序列化时忽略null值 | |||
| objectMapper.setSerializationInclusion(JsonInclude.Include.NON_NULL); | |||
| } | |||
| //调用语义大模型接口 | |||
| public String semanticsModel(Multimodal multimodal){ | |||
| // 重试次数 | |||
| int maxRetries = 3; | |||
| int attempt = 0; | |||
| while (attempt < maxRetries) { | |||
| try { | |||
| // 构建请求JSON | |||
| ChatCompletionRequest request = buildRequestBody(multimodal); | |||
| System.out.println("创建json" + request.getClass()); | |||
| // 发送请求并获取响应 | |||
| ChatCompletionResponse response = semanticsModelResponse(request); | |||
| String content = String.valueOf(response.getChoices().get(0).getMessage().getContent()); | |||
| System.out.println("语义大模型返回结果:"+content); | |||
| return content; | |||
| } catch (IOException e) { | |||
| if (attempt == maxRetries) { | |||
| return "请求超时,请稍后重试"; | |||
| } | |||
| System.out.println("第" + attempt + "次尝试超时,准备重试..."); | |||
| try { | |||
| Thread.sleep(1000 * attempt); // 指数退避 | |||
| } catch (InterruptedException ie) { | |||
| Thread.currentThread().interrupt(); | |||
| } | |||
| } | |||
| } | |||
| return "请求处理失败"; | |||
| } | |||
| private ChatCompletionRequest buildRequestBody(Multimodal multimodal) { | |||
| ChatCompletionRequest request = new ChatCompletionRequest(); | |||
| // 设置模型名称,默认"SGGM-VL-74B-V1.2" | |||
| request.setModel(multimodal.getModel() != null ? multimodal.getModel() : "SGGM-VL-74B-V1.2"); | |||
| // 构建消息 | |||
| Message message = new Message(); | |||
| message.setRole(StringUtils.isNotBlank(multimodal.getRole()) ? multimodal.getRole() : "user"); | |||
| message.setContent(multimodal.getText()); | |||
| request.setMessages(Collections.singletonList(message)); | |||
| return request; | |||
| } | |||
| private ChatCompletionResponse semanticsModelResponse(ChatCompletionRequest request) throws IOException { | |||
| String requestBody; | |||
| try { | |||
| requestBody = objectMapper.writeValueAsString(request); | |||
| } catch (JsonProcessingException e) { | |||
| throw new IOException("请求体序列化失败", e); | |||
| } | |||
| Request httpRequest = new Request.Builder() | |||
| .url("http://25.80.45.92:18063/lmp-cloud-ias-server/api/llm/chat/completions") | |||
| .post(RequestBody.create(MediaType.parse("application/json"), requestBody)) | |||
| .addHeader("Authorization", "Bearer 54c1ae2c5fd54afe85e74d6fe9161f7f") | |||
| .addHeader("Content-Type", "application/json") | |||
| .build(); | |||
| try (Response response = httpClient.newCall(httpRequest).execute()) { | |||
| if (!response.isSuccessful()) { | |||
| String errorBody = response.body() != null ? response.body().string() : "无响应体"; | |||
| throw new IOException(String.format("请求失败,状态码: %d,错误信息: %s", response.code(), errorBody)); | |||
| } | |||
| String responseBody = response.body().string(); | |||
| System.out.println("语义大模型API响应内容: " + responseBody); | |||
| return objectMapper.readValue(responseBody, ChatCompletionResponse.class); | |||
| } catch (SocketTimeoutException e) { | |||
| throw new IOException("请求超时,请检查网络连接或增加超时时间", e); | |||
| } | |||
| } | |||
| } | |||