Commit 69d99aa4ea6ab28c4b6f333e8a3e774b41997a51

Authored by YunaiV
1 parent d82c8e05

fix:【ai 大模型】剩余需要 spring ai 兼容支持 thinking 的模型单测补充!

yudao-module-ai/src/test/java/cn/iocoder/yudao/module/ai/framework/ai/core/model/chat/AnthropicChatModelTest.java
@@ -3,6 +3,7 @@ package cn.iocoder.yudao.module.ai.framework.ai.core.model.chat; @@ -3,6 +3,7 @@ package cn.iocoder.yudao.module.ai.framework.ai.core.model.chat;
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.springframework.ai.anthropic.AnthropicChatModel; 5 import org.springframework.ai.anthropic.AnthropicChatModel;
  6 +import org.springframework.ai.anthropic.AnthropicChatOptions;
6 import org.springframework.ai.anthropic.api.AnthropicApi; 7 import org.springframework.ai.anthropic.api.AnthropicApi;
7 import org.springframework.ai.chat.messages.Message; 8 import org.springframework.ai.chat.messages.Message;
8 import org.springframework.ai.chat.messages.SystemMessage; 9 import org.springframework.ai.chat.messages.SystemMessage;
@@ -26,6 +27,11 @@ public class AnthropicChatModelTest { @@ -26,6 +27,11 @@ public class AnthropicChatModelTest {
26 .apiKey("sk-muubv7cXeLw0Etgs743f365cD5Ea44429946Fa7e672d8942") 27 .apiKey("sk-muubv7cXeLw0Etgs743f365cD5Ea44429946Fa7e672d8942")
27 .baseUrl("https://aihubmix.com") 28 .baseUrl("https://aihubmix.com")
28 .build()) 29 .build())
  30 + .defaultOptions(AnthropicChatOptions.builder()
  31 + .model(AnthropicApi.ChatModel.CLAUDE_SONNET_4)
  32 + .temperature(0.7)
  33 + .maxTokens(4096)
  34 + .build())
29 .build(); 35 .build();
30 36
31 @Test 37 @Test
@@ -56,4 +62,26 @@ public class AnthropicChatModelTest { @@ -56,4 +62,26 @@ public class AnthropicChatModelTest {
56 flux.doOnNext(System.out::println).then().block(); 62 flux.doOnNext(System.out::println).then().block();
57 } 63 }
58 64
  65 + // TODO @芋艿:需要等 spring ai 升级:https://github.com/spring-projects/spring-ai/pull/2800
  66 + @Test
  67 + @Disabled
  68 + public void testStream_thinking() {
  69 + // 准备参数
  70 + List<Message> messages = new ArrayList<>();
  71 + messages.add(new UserMessage("thkinking 下,1+1 为什么等于 2 "));
  72 + AnthropicChatOptions options = AnthropicChatOptions.builder()
  73 + .model(AnthropicApi.ChatModel.CLAUDE_SONNET_4)
  74 + .thinking(AnthropicApi.ThinkingType.ENABLED, 3096)
  75 + .temperature(1D)
  76 + .build();
  77 +
  78 + // 调用
  79 + Flux<ChatResponse> flux = chatModel.stream(new Prompt(messages, options));
  80 + // 打印结果
  81 + flux.doOnNext(response -> {
  82 +// System.out.println(response);
  83 + System.out.println(response.getResult());
  84 + }).then().block();
  85 + }
  86 +
59 } 87 }
yudao-module-ai/src/test/java/cn/iocoder/yudao/module/ai/framework/ai/core/model/chat/DeepSeekChatModelTests.java
@@ -60,4 +60,23 @@ public class DeepSeekChatModelTests { @@ -60,4 +60,23 @@ public class DeepSeekChatModelTests {
60 flux.doOnNext(System.out::println).then().block(); 60 flux.doOnNext(System.out::println).then().block();
61 } 61 }
62 62
  63 + @Test
  64 + @Disabled
  65 + public void testStream_thinking() {
  66 + // 准备参数
  67 + List<Message> messages = new ArrayList<>();
  68 + messages.add(new UserMessage("详细分析下,如何设计一个电商系统?"));
  69 + DeepSeekChatOptions options = DeepSeekChatOptions.builder()
  70 + .model("deepseek-reasoner")
  71 + .build();
  72 +
  73 + // 调用
  74 + Flux<ChatResponse> flux = chatModel.stream(new Prompt(messages, options));
  75 + // 打印结果
  76 + flux.doOnNext(response -> {
  77 +// System.out.println(response);
  78 + System.out.println(response.getResult().getOutput());
  79 + }).then().block();
  80 + }
  81 +
63 } 82 }
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;
3 import org.springframework.ai.ollama.OllamaChatModel; 10 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;
4 18
5 /** 19 /**
6 * {@link OllamaChatModel} 集成测试 20 * {@link OllamaChatModel} 集成测试
@@ -9,43 +23,65 @@ import org.springframework.ai.ollama.OllamaChatModel; @@ -9,43 +23,65 @@ import org.springframework.ai.ollama.OllamaChatModel;
9 */ 23 */
10 public class LlamaChatModelTests { 24 public class LlamaChatModelTests {
11 25
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 -// } 26 + private final OllamaChatModel chatModel = OllamaChatModel.builder()
  27 + .ollamaApi(OllamaApi.builder()
  28 + .baseUrl("http://127.0.0.1:11434") // Ollama 服务地址
  29 + .build())
  30 + .defaultOptions(OllamaOptions.builder()
  31 + .model(OllamaModel.LLAMA3.getName()) // 模型
  32 + .build())
  33 + .build();
  34 +
  35 + @Test
  36 + @Disabled
  37 + public void testCall() {
  38 + // 准备参数
  39 + List<Message> messages = new ArrayList<>();
  40 + messages.add(new SystemMessage("你是一个优质的文言文作者,用文言文描述着各城市的人文风景。"));
  41 + messages.add(new UserMessage("1 + 1 = ?"));
  42 +
  43 + // 调用
  44 + ChatResponse response = chatModel.call(new Prompt(messages));
  45 + // 打印结果
  46 + System.out.println(response);
  47 + System.out.println(response.getResult().getOutput());
  48 + }
  49 +
  50 + @Test
  51 + @Disabled
  52 + public void testStream() {
  53 + // 准备参数
  54 + List<Message> messages = new ArrayList<>();
  55 + messages.add(new SystemMessage("你是一个优质的文言文作者,用文言文描述着各城市的人文风景。"));
  56 + messages.add(new UserMessage("1 + 1 = ?"));
  57 +
  58 + // 调用
  59 + Flux<ChatResponse> flux = chatModel.stream(new Prompt(messages));
  60 + // 打印结果
  61 + flux.doOnNext(response -> {
  62 +// System.out.println(response);
  63 + System.out.println(response.getResult().getOutput());
  64 + }).then().block();
  65 + }
  66 +
  67 + @Test
  68 + @Disabled
  69 + public void testStream_thinking() {
  70 + // 准备参数
  71 + List<Message> messages = new ArrayList<>();
  72 + messages.add(new UserMessage("详细分析下,如何设计一个电商系统?"));
  73 + OllamaOptions options = OllamaOptions.builder()
  74 + .model("qwen3")
  75 + .build();
  76 +
  77 + // 调用
  78 + Flux<ChatResponse> flux = chatModel.stream(new Prompt(messages, options));
  79 + // 打印结果
  80 + flux.doOnNext(response -> {
  81 +// System.out.println(response);
  82 + System.out.println(response.getResult().getOutput());
  83 + }).then().block();
  84 + }
  85 +
50 86
51 } 87 }
yudao-module-ai/src/test/java/cn/iocoder/yudao/module/ai/framework/ai/core/model/chat/MiniMaxChatModelTests.java
@@ -59,4 +59,24 @@ public class MiniMaxChatModelTests { @@ -59,4 +59,24 @@ public class MiniMaxChatModelTests {
59 }).then().block(); 59 }).then().block();
60 } 60 }
61 61
  62 + // TODO @芋艿:暂时没解析 reasoning_content 结果,需要等官方修复
  63 + @Test
  64 + @Disabled
  65 + public void testStream_thinking() {
  66 + // 准备参数
  67 + List<Message> messages = new ArrayList<>();
  68 + messages.add(new UserMessage("详细分析下,如何设计一个电商系统?"));
  69 + MiniMaxChatOptions options = MiniMaxChatOptions.builder()
  70 + .model("MiniMax-M1")
  71 + .build();
  72 +
  73 + // 调用
  74 + Flux<ChatResponse> flux = chatModel.stream(new Prompt(messages, options));
  75 + // 打印结果
  76 + flux.doOnNext(response -> {
  77 +// System.out.println(response);
  78 + System.out.println(response.getResult().getOutput());
  79 + }).then().block();
  80 + }
  81 +
62 } 82 }
yudao-module-ai/src/test/java/cn/iocoder/yudao/module/ai/framework/ai/core/model/chat/MoonshotChatModelTests.java
@@ -63,4 +63,25 @@ public class MoonshotChatModelTests { @@ -63,4 +63,25 @@ public class MoonshotChatModelTests {
63 }).then().block(); 63 }).then().block();
64 } 64 }
65 65
  66 + // TODO @芋艿:暂时没解析 reasoning_content 结果,需要等官方修复
  67 + @Test
  68 + @Disabled
  69 + public void testStream_thinking() {
  70 + // 准备参数
  71 + List<Message> messages = new ArrayList<>();
  72 + messages.add(new UserMessage("详细分析下,如何设计一个电商系统?"));
  73 + MoonshotChatOptions options = MoonshotChatOptions.builder()
  74 +// .model("kimi-k2-0711-preview")
  75 + .model("kimi-thinking-preview")
  76 + .build();
  77 +
  78 + // 调用
  79 + Flux<ChatResponse> flux = chatModel.stream(new Prompt(messages, options));
  80 + // 打印结果
  81 + flux.doOnNext(response -> {
  82 +// System.out.println(response);
  83 + System.out.println(response.getResult().getOutput());
  84 + }).then().block();
  85 + }
  86 +
66 } 87 }
yudao-module-ai/src/test/java/cn/iocoder/yudao/module/ai/framework/ai/core/model/chat/OpenAIChatModelTests.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 com.azure.ai.openai.models.ReasoningEffortValue;
3 import org.junit.jupiter.api.Disabled; 4 import org.junit.jupiter.api.Disabled;
4 import org.junit.jupiter.api.Test; 5 import org.junit.jupiter.api.Test;
5 import org.springframework.ai.chat.messages.Message; 6 import org.springframework.ai.chat.messages.Message;
@@ -25,10 +26,11 @@ public class OpenAIChatModelTests { @@ -25,10 +26,11 @@ public class OpenAIChatModelTests {
25 private final OpenAiChatModel chatModel = OpenAiChatModel.builder() 26 private final OpenAiChatModel chatModel = OpenAiChatModel.builder()
26 .openAiApi(OpenAiApi.builder() 27 .openAiApi(OpenAiApi.builder()
27 .baseUrl("https://api.holdai.top") 28 .baseUrl("https://api.holdai.top")
28 - .apiKey("sk-PytRecQlmjEteoa2RRN6cGnwslo72UUPLQVNEMS6K9yjbmpD") // apiKey 29 + .apiKey("sk-z5joyRoV1iFEnh2SAi8QPNrIZTXyQSyxTmD5CoNDQbFixK2l") // apiKey
29 .build()) 30 .build())
30 .defaultOptions(OpenAiChatOptions.builder() 31 .defaultOptions(OpenAiChatOptions.builder()
31 - .model(OpenAiApi.ChatModel.GPT_4_1_NANO) // 模型 32 + .model("gpt-5-nano-2025-08-07") // 模型
  33 +// .model(OpenAiApi.ChatModel.O1) // 模型
32 .temperature(0.7) 34 .temperature(0.7)
33 .build()) 35 .build())
34 .build(); 36 .build();
@@ -54,7 +56,7 @@ public class OpenAIChatModelTests { @@ -54,7 +56,7 @@ public class OpenAIChatModelTests {
54 // 准备参数 56 // 准备参数
55 List<Message> messages = new ArrayList<>(); 57 List<Message> messages = new ArrayList<>();
56 messages.add(new SystemMessage("你是一个优质的文言文作者,用文言文描述着各城市的人文风景。")); 58 messages.add(new SystemMessage("你是一个优质的文言文作者,用文言文描述着各城市的人文风景。"));
57 - messages.add(new UserMessage("1 + 1 = ?")); 59 + messages.add(new UserMessage("帮我推理下,怎么实现一个用户中心!"));
58 60
59 // 调用 61 // 调用
60 Flux<ChatResponse> flux = chatModel.stream(new Prompt(messages)); 62 Flux<ChatResponse> flux = chatModel.stream(new Prompt(messages));
@@ -65,4 +67,29 @@ public class OpenAIChatModelTests { @@ -65,4 +67,29 @@ public class OpenAIChatModelTests {
65 }).then().block(); 67 }).then().block();
66 } 68 }
67 69
  70 + // TODO @芋艿:无法触发思考的字段返回,需要 response api:https://github.com/spring-projects/spring-ai/issues/2962
  71 + @Test
  72 + @Disabled
  73 + public void testStream_thinking() {
  74 + // 准备参数
  75 + List<Message> messages = new ArrayList<>();
  76 + messages.add(new UserMessage("详细分析下,如何设计一个电商系统?"));
  77 + OpenAiChatOptions options = OpenAiChatOptions.builder()
  78 + .model("gpt-5")
  79 +// .model(OpenAiApi.ChatModel.O4_MINI)
  80 +// .model("o3-pro")
  81 + .reasoningEffort(ReasoningEffortValue.LOW.getValue())
  82 + .build();
  83 +
  84 + // 调用
  85 + Flux<ChatResponse> flux = chatModel.stream(new Prompt(messages, options));
  86 + // 打印结果
  87 + flux.doOnNext(response -> {
  88 +// System.out.println(response);
  89 + System.out.println(response.getResult().getOutput());
  90 + }).then().block();
  91 + }
  92 +
  93 +
  94 +
68 } 95 }
yudao-module-ai/src/test/java/cn/iocoder/yudao/module/ai/framework/ai/core/model/chat/TongYiChatModelTests.java
@@ -26,11 +26,13 @@ public class TongYiChatModelTests { @@ -26,11 +26,13 @@ public class TongYiChatModelTests {
26 .dashScopeApi(DashScopeApi.builder() 26 .dashScopeApi(DashScopeApi.builder()
27 .apiKey("sk-47aa124781be4bfb95244cc62f63f7d0") 27 .apiKey("sk-47aa124781be4bfb95244cc62f63f7d0")
28 .build()) 28 .build())
29 - .defaultOptions( DashScopeChatOptions.builder()  
30 - .withModel("qwen1.5-72b-chat") // 模型 29 + .defaultOptions(DashScopeChatOptions.builder()
  30 +// .withModel("qwen1.5-72b-chat") // 模型
  31 + .withModel("qwen3-235b-a22b-thinking-2507") // 模型
31 // .withModel("deepseek-r1") // 模型(deepseek-r1) 32 // .withModel("deepseek-r1") // 模型(deepseek-r1)
32 // .withModel("deepseek-v3") // 模型(deepseek-v3) 33 // .withModel("deepseek-v3") // 模型(deepseek-v3)
33 // .withModel("deepseek-r1-distill-qwen-1.5b") // 模型(deepseek-r1-distill-qwen-1.5b) 34 // .withModel("deepseek-r1-distill-qwen-1.5b") // 模型(deepseek-r1-distill-qwen-1.5b)
  35 +// .withEnableThinking(true)
34 .build()) 36 .build())
35 .build(); 37 .build();
36 38
@@ -54,8 +56,8 @@ public class TongYiChatModelTests { @@ -54,8 +56,8 @@ public class TongYiChatModelTests {
54 public void testStream() { 56 public void testStream() {
55 // 准备参数 57 // 准备参数
56 List<Message> messages = new ArrayList<>(); 58 List<Message> messages = new ArrayList<>();
57 - messages.add(new SystemMessage("你是一个优质的文言文作者,用文言文描述着各城市的人文风景。"));  
58 - messages.add(new UserMessage("1 + 1 = ?")); 59 +// messages.add(new SystemMessage("你是一个优质的文言文作者,用文言文描述着各城市的人文风景。"));
  60 + messages.add(new UserMessage("帮我推理下,怎么实现一个用户中心!"));
59 61
60 // 调用 62 // 调用
61 Flux<ChatResponse> flux = chatModel.stream(new Prompt(messages)); 63 Flux<ChatResponse> flux = chatModel.stream(new Prompt(messages));
@@ -66,4 +68,24 @@ public class TongYiChatModelTests { @@ -66,4 +68,24 @@ public class TongYiChatModelTests {
66 }).then().block(); 68 }).then().block();
67 } 69 }
68 70
  71 + @Test
  72 + @Disabled
  73 + public void testStream_thinking() {
  74 + // 准备参数
  75 + List<Message> messages = new ArrayList<>();
  76 + messages.add(new UserMessage("详细分析下,如何设计一个电商系统?"));
  77 + DashScopeChatOptions options = DashScopeChatOptions.builder()
  78 + .withModel("qwen3-235b-a22b-thinking-2507")
  79 + .withEnableThinking(true) // 必须设置,否则会报错
  80 + .build();
  81 +
  82 + // 调用
  83 + Flux<ChatResponse> flux = chatModel.stream(new Prompt(messages, options));
  84 + // 打印结果
  85 + flux.doOnNext(response -> {
  86 +// System.out.println(response);
  87 + System.out.println(response.getResult().getOutput());
  88 + }).then().block();
  89 + }
  90 +
69 } 91 }
yudao-module-ai/src/test/java/cn/iocoder/yudao/module/ai/framework/ai/core/model/chat/ZhiPuAiChatModelTests.java
@@ -23,7 +23,7 @@ import java.util.List; @@ -23,7 +23,7 @@ import java.util.List;
23 public class ZhiPuAiChatModelTests { 23 public class ZhiPuAiChatModelTests {
24 24
25 private final ZhiPuAiChatModel chatModel = new ZhiPuAiChatModel( 25 private final ZhiPuAiChatModel chatModel = new ZhiPuAiChatModel(
26 - new ZhiPuAiApi("32f84543e54eee31f8d56b2bd6020573.3vh9idLJZ2ZhxDEs"), // 密钥 26 + new ZhiPuAiApi("2f35fb6ca4ea41fab898729b7fac086c.6ESSfPcCkxaKEUlR"), // 密钥
27 ZhiPuAiChatOptions.builder() 27 ZhiPuAiChatOptions.builder()
28 .model(ZhiPuAiApi.ChatModel.GLM_4.getName()) // 模型 28 .model(ZhiPuAiApi.ChatModel.GLM_4.getName()) // 模型
29 .build() 29 .build()
@@ -61,4 +61,24 @@ public class ZhiPuAiChatModelTests { @@ -61,4 +61,24 @@ public class ZhiPuAiChatModelTests {
61 }).then().block(); 61 }).then().block();
62 } 62 }
63 63
  64 + // TODO @芋艿:暂时没解析 reasoning_content 结果,需要等官方修复
  65 + @Test
  66 + @Disabled
  67 + public void testStream_thinking() {
  68 + // 准备参数
  69 + List<Message> messages = new ArrayList<>();
  70 + messages.add(new UserMessage("详细分析下,如何设计一个电商系统?"));
  71 + ZhiPuAiChatOptions options = ZhiPuAiChatOptions.builder()
  72 + .model("GLM-4.5")
  73 + .build();
  74 +
  75 + // 调用
  76 + Flux<ChatResponse> flux = chatModel.stream(new Prompt(messages, options));
  77 + // 打印结果
  78 + flux.doOnNext(response -> {
  79 +// System.out.println(response);
  80 + System.out.println(response.getResult().getOutput());
  81 + }).then().block();
  82 + }
  83 +
64 } 84 }