Commit 39ecf5ebe5aa8489a7ec44fd9bf31226c2f6887d

Authored by YunaiV
1 parent 750709d7

feat:【AI 大模型】文心一言存在 springai 接入问题,无法使用 https://github.com/spring-ai-community/qianfan/issues/6

yudao-module-ai/src/main/java/cn/iocoder/yudao/module/ai/framework/ai/core/AiModelFactoryImpl.java
@@ -357,7 +357,7 @@ public class AiModelFactoryImpl implements AiModelFactory { @@ -357,7 +357,7 @@ public class AiModelFactoryImpl implements AiModelFactory {
357 * 可参考 {@link QianFanChatAutoConfiguration} 的 qianFanChatModel 方法 357 * 可参考 {@link QianFanChatAutoConfiguration} 的 qianFanChatModel 方法
358 */ 358 */
359 private static QianFanChatModel buildYiYanChatModel(String key) { 359 private static QianFanChatModel buildYiYanChatModel(String key) {
360 - // TODO @芋艿:未测试 360 + // TODO spring ai qianfan 有 bug,无法使用 https://github.com/spring-ai-community/qianfan/issues/6
361 List<String> keys = StrUtil.split(key, '|'); 361 List<String> keys = StrUtil.split(key, '|');
362 Assert.equals(keys.size(), 2, "YiYanChatClient 的密钥需要 (appKey|secretKey) 格式"); 362 Assert.equals(keys.size(), 2, "YiYanChatClient 的密钥需要 (appKey|secretKey) 格式");
363 String appKey = keys.get(0); 363 String appKey = keys.get(0);
@@ -370,7 +370,7 @@ public class AiModelFactoryImpl implements AiModelFactory { @@ -370,7 +370,7 @@ public class AiModelFactoryImpl implements AiModelFactory {
370 * 可参考 {@link QianFanEmbeddingAutoConfiguration} 的 qianFanImageModel 方法 370 * 可参考 {@link QianFanEmbeddingAutoConfiguration} 的 qianFanImageModel 方法
371 */ 371 */
372 private QianFanImageModel buildQianFanImageModel(String key) { 372 private QianFanImageModel buildQianFanImageModel(String key) {
373 - // TODO @芋艿:未测试 373 + // TODO spring ai qianfan 有 bug,无法使用 https://github.com/spring-ai-community/qianfan/issues/6
374 List<String> keys = StrUtil.split(key, '|'); 374 List<String> keys = StrUtil.split(key, '|');
375 Assert.equals(keys.size(), 2, "YiYanChatClient 的密钥需要 (appKey|secretKey) 格式"); 375 Assert.equals(keys.size(), 2, "YiYanChatClient 的密钥需要 (appKey|secretKey) 格式");
376 String appKey = keys.get(0); 376 String appKey = keys.get(0);
@@ -525,7 +525,6 @@ public class AiModelFactoryImpl implements AiModelFactory { @@ -525,7 +525,6 @@ public class AiModelFactoryImpl implements AiModelFactory {
525 * 创建 SiliconFlowImageModel 对象 525 * 创建 SiliconFlowImageModel 对象
526 */ 526 */
527 private SiliconFlowImageModel buildSiliconFlowImageModel(String apiToken, String url) { 527 private SiliconFlowImageModel buildSiliconFlowImageModel(String apiToken, String url) {
528 - // TODO @芋艿:未测试  
529 url = StrUtil.blankToDefault(url, SiliconFlowApiConstants.DEFAULT_BASE_URL); 528 url = StrUtil.blankToDefault(url, SiliconFlowApiConstants.DEFAULT_BASE_URL);
530 SiliconFlowImageApi openAiApi = new SiliconFlowImageApi(url, apiToken); 529 SiliconFlowImageApi openAiApi = new SiliconFlowImageApi(url, apiToken);
531 return new SiliconFlowImageModel(openAiApi); 530 return new SiliconFlowImageModel(openAiApi);
@@ -535,9 +534,11 @@ public class AiModelFactoryImpl implements AiModelFactory { @@ -535,9 +534,11 @@ public class AiModelFactoryImpl implements AiModelFactory {
535 * 可参考 {@link OllamaChatAutoConfiguration} 的 ollamaChatModel 方法 534 * 可参考 {@link OllamaChatAutoConfiguration} 的 ollamaChatModel 方法
536 */ 535 */
537 private static OllamaChatModel buildOllamaChatModel(String url) { 536 private static OllamaChatModel buildOllamaChatModel(String url) {
538 - // TODO @芋艿:未测试  
539 OllamaApi ollamaApi = OllamaApi.builder().baseUrl(url).build(); 537 OllamaApi ollamaApi = OllamaApi.builder().baseUrl(url).build();
540 - return OllamaChatModel.builder().ollamaApi(ollamaApi).toolCallingManager(getToolCallingManager()).build(); 538 + return OllamaChatModel.builder()
  539 + .ollamaApi(ollamaApi)
  540 + .toolCallingManager(getToolCallingManager())
  541 + .build();
541 } 542 }
542 543
543 /** 544 /**
@@ -596,7 +597,10 @@ public class AiModelFactoryImpl implements AiModelFactory { @@ -596,7 +597,10 @@ public class AiModelFactoryImpl implements AiModelFactory {
596 private OllamaEmbeddingModel buildOllamaEmbeddingModel(String url, String model) { 597 private OllamaEmbeddingModel buildOllamaEmbeddingModel(String url, String model) {
597 OllamaApi ollamaApi = OllamaApi.builder().baseUrl(url).build(); 598 OllamaApi ollamaApi = OllamaApi.builder().baseUrl(url).build();
598 OllamaOptions ollamaOptions = OllamaOptions.builder().model(model).build(); 599 OllamaOptions ollamaOptions = OllamaOptions.builder().model(model).build();
599 - return OllamaEmbeddingModel.builder().ollamaApi(ollamaApi).defaultOptions(ollamaOptions).build(); 600 + return OllamaEmbeddingModel.builder()
  601 + .ollamaApi(ollamaApi)
  602 + .defaultOptions(ollamaOptions)
  603 + .build();
600 } 604 }
601 605
602 /** 606 /**
yudao-module-ai/src/test/java/cn/iocoder/yudao/module/ai/framework/ai/core/model/chat/LlamaChatModelTests.java
1 package cn.iocoder.yudao.module.ai.framework.ai.core.model.chat; 1 package cn.iocoder.yudao.module.ai.framework.ai.core.model.chat;
2 2
3 -import org.junit.jupiter.api.Disabled;  
4 -import org.junit.jupiter.api.Test;  
5 -import org.springframework.ai.chat.messages.Message;  
6 -import org.springframework.ai.chat.messages.SystemMessage;  
7 -import org.springframework.ai.chat.messages.UserMessage;  
8 -import org.springframework.ai.chat.model.ChatResponse;  
9 -import org.springframework.ai.chat.prompt.Prompt;  
10 import org.springframework.ai.ollama.OllamaChatModel; 3 import org.springframework.ai.ollama.OllamaChatModel;
11 -import org.springframework.ai.ollama.api.OllamaApi;  
12 -import org.springframework.ai.ollama.api.OllamaModel;  
13 -import org.springframework.ai.ollama.api.OllamaOptions;  
14 -import reactor.core.publisher.Flux;  
15 -  
16 -import java.util.ArrayList;  
17 -import java.util.List;  
18 4
19 /** 5 /**
20 * {@link OllamaChatModel} 集成测试 6 * {@link OllamaChatModel} 集成测试
@@ -23,43 +9,43 @@ import java.util.List; @@ -23,43 +9,43 @@ import java.util.List;
23 */ 9 */
24 public class LlamaChatModelTests { 10 public class LlamaChatModelTests {
25 11
26 - private final OllamaChatModel chatModel = OllamaChatModel.builder()  
27 - .ollamaApi(new OllamaApi("http://127.0.0.1:11434")) // Ollama 服务地址  
28 - .defaultOptions(OllamaOptions.builder()  
29 - .model(OllamaModel.LLAMA3.getName()) // 模型  
30 - .build())  
31 - .build();  
32 -  
33 - @Test  
34 - @Disabled  
35 - public void testCall() {  
36 - // 准备参数  
37 - List<Message> messages = new ArrayList<>();  
38 - messages.add(new SystemMessage("你是一个优质的文言文作者,用文言文描述着各城市的人文风景。"));  
39 - messages.add(new UserMessage("1 + 1 = ?"));  
40 -  
41 - // 调用  
42 - ChatResponse response = chatModel.call(new Prompt(messages));  
43 - // 打印结果  
44 - System.out.println(response);  
45 - System.out.println(response.getResult().getOutput());  
46 - }  
47 -  
48 - @Test  
49 - @Disabled  
50 - public void testStream() {  
51 - // 准备参数  
52 - List<Message> messages = new ArrayList<>();  
53 - messages.add(new SystemMessage("你是一个优质的文言文作者,用文言文描述着各城市的人文风景。"));  
54 - messages.add(new UserMessage("1 + 1 = ?"));  
55 -  
56 - // 调用  
57 - Flux<ChatResponse> flux = chatModel.stream(new Prompt(messages));  
58 - // 打印结果  
59 - flux.doOnNext(response -> {  
60 -// System.out.println(response);  
61 - System.out.println(response.getResult().getOutput());  
62 - }).then().block();  
63 - } 12 +// private final OllamaChatModel chatModel = OllamaChatModel.builder()
  13 +// .ollamaApi(new OllamaApi("http://127.0.0.1:11434")) // Ollama 服务地址
  14 +// .defaultOptions(OllamaOptions.builder()
  15 +// .model(OllamaModel.LLAMA3.getName()) // 模型
  16 +// .build())
  17 +// .build();
  18 +//
  19 +// @Test
  20 +// @Disabled
  21 +// public void testCall() {
  22 +// // 准备参数
  23 +// List<Message> messages = new ArrayList<>();
  24 +// messages.add(new SystemMessage("你是一个优质的文言文作者,用文言文描述着各城市的人文风景。"));
  25 +// messages.add(new UserMessage("1 + 1 = ?"));
  26 +//
  27 +// // 调用
  28 +// ChatResponse response = chatModel.call(new Prompt(messages));
  29 +// // 打印结果
  30 +// System.out.println(response);
  31 +// System.out.println(response.getResult().getOutput());
  32 +// }
  33 +//
  34 +// @Test
  35 +// @Disabled
  36 +// public void testStream() {
  37 +// // 准备参数
  38 +// List<Message> messages = new ArrayList<>();
  39 +// messages.add(new SystemMessage("你是一个优质的文言文作者,用文言文描述着各城市的人文风景。"));
  40 +// messages.add(new UserMessage("1 + 1 = ?"));
  41 +//
  42 +// // 调用
  43 +// Flux<ChatResponse> flux = chatModel.stream(new Prompt(messages));
  44 +// // 打印结果
  45 +// flux.doOnNext(response -> {
  46 +//// System.out.println(response);
  47 +// System.out.println(response.getResult().getOutput());
  48 +// }).then().block();
  49 +// }
64 50
65 } 51 }
yudao-module-ai/src/test/java/cn/iocoder/yudao/module/ai/framework/ai/core/model/chat/OllamaChatModelTests.java
@@ -23,7 +23,9 @@ import java.util.List; @@ -23,7 +23,9 @@ import java.util.List;
23 public class OllamaChatModelTests { 23 public class OllamaChatModelTests {
24 24
25 private final OllamaChatModel chatModel = OllamaChatModel.builder() 25 private final OllamaChatModel chatModel = OllamaChatModel.builder()
26 - .ollamaApi(new OllamaApi("http://127.0.0.1:11434")) // Ollama 服务地址 26 + .ollamaApi(OllamaApi.builder()
  27 + .baseUrl("http://127.0.0.1:11434") // Ollama 服务地址
  28 + .build())
27 .defaultOptions(OllamaOptions.builder() 29 .defaultOptions(OllamaOptions.builder()
28 // .model("qwen") // 模型(https://ollama.com/library/qwen) 30 // .model("qwen") // 模型(https://ollama.com/library/qwen)
29 .model("deepseek-r1") // 模型(https://ollama.com/library/deepseek-r1) 31 .model("deepseek-r1") // 模型(https://ollama.com/library/deepseek-r1)
yudao-module-ai/src/test/java/cn/iocoder/yudao/module/ai/framework/ai/core/model/chat/YiYanChatModelTests.java
@@ -2,13 +2,13 @@ package cn.iocoder.yudao.module.ai.framework.ai.core.model.chat; @@ -2,13 +2,13 @@ package cn.iocoder.yudao.module.ai.framework.ai.core.model.chat;
2 2
3 import org.junit.jupiter.api.Disabled; 3 import org.junit.jupiter.api.Disabled;
4 import org.junit.jupiter.api.Test; 4 import org.junit.jupiter.api.Test;
  5 +import org.springaicommunity.qianfan.QianFanChatModel;
  6 +import org.springaicommunity.qianfan.QianFanChatOptions;
  7 +import org.springaicommunity.qianfan.api.QianFanApi;
5 import org.springframework.ai.chat.messages.Message; 8 import org.springframework.ai.chat.messages.Message;
6 import org.springframework.ai.chat.messages.UserMessage; 9 import org.springframework.ai.chat.messages.UserMessage;
7 import org.springframework.ai.chat.model.ChatResponse; 10 import org.springframework.ai.chat.model.ChatResponse;
8 import org.springframework.ai.chat.prompt.Prompt; 11 import org.springframework.ai.chat.prompt.Prompt;
9 -import org.springframework.ai.qianfan.QianFanChatModel;  
10 -import org.springframework.ai.qianfan.QianFanChatOptions;  
11 -import org.springframework.ai.qianfan.api.QianFanApi;  
12 import reactor.core.publisher.Flux; 12 import reactor.core.publisher.Flux;
13 13
14 import java.util.ArrayList; 14 import java.util.ArrayList;
@@ -23,9 +23,9 @@ import java.util.List; @@ -23,9 +23,9 @@ import java.util.List;
23 public class YiYanChatModelTests { 23 public class YiYanChatModelTests {
24 24
25 private final QianFanChatModel chatModel = new QianFanChatModel( 25 private final QianFanChatModel chatModel = new QianFanChatModel(
26 - new QianFanApi("qS8k8dYr2nXunagK4SSU8Xjj", "pHGbx51ql2f0hOyabQvSZezahVC3hh3e"), // 密钥 26 + new QianFanApi("DGnyzREuaY7av7c38bOM9Ji2", "9aR8myflEOPDrEeLhoXv0FdqANOAyIZW"), // 密钥
27 QianFanChatOptions.builder() 27 QianFanChatOptions.builder()
28 - .model(QianFanApi.ChatModel.ERNIE_4_0_8K_Preview.getValue()) 28 + .model("ERNIE-4.5-8K-Preview")
29 .build() 29 .build()
30 ); 30 );
31 31
yudao-module-ai/src/test/java/cn/iocoder/yudao/module/ai/framework/ai/core/model/image/QianFanImageTests.java
@@ -2,11 +2,11 @@ package cn.iocoder.yudao.module.ai.framework.ai.core.model.image; @@ -2,11 +2,11 @@ package cn.iocoder.yudao.module.ai.framework.ai.core.model.image;
2 2
3 import org.junit.jupiter.api.Disabled; 3 import org.junit.jupiter.api.Disabled;
4 import org.junit.jupiter.api.Test; 4 import org.junit.jupiter.api.Test;
  5 +import org.springaicommunity.qianfan.QianFanImageModel;
  6 +import org.springaicommunity.qianfan.QianFanImageOptions;
  7 +import org.springaicommunity.qianfan.api.QianFanImageApi;
5 import org.springframework.ai.image.ImagePrompt; 8 import org.springframework.ai.image.ImagePrompt;
6 import org.springframework.ai.image.ImageResponse; 9 import org.springframework.ai.image.ImageResponse;
7 -import org.springframework.ai.qianfan.QianFanImageModel;  
8 -import org.springframework.ai.qianfan.QianFanImageOptions;  
9 -import org.springframework.ai.qianfan.api.QianFanImageApi;  
10 10
11 import static cn.iocoder.yudao.module.ai.framework.ai.core.model.image.StabilityAiImageModelTests.viewImage; 11 import static cn.iocoder.yudao.module.ai.framework.ai.core.model.image.StabilityAiImageModelTests.viewImage;
12 12