Browse Source

接口入deepseep api

tsurumure 6 months ago
parent
commit
5261f5728f

+ 7 - 0
pom.xml

@@ -388,6 +388,13 @@
             <artifactId>spring-boot-starter-thymeleaf</artifactId>
         </dependency>
 
+        <!-- Deepseek -->
+        <dependency>
+            <groupId>io.github.pig-mesh.ai</groupId>
+            <artifactId>deepseek-spring-boot-starter</artifactId>
+            <version>1.4.3</version>
+        </dependency>
+
     </dependencies>
 
 

+ 38 - 0
src/main/java/com/backendsys/modules/TestController.java

@@ -7,6 +7,7 @@ import cn.hutool.json.JSONUtil;
 
 import com.backendsys.aspect.RateLimiting;
 import com.backendsys.aspect.QueuingPoll;
+import com.backendsys.exception.CustException;
 import com.backendsys.service.TestService;
 import com.backendsys.utils.ResourceUtil;
 import com.fasterxml.jackson.core.JsonProcessingException;
@@ -16,6 +17,9 @@ import cn.afterturn.easypoi.word.WordExportUtil;
 import com.backendsys.utils.MD5Util;
 
 import com.tencentcloudapi.common.Credential;
+import io.github.pigmesh.ai.deepseek.core.DeepSeekClient;
+import io.github.pigmesh.ai.deepseek.core.OpenAiHttpException;
+import io.github.pigmesh.ai.deepseek.core.chat.ChatCompletionResponse;
 import jakarta.servlet.ServletContext;
 import org.apache.poi.xwpf.usermodel.XWPFDocument;
 import org.redisson.api.*;
@@ -23,6 +27,7 @@ import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.beans.factory.annotation.Value;
 import org.springframework.context.annotation.Lazy;
 import org.springframework.data.redis.core.RedisTemplate;
+import org.springframework.http.MediaType;
 import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;
 import org.springframework.web.bind.annotation.*;
 
@@ -53,6 +58,7 @@ import java.util.concurrent.TimeUnit;
 
 import com.tencentcloudapi.common.CommonClient;
 import com.tencentcloudapi.common.exception.TencentCloudSDKException;
+import reactor.core.publisher.Flux;
 
 
 @RestController
@@ -67,6 +73,38 @@ public class TestController {
     private String SECRET_KEY;
 
 
+//    @Autowired
+//    private DeepSeekClient deepSeekClient;
+//
+//    // https://javaai.pig4cloud.com/deepseek/quickstart
+//    // sse 流式返回
+//    @GetMapping(value = "/deepseek/chat", produces = MediaType.TEXT_EVENT_STREAM_VALUE)
+//    public Flux<ChatCompletionResponse> chat(String prompt) {
+//        try {
+//            Flux<ChatCompletionResponse> flux = deepSeekClient.chatFluxCompletion(prompt);
+//            return flux;
+//        } catch (OpenAiHttpException e) {
+//            throw new CustException(e.getMessage());
+//        }
+//    }
+
+//    // 进阶配置(多轮对话)
+//    @GetMapping(value = "/chat/advanced", produces = MediaType.TEXT_EVENT_STREAM_VALUE)
+//    public Flux<ChatCompletionResponse> advancedChat(String prompt) {
+//        ChatCompletionRequest request = ChatCompletionRequest.builder()
+//                .model(ChatCompletionModel.DEEPSEEK_REASONER)  // 指定推理模型
+//                .addUserMessage(prompt)                       // 用户当前问题
+//                .addAssistantMessage("上轮对话结果")            // 历史助手回复
+//                .addSystemMessage("你是一名AI助理")            // 系统角色设定
+//                .maxTokens(1000)                              // 最大生成 token 数
+//                .temperature(0.7)                             // 生成多样性控制
+//                .tools(yourFunctionTools)                     // Function Calling 工具
+//                .responseFormat(ChatResponseFormat.JSON)       // 结构化响应
+//                .build();
+//
+//        return deepSeekClient.chatFluxCompletion(request);
+//    }
+
 
     @Autowired
     private ServletContext servletContext;

+ 61 - 1
src/main/java/com/backendsys/modules/ai/deepSeek/controller/DeepSeekController.java

@@ -1,17 +1,30 @@
 package com.backendsys.modules.ai.deepSeek.controller;
 
+import cn.hutool.core.convert.Convert;
 import com.backendsys.modules.ai.deepSeek.entity.DeepSeekParam;
 import com.backendsys.modules.ai.deepSeek.utils.OllamaUtil;
 import com.backendsys.modules.common.config.security.utils.SecurityUtil;
 import com.backendsys.modules.common.utils.Result;
+import com.backendsys.modules.sse.entity.SseResponse;
+import com.backendsys.modules.sse.entity.SseResponseEnum;
+import com.backendsys.modules.sse.utils.SseUtil;
+import io.github.pigmesh.ai.deepseek.core.DeepSeekClient;
+import io.github.pigmesh.ai.deepseek.core.chat.AssistantMessage;
+import io.github.pigmesh.ai.deepseek.core.chat.ChatCompletionChoice;
+import io.github.pigmesh.ai.deepseek.core.chat.ChatCompletionResponse;
 import io.swagger.v3.oas.annotations.Operation;
 import io.swagger.v3.oas.annotations.tags.Tag;
 import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.beans.factory.annotation.Value;
 import org.springframework.security.access.prepost.PreAuthorize;
 import org.springframework.validation.annotation.Validated;
 import org.springframework.web.bind.annotation.PostMapping;
 import org.springframework.web.bind.annotation.RequestBody;
 import org.springframework.web.bind.annotation.RestController;
+import reactor.core.publisher.Flux;
+
+import java.util.List;
+import java.util.concurrent.CompletableFuture;
 
 @Validated
 @RestController
@@ -21,14 +34,61 @@ public class DeepSeekController {
     @Autowired
     private OllamaUtil ollamaUtil;
 
+    @Value("${spring.application.name}")
+    private String APPLICATION_NAME;
+    @Autowired
+    private SseUtil sseUtil;
+    @Autowired
+    private DeepSeekClient deepSeekClient;
+
+
+    /**
+     * deepseek4j
+     * https://javaai.pig4cloud.com/deepseek/quickstart
+     *
+     * deepseek开放平台
+     * https://platform.deepseek.com/
+     */
+
     @Operation(summary = "提问")
     @PreAuthorize("@sr.hasPermission('101')")
     @PostMapping("/api/deepSeek/ask")
     public Result ask(@Validated @RequestBody DeepSeekParam param) {
+
         Long userId = SecurityUtil.getUserId();
+        String emitterKey = APPLICATION_NAME + "-userid-" + Convert.toStr(userId);
+
+        Flux<ChatCompletionResponse> flux = deepSeekClient.chatFluxCompletion(param.getQuestion());
+        System.out.println(flux);
+
+//        // 创建一个 CompletableFuture 来执行异步任务
+//        CompletableFuture<Void> future = CompletableFuture.runAsync(() -> {
+//
+//            System.out.println("question: " + param.getQuestion());
+//
+//            System.out.println(flux);
+//
+//            flux.doOnNext(i -> {
+//                System.out.println("i.");
+//                List<ChatCompletionChoice> contentList = i.choices();
+//                contentList.stream().forEach(content -> {
+//                    AssistantMessage message = content.message();
+//                    System.out.println("message: " + message.content());
+//
+//                    // [SSE] 发送消息
+//                    String dataStr = (new SseResponse(SseResponseEnum.DEEPSEEK, message.content())).toJsonStr();
+//                    sseUtil.send(emitterKey, dataStr);
+//
+//                });
+//                // 其他ELT流程
+//            }).doOnError(e -> {
+//                System.out.println(e.getMessage());
+//            });
+//
+//        });
 
 //        ollamaUtil.chatDeepSeek("deepseek-r1:1.5b", param.getQuestion(), userId);
-        ollamaUtil.chatDeepSeek("deepseek-r1:7b", param.getQuestion(), userId);
+//        ollamaUtil.chatDeepSeek("deepseek-r1:7b", param.getQuestion(), userId);
 
         return Result.success();
     }

+ 4 - 1
src/main/resources/application-local.yml

@@ -164,4 +164,7 @@ baidu:
 ai:
   config:
     deepseek:
-      domain: http://localhost:11434
+      domain: http://localhost:11434
+
+deepseek:
+  api-key: sk-7614064f7e3343d786a2240672dd4d39

+ 4 - 1
src/main/resources/application-prod.yml

@@ -156,4 +156,7 @@ baidu:
 ai:
   config:
     deepseek:
-      domain: http://localhost:11434
+      domain: http://localhost:11434
+
+deepseek:
+  api-key: sk-7614064f7e3343d786a2240672dd4d39