Commit 69d99aa4ea6ab28c4b6f333e8a3e774b41997a51
1 parent
d82c8e05
fix:【ai 大模型】剩余需要 spring ai 兼容支持 thinking 的模型单测补充!
Showing
8 changed files
with
239 additions
and
46 deletions
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 | 3 | import org.junit.jupiter.api.Disabled; |
| 4 | 4 | import org.junit.jupiter.api.Test; |
| 5 | 5 | import org.springframework.ai.anthropic.AnthropicChatModel; |
| 6 | +import org.springframework.ai.anthropic.AnthropicChatOptions; | |
| 6 | 7 | import org.springframework.ai.anthropic.api.AnthropicApi; |
| 7 | 8 | import org.springframework.ai.chat.messages.Message; |
| 8 | 9 | import org.springframework.ai.chat.messages.SystemMessage; |
| ... | ... | @@ -26,6 +27,11 @@ public class AnthropicChatModelTest { |
| 26 | 27 | .apiKey("sk-muubv7cXeLw0Etgs743f365cD5Ea44429946Fa7e672d8942") |
| 27 | 28 | .baseUrl("https://aihubmix.com") |
| 28 | 29 | .build()) |
| 30 | + .defaultOptions(AnthropicChatOptions.builder() | |
| 31 | + .model(AnthropicApi.ChatModel.CLAUDE_SONNET_4) | |
| 32 | + .temperature(0.7) | |
| 33 | + .maxTokens(4096) | |
| 34 | + .build()) | |
| 29 | 35 | .build(); |
| 30 | 36 | |
| 31 | 37 | @Test |
| ... | ... | @@ -56,4 +62,26 @@ public class AnthropicChatModelTest { |
| 56 | 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 | 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 | 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 | 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 | 20 | * {@link OllamaChatModel} 集成测试 |
| ... | ... | @@ -9,43 +23,65 @@ import org.springframework.ai.ollama.OllamaChatModel; |
| 9 | 23 | */ |
| 10 | 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 | 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 | 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 | 1 | package cn.iocoder.yudao.module.ai.framework.ai.core.model.chat; |
| 2 | 2 | |
| 3 | +import com.azure.ai.openai.models.ReasoningEffortValue; | |
| 3 | 4 | import org.junit.jupiter.api.Disabled; |
| 4 | 5 | import org.junit.jupiter.api.Test; |
| 5 | 6 | import org.springframework.ai.chat.messages.Message; |
| ... | ... | @@ -25,10 +26,11 @@ public class OpenAIChatModelTests { |
| 25 | 26 | private final OpenAiChatModel chatModel = OpenAiChatModel.builder() |
| 26 | 27 | .openAiApi(OpenAiApi.builder() |
| 27 | 28 | .baseUrl("https://api.holdai.top") |
| 28 | - .apiKey("sk-PytRecQlmjEteoa2RRN6cGnwslo72UUPLQVNEMS6K9yjbmpD") // apiKey | |
| 29 | + .apiKey("sk-z5joyRoV1iFEnh2SAi8QPNrIZTXyQSyxTmD5CoNDQbFixK2l") // apiKey | |
| 29 | 30 | .build()) |
| 30 | 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 | 34 | .temperature(0.7) |
| 33 | 35 | .build()) |
| 34 | 36 | .build(); |
| ... | ... | @@ -54,7 +56,7 @@ public class OpenAIChatModelTests { |
| 54 | 56 | // 准备参数 |
| 55 | 57 | List<Message> messages = new ArrayList<>(); |
| 56 | 58 | messages.add(new SystemMessage("你是一个优质的文言文作者,用文言文描述着各城市的人文风景。")); |
| 57 | - messages.add(new UserMessage("1 + 1 = ?")); | |
| 59 | + messages.add(new UserMessage("帮我推理下,怎么实现一个用户中心!")); | |
| 58 | 60 | |
| 59 | 61 | // 调用 |
| 60 | 62 | Flux<ChatResponse> flux = chatModel.stream(new Prompt(messages)); |
| ... | ... | @@ -65,4 +67,29 @@ public class OpenAIChatModelTests { |
| 65 | 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 | 26 | .dashScopeApi(DashScopeApi.builder() |
| 27 | 27 | .apiKey("sk-47aa124781be4bfb95244cc62f63f7d0") |
| 28 | 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 | 32 | // .withModel("deepseek-r1") // 模型(deepseek-r1) |
| 32 | 33 | // .withModel("deepseek-v3") // 模型(deepseek-v3) |
| 33 | 34 | // .withModel("deepseek-r1-distill-qwen-1.5b") // 模型(deepseek-r1-distill-qwen-1.5b) |
| 35 | +// .withEnableThinking(true) | |
| 34 | 36 | .build()) |
| 35 | 37 | .build(); |
| 36 | 38 | |
| ... | ... | @@ -54,8 +56,8 @@ public class TongYiChatModelTests { |
| 54 | 56 | public void testStream() { |
| 55 | 57 | // 准备参数 |
| 56 | 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 | 63 | Flux<ChatResponse> flux = chatModel.stream(new Prompt(messages)); |
| ... | ... | @@ -66,4 +68,24 @@ public class TongYiChatModelTests { |
| 66 | 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 | 23 | public class ZhiPuAiChatModelTests { |
| 24 | 24 | |
| 25 | 25 | private final ZhiPuAiChatModel chatModel = new ZhiPuAiChatModel( |
| 26 | - new ZhiPuAiApi("32f84543e54eee31f8d56b2bd6020573.3vh9idLJZ2ZhxDEs"), // 密钥 | |
| 26 | + new ZhiPuAiApi("2f35fb6ca4ea41fab898729b7fac086c.6ESSfPcCkxaKEUlR"), // 密钥 | |
| 27 | 27 | ZhiPuAiChatOptions.builder() |
| 28 | 28 | .model(ZhiPuAiApi.ChatModel.GLM_4.getName()) // 模型 |
| 29 | 29 | .build() |
| ... | ... | @@ -61,4 +61,24 @@ public class ZhiPuAiChatModelTests { |
| 61 | 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 | } | ... | ... |