Quellcode durchsuchen

【代码优化】AI:适配 Spring AI 1.0.6 对 OpenAI 的逻辑

YunaiV vor 5 Monaten
Ursprung
Commit
5655ae925c

+ 2 - 2
yudao-module-ai/yudao-module-ai-biz/src/main/java/cn/iocoder/yudao/module/ai/service/chat/AiChatMessageServiceImpl.java

@@ -98,7 +98,7 @@ public class AiChatMessageServiceImpl implements AiChatMessageService {
         ChatResponse chatResponse = chatModel.call(prompt);
 
         // 3.4 段式返回
-        String newContent = chatResponse.getResult().getOutput().getContent();
+        String newContent = chatResponse.getResult().getOutput().getText();
         chatMessageMapper.updateById(new AiChatMessageDO().setId(assistantMessage.getId()).setSegmentIds(convertList(segmentList, AiKnowledgeSegmentDO::getId)).setContent(newContent));
         return new AiChatMessageSendRespVO().setSend(BeanUtils.toBean(userMessage, AiChatMessageSendRespVO.Message.class))
                 .setReceive(BeanUtils.toBean(assistantMessage, AiChatMessageSendRespVO.Message.class).setContent(newContent));
@@ -136,7 +136,7 @@ public class AiChatMessageServiceImpl implements AiChatMessageService {
         // TODO 注意:Schedulers.immediate() 目的是,避免默认 Schedulers.parallel() 并发消费 chunk 导致 SSE 响应前端会乱序问题
         StringBuffer contentBuffer = new StringBuffer();
         return streamResponse.map(chunk -> {
-            String newContent = chunk.getResult() != null ? chunk.getResult().getOutput().getContent() : null;
+            String newContent = chunk.getResult() != null ? chunk.getResult().getOutput().getText() : null;
             newContent = StrUtil.nullToDefault(newContent, ""); // 避免 null 的 情况
             contentBuffer.append(newContent);
             // 响应结果

+ 3 - 3
yudao-module-ai/yudao-module-ai-biz/src/main/java/cn/iocoder/yudao/module/ai/service/knowledge/AiKnowledgeDocumentServiceImpl.java

@@ -60,7 +60,7 @@ public class AiKnowledgeDocumentServiceImpl implements AiKnowledgeDocumentServic
         List<Document> documents = loader.get();
         Document document = CollUtil.getFirst(documents);
         // 1.2 文档记录入库
-        String content = document.getContent();
+        String content = document.getText();
         AiKnowledgeDocumentDO documentDO = BeanUtils.toBean(createReqVO, AiKnowledgeDocumentDO.class)
                 .setTokens(tokenCountEstimator.estimate(content)).setWordCount(content.length())
                 .setStatus(CommonStatusEnum.ENABLE.getStatus()).setSliceStatus(AiKnowledgeDocumentStatusEnum.SUCCESS.getStatus());
@@ -77,9 +77,9 @@ public class AiKnowledgeDocumentServiceImpl implements AiKnowledgeDocumentServic
         List<Document> segments = tokenTextSplitter.apply(documents);
         // 2.2 分段内容入库
         List<AiKnowledgeSegmentDO> segmentDOList = CollectionUtils.convertList(segments,
-                segment -> new AiKnowledgeSegmentDO().setContent(segment.getContent()).setDocumentId(documentId)
+                segment -> new AiKnowledgeSegmentDO().setContent(segment.getText()).setDocumentId(documentId)
                         .setKnowledgeId(createReqVO.getKnowledgeId()).setVectorId(segment.getId())
-                        .setTokens(tokenCountEstimator.estimate(segment.getContent())).setWordCount(segment.getContent().length())
+                        .setTokens(tokenCountEstimator.estimate(segment.getText())).setWordCount(segment.getText().length())
                         .setStatus(CommonStatusEnum.ENABLE.getStatus()));
         segmentMapper.insertBatch(segmentDOList);
 

+ 6 - 4
yudao-module-ai/yudao-module-ai-biz/src/main/java/cn/iocoder/yudao/module/ai/service/knowledge/AiKnowledgeSegmentServiceImpl.java

@@ -106,10 +106,12 @@ public class AiKnowledgeSegmentServiceImpl implements AiKnowledgeSegmentService
         VectorStore vectorStore = apiKeyService.getOrCreateVectorStore(model.getKeyId());
 
         // 3.1 向量检索
-        List<Document> documentList = vectorStore.similaritySearch(SearchRequest.query(reqVO.getContent())
-                .withTopK(knowledge.getTopK())
-                .withSimilarityThreshold(knowledge.getSimilarityThreshold())
-                .withFilterExpression(new FilterExpressionBuilder().eq(AiKnowledgeSegmentDO.FIELD_KNOWLEDGE_ID, reqVO.getKnowledgeId()).build()));
+        List<Document> documentList = vectorStore.similaritySearch(SearchRequest.builder()
+                .query(reqVO.getContent())
+                .topK(knowledge.getTopK())
+                .similarityThreshold(knowledge.getSimilarityThreshold())
+                .filterExpression(new FilterExpressionBuilder().eq(AiKnowledgeSegmentDO.FIELD_KNOWLEDGE_ID, reqVO.getKnowledgeId()).build())
+                .build());
         if (CollUtil.isEmpty(documentList)) {
             return ListUtil.empty();
         }

+ 1 - 1
yudao-module-ai/yudao-module-ai-biz/src/main/java/cn/iocoder/yudao/module/ai/service/mindmap/AiMindMapServiceImpl.java

@@ -85,7 +85,7 @@ public class AiMindMapServiceImpl implements AiMindMapService {
         // 3.2 流式返回
         StringBuffer contentBuffer = new StringBuffer();
         return streamResponse.map(chunk -> {
-            String newContent = chunk.getResult() != null ? chunk.getResult().getOutput().getContent() : null;
+            String newContent = chunk.getResult() != null ? chunk.getResult().getOutput().getText() : null;
             newContent = StrUtil.nullToDefault(newContent, ""); // 避免 null 的 情况
             contentBuffer.append(newContent);
             // 响应结果

+ 1 - 1
yudao-module-ai/yudao-module-ai-biz/src/main/java/cn/iocoder/yudao/module/ai/service/write/AiWriteServiceImpl.java

@@ -92,7 +92,7 @@ public class AiWriteServiceImpl implements AiWriteService {
         // 3.2 流式返回
         StringBuffer contentBuffer = new StringBuffer();
         return streamResponse.map(chunk -> {
-            String newContent = chunk.getResult() != null ? chunk.getResult().getOutput().getContent() : null;
+            String newContent = chunk.getResult() != null ? chunk.getResult().getOutput().getText() : null;
             newContent = StrUtil.nullToDefault(newContent, ""); // 避免 null 的 情况
             contentBuffer.append(newContent);
             // 响应结果

+ 10 - 5
yudao-module-ai/yudao-spring-boot-starter-ai/src/test/java/cn/iocoder/yudao/framework/ai/chat/OpenAIChatModelTests.java

@@ -22,11 +22,16 @@ import java.util.List;
  */
 public class OpenAIChatModelTests {
 
-    private final OpenAiApi openAiApi = new OpenAiApi(
-            "https://api.holdai.top",
-            "sk-dZEPiVaNcT3FHhef51996bAa0bC74806BeAb620dA5Da10Bf");
-    private final OpenAiChatModel chatModel = new OpenAiChatModel(openAiApi,
-            OpenAiChatOptions.builder().model(OpenAiApi.ChatModel.GPT_4_O).build());
+    private static final OpenAiChatModel chatModel = OpenAiChatModel.builder()
+            .openAiApi(OpenAiApi.builder()
+                    .baseUrl("https://api.holdai.top")
+                    .apiKey("sk-aN6nWn3fILjrgLFT0fC4Aa60B72e4253826c77B29dC94f17") // apiKey
+                    .build())
+            .defaultOptions(OpenAiChatOptions.builder()
+                    .model(OpenAiApi.ChatModel.GPT_4_O) // 模型
+                    .temperature(0.7)
+                    .build())
+            .build();
 
     @Test
     @Disabled

+ 7 - 5
yudao-module-ai/yudao-spring-boot-starter-ai/src/test/java/cn/iocoder/yudao/framework/ai/image/OpenAiImageModelTests.java

@@ -5,8 +5,11 @@ import org.junit.jupiter.api.Test;
 import org.springframework.ai.image.ImageOptions;
 import org.springframework.ai.image.ImagePrompt;
 import org.springframework.ai.image.ImageResponse;
+import org.springframework.ai.openai.OpenAiChatModel;
+import org.springframework.ai.openai.OpenAiChatOptions;
 import org.springframework.ai.openai.OpenAiImageModel;
 import org.springframework.ai.openai.OpenAiImageOptions;
+import org.springframework.ai.openai.api.OpenAiApi;
 import org.springframework.ai.openai.api.OpenAiImageApi;
 import org.springframework.web.client.RestClient;
 
@@ -17,11 +20,10 @@ import org.springframework.web.client.RestClient;
  */
 public class OpenAiImageModelTests {
 
-    private final OpenAiImageApi imageApi = new OpenAiImageApi(
-            "https://api.holdai.top",
-            "sk-dZEPiVaNcT3FHhef51996bAa0bC74806BeAb620dA5Da10Bf",
-            RestClient.builder());
-    private final OpenAiImageModel imageModel = new OpenAiImageModel(imageApi);
+    private final OpenAiImageModel imageModel = new OpenAiImageModel(OpenAiImageApi.builder()
+            .baseUrl("https://api.holdai.top") // apiKey
+            .apiKey("sk-aN6nWn3fILjrgLFT0fC4Aa60B72e4253826c77B29dC94f17")
+            .build());
 
     @Test
     @Disabled

+ 3 - 6
yudao-server/src/main/resources/application.yaml

@@ -163,7 +163,7 @@ spring:
     zhipuai: # 智谱 AI
       api-key: 32f84543e54eee31f8d56b2bd6020573.3vh9idLJZ2ZhxDEs
     openai: # OpenAI 官方
-      api-key: sk-yzKea6d8e8212c3bdd99f9f44ced1cae37c097e5aa3BTS7z
+      api-key: sk-aN6nWn3fILjrgLFT0fC4Aa60B72e4253826c77B29dC94f17
       base-url: https://api.gptsapi.net
     azure: # OpenAI 微软
       openai:
@@ -175,11 +175,8 @@ spring:
         model: llama3
     stabilityai:
       api-key: sk-e53UqbboF8QJCscYvzJscJxJXoFcFg4iJjl1oqgE7baJETmx
-  cloud:
-    ai:
-      tongyi: # 通义千问
-        tongyi:
-          api-key: sk-Zsd81gZYg7
+    dashscope: # 通义千问
+      api-key: sk-71800982914041848008480000000000
 
 yudao:
   ai: