Commit 750709d706fdad1fdde16e6fab7a75de238ea879

Authored by YunaiV
1 parent 3d0eb771

feat:【AI 大模型】deepseek、azure、baichuan、moonshot 适配 1.0.0

yudao-module-ai/src/main/java/cn/iocoder/yudao/module/ai/framework/ai/core/AiModelFactoryImpl.java
@@ -8,11 +8,11 @@ import cn.hutool.core.util.ArrayUtil; @@ -8,11 +8,11 @@ import cn.hutool.core.util.ArrayUtil;
8 import cn.hutool.core.util.RuntimeUtil; 8 import cn.hutool.core.util.RuntimeUtil;
9 import cn.hutool.core.util.StrUtil; 9 import cn.hutool.core.util.StrUtil;
10 import cn.hutool.extra.spring.SpringUtil; 10 import cn.hutool.extra.spring.SpringUtil;
  11 +import cn.iocoder.yudao.framework.common.util.spring.SpringUtils;
  12 +import cn.iocoder.yudao.module.ai.enums.model.AiPlatformEnum;
11 import cn.iocoder.yudao.module.ai.framework.ai.config.AiAutoConfiguration; 13 import cn.iocoder.yudao.module.ai.framework.ai.config.AiAutoConfiguration;
12 import cn.iocoder.yudao.module.ai.framework.ai.config.YudaoAiProperties; 14 import cn.iocoder.yudao.module.ai.framework.ai.config.YudaoAiProperties;
13 -import cn.iocoder.yudao.module.ai.enums.model.AiPlatformEnum;  
14 import cn.iocoder.yudao.module.ai.framework.ai.core.model.baichuan.BaiChuanChatModel; 15 import cn.iocoder.yudao.module.ai.framework.ai.core.model.baichuan.BaiChuanChatModel;
15 -import cn.iocoder.yudao.module.ai.framework.ai.core.model.deepseek.DeepSeekChatModel;  
16 import cn.iocoder.yudao.module.ai.framework.ai.core.model.doubao.DouBaoChatModel; 16 import cn.iocoder.yudao.module.ai.framework.ai.core.model.doubao.DouBaoChatModel;
17 import cn.iocoder.yudao.module.ai.framework.ai.core.model.hunyuan.HunYuanChatModel; 17 import cn.iocoder.yudao.module.ai.framework.ai.core.model.hunyuan.HunYuanChatModel;
18 import cn.iocoder.yudao.module.ai.framework.ai.core.model.midjourney.api.MidjourneyApi; 18 import cn.iocoder.yudao.module.ai.framework.ai.core.model.midjourney.api.MidjourneyApi;
@@ -22,8 +22,9 @@ import cn.iocoder.yudao.module.ai.framework.ai.core.model.siliconflow.SiliconFlo @@ -22,8 +22,9 @@ import cn.iocoder.yudao.module.ai.framework.ai.core.model.siliconflow.SiliconFlo
22 import cn.iocoder.yudao.module.ai.framework.ai.core.model.siliconflow.SiliconFlowImageModel; 22 import cn.iocoder.yudao.module.ai.framework.ai.core.model.siliconflow.SiliconFlowImageModel;
23 import cn.iocoder.yudao.module.ai.framework.ai.core.model.suno.api.SunoApi; 23 import cn.iocoder.yudao.module.ai.framework.ai.core.model.suno.api.SunoApi;
24 import cn.iocoder.yudao.module.ai.framework.ai.core.model.xinghuo.XingHuoChatModel; 24 import cn.iocoder.yudao.module.ai.framework.ai.core.model.xinghuo.XingHuoChatModel;
25 -import cn.iocoder.yudao.framework.common.util.spring.SpringUtils;  
26 -import com.alibaba.cloud.ai.autoconfigure.dashscope.DashScopeAutoConfiguration; 25 +import com.alibaba.cloud.ai.autoconfigure.dashscope.DashScopeChatAutoConfiguration;
  26 +import com.alibaba.cloud.ai.autoconfigure.dashscope.DashScopeEmbeddingAutoConfiguration;
  27 +import com.alibaba.cloud.ai.autoconfigure.dashscope.DashScopeImageAutoConfiguration;
27 import com.alibaba.cloud.ai.dashscope.api.DashScopeApi; 28 import com.alibaba.cloud.ai.dashscope.api.DashScopeApi;
28 import com.alibaba.cloud.ai.dashscope.api.DashScopeImageApi; 29 import com.alibaba.cloud.ai.dashscope.api.DashScopeImageApi;
29 import com.alibaba.cloud.ai.dashscope.chat.DashScopeChatModel; 30 import com.alibaba.cloud.ai.dashscope.chat.DashScopeChatModel;
@@ -32,47 +33,55 @@ import com.alibaba.cloud.ai.dashscope.embedding.DashScopeEmbeddingModel; @@ -32,47 +33,55 @@ import com.alibaba.cloud.ai.dashscope.embedding.DashScopeEmbeddingModel;
32 import com.alibaba.cloud.ai.dashscope.embedding.DashScopeEmbeddingOptions; 33 import com.alibaba.cloud.ai.dashscope.embedding.DashScopeEmbeddingOptions;
33 import com.alibaba.cloud.ai.dashscope.image.DashScopeImageModel; 34 import com.alibaba.cloud.ai.dashscope.image.DashScopeImageModel;
34 import com.azure.ai.openai.OpenAIClientBuilder; 35 import com.azure.ai.openai.OpenAIClientBuilder;
  36 +import com.azure.core.credential.KeyCredential;
35 import io.micrometer.observation.ObservationRegistry; 37 import io.micrometer.observation.ObservationRegistry;
36 import io.milvus.client.MilvusServiceClient; 38 import io.milvus.client.MilvusServiceClient;
37 import io.qdrant.client.QdrantClient; 39 import io.qdrant.client.QdrantClient;
38 import io.qdrant.client.QdrantGrpcClient; 40 import io.qdrant.client.QdrantGrpcClient;
39 import lombok.SneakyThrows; 41 import lombok.SneakyThrows;
40 -import org.springframework.ai.autoconfigure.azure.openai.AzureOpenAiAutoConfiguration;  
41 -import org.springframework.ai.autoconfigure.azure.openai.AzureOpenAiChatProperties;  
42 -import org.springframework.ai.autoconfigure.azure.openai.AzureOpenAiConnectionProperties;  
43 -import org.springframework.ai.autoconfigure.azure.openai.AzureOpenAiEmbeddingProperties;  
44 -import org.springframework.ai.autoconfigure.minimax.MiniMaxAutoConfiguration;  
45 -import org.springframework.ai.autoconfigure.moonshot.MoonshotAutoConfiguration;  
46 -import org.springframework.ai.autoconfigure.ollama.OllamaAutoConfiguration;  
47 -import org.springframework.ai.autoconfigure.openai.OpenAiAutoConfiguration;  
48 -import org.springframework.ai.autoconfigure.qianfan.QianFanAutoConfiguration;  
49 -import org.springframework.ai.autoconfigure.stabilityai.StabilityAiImageAutoConfiguration;  
50 -import org.springframework.ai.autoconfigure.vectorstore.milvus.MilvusServiceClientConnectionDetails;  
51 -import org.springframework.ai.autoconfigure.vectorstore.milvus.MilvusServiceClientProperties;  
52 -import org.springframework.ai.autoconfigure.vectorstore.milvus.MilvusVectorStoreAutoConfiguration;  
53 -import org.springframework.ai.autoconfigure.vectorstore.milvus.MilvusVectorStoreProperties;  
54 -import org.springframework.ai.autoconfigure.vectorstore.qdrant.QdrantVectorStoreAutoConfiguration;  
55 -import org.springframework.ai.autoconfigure.vectorstore.qdrant.QdrantVectorStoreProperties;  
56 -import org.springframework.ai.autoconfigure.vectorstore.redis.RedisVectorStoreAutoConfiguration;  
57 -import org.springframework.ai.autoconfigure.vectorstore.redis.RedisVectorStoreProperties;  
58 -import org.springframework.ai.autoconfigure.zhipuai.ZhiPuAiAutoConfiguration; 42 +import org.springaicommunity.moonshot.MoonshotChatModel;
  43 +import org.springaicommunity.moonshot.MoonshotChatOptions;
  44 +import org.springaicommunity.moonshot.api.MoonshotApi;
  45 +import org.springaicommunity.moonshot.autoconfigure.MoonshotChatAutoConfiguration;
  46 +import org.springaicommunity.qianfan.QianFanChatModel;
  47 +import org.springaicommunity.qianfan.QianFanEmbeddingModel;
  48 +import org.springaicommunity.qianfan.QianFanEmbeddingOptions;
  49 +import org.springaicommunity.qianfan.QianFanImageModel;
  50 +import org.springaicommunity.qianfan.api.QianFanApi;
  51 +import org.springaicommunity.qianfan.api.QianFanImageApi;
  52 +import org.springaicommunity.qianfan.autoconfigure.QianFanChatAutoConfiguration;
  53 +import org.springaicommunity.qianfan.autoconfigure.QianFanEmbeddingAutoConfiguration;
59 import org.springframework.ai.azure.openai.AzureOpenAiChatModel; 54 import org.springframework.ai.azure.openai.AzureOpenAiChatModel;
60 import org.springframework.ai.azure.openai.AzureOpenAiEmbeddingModel; 55 import org.springframework.ai.azure.openai.AzureOpenAiEmbeddingModel;
61 import org.springframework.ai.chat.model.ChatModel; 56 import org.springframework.ai.chat.model.ChatModel;
  57 +import org.springframework.ai.deepseek.DeepSeekChatModel;
  58 +import org.springframework.ai.deepseek.DeepSeekChatOptions;
  59 +import org.springframework.ai.deepseek.api.DeepSeekApi;
62 import org.springframework.ai.document.MetadataMode; 60 import org.springframework.ai.document.MetadataMode;
63 import org.springframework.ai.embedding.BatchingStrategy; 61 import org.springframework.ai.embedding.BatchingStrategy;
64 import org.springframework.ai.embedding.EmbeddingModel; 62 import org.springframework.ai.embedding.EmbeddingModel;
  63 +import org.springframework.ai.embedding.observation.EmbeddingModelObservationConvention;
65 import org.springframework.ai.image.ImageModel; 64 import org.springframework.ai.image.ImageModel;
66 import org.springframework.ai.minimax.MiniMaxChatModel; 65 import org.springframework.ai.minimax.MiniMaxChatModel;
67 import org.springframework.ai.minimax.MiniMaxChatOptions; 66 import org.springframework.ai.minimax.MiniMaxChatOptions;
68 import org.springframework.ai.minimax.MiniMaxEmbeddingModel; 67 import org.springframework.ai.minimax.MiniMaxEmbeddingModel;
69 import org.springframework.ai.minimax.MiniMaxEmbeddingOptions; 68 import org.springframework.ai.minimax.MiniMaxEmbeddingOptions;
70 import org.springframework.ai.minimax.api.MiniMaxApi; 69 import org.springframework.ai.minimax.api.MiniMaxApi;
71 -import org.springframework.ai.model.function.FunctionCallbackResolver; 70 +import org.springframework.ai.model.azure.openai.autoconfigure.AzureOpenAiChatAutoConfiguration;
  71 +import org.springframework.ai.model.azure.openai.autoconfigure.AzureOpenAiEmbeddingAutoConfiguration;
  72 +import org.springframework.ai.model.azure.openai.autoconfigure.AzureOpenAiEmbeddingProperties;
  73 +import org.springframework.ai.model.deepseek.autoconfigure.DeepSeekChatAutoConfiguration;
  74 +import org.springframework.ai.model.minimax.autoconfigure.MiniMaxChatAutoConfiguration;
  75 +import org.springframework.ai.model.minimax.autoconfigure.MiniMaxEmbeddingAutoConfiguration;
  76 +import org.springframework.ai.model.ollama.autoconfigure.OllamaChatAutoConfiguration;
  77 +import org.springframework.ai.model.openai.autoconfigure.OpenAiChatAutoConfiguration;
  78 +import org.springframework.ai.model.openai.autoconfigure.OpenAiEmbeddingAutoConfiguration;
  79 +import org.springframework.ai.model.openai.autoconfigure.OpenAiImageAutoConfiguration;
  80 +import org.springframework.ai.model.stabilityai.autoconfigure.StabilityAiImageAutoConfiguration;
72 import org.springframework.ai.model.tool.ToolCallingManager; 81 import org.springframework.ai.model.tool.ToolCallingManager;
73 -import org.springframework.ai.moonshot.MoonshotChatModel;  
74 -import org.springframework.ai.moonshot.MoonshotChatOptions;  
75 -import org.springframework.ai.moonshot.api.MoonshotApi; 82 +import org.springframework.ai.model.zhipuai.autoconfigure.ZhiPuAiChatAutoConfiguration;
  83 +import org.springframework.ai.model.zhipuai.autoconfigure.ZhiPuAiEmbeddingAutoConfiguration;
  84 +import org.springframework.ai.model.zhipuai.autoconfigure.ZhiPuAiImageAutoConfiguration;
76 import org.springframework.ai.ollama.OllamaChatModel; 85 import org.springframework.ai.ollama.OllamaChatModel;
77 import org.springframework.ai.ollama.OllamaEmbeddingModel; 86 import org.springframework.ai.ollama.OllamaEmbeddingModel;
78 import org.springframework.ai.ollama.api.OllamaApi; 87 import org.springframework.ai.ollama.api.OllamaApi;
@@ -84,21 +93,23 @@ import org.springframework.ai.openai.OpenAiImageModel; @@ -84,21 +93,23 @@ import org.springframework.ai.openai.OpenAiImageModel;
84 import org.springframework.ai.openai.api.OpenAiApi; 93 import org.springframework.ai.openai.api.OpenAiApi;
85 import org.springframework.ai.openai.api.OpenAiImageApi; 94 import org.springframework.ai.openai.api.OpenAiImageApi;
86 import org.springframework.ai.openai.api.common.OpenAiApiConstants; 95 import org.springframework.ai.openai.api.common.OpenAiApiConstants;
87 -import org.springframework.ai.qianfan.QianFanChatModel;  
88 -import org.springframework.ai.qianfan.QianFanEmbeddingModel;  
89 -import org.springframework.ai.qianfan.QianFanEmbeddingOptions;  
90 -import org.springframework.ai.qianfan.QianFanImageModel;  
91 -import org.springframework.ai.qianfan.api.QianFanApi;  
92 -import org.springframework.ai.qianfan.api.QianFanImageApi;  
93 import org.springframework.ai.stabilityai.StabilityAiImageModel; 96 import org.springframework.ai.stabilityai.StabilityAiImageModel;
94 import org.springframework.ai.stabilityai.api.StabilityAiApi; 97 import org.springframework.ai.stabilityai.api.StabilityAiApi;
95 import org.springframework.ai.vectorstore.SimpleVectorStore; 98 import org.springframework.ai.vectorstore.SimpleVectorStore;
96 import org.springframework.ai.vectorstore.VectorStore; 99 import org.springframework.ai.vectorstore.VectorStore;
97 import org.springframework.ai.vectorstore.milvus.MilvusVectorStore; 100 import org.springframework.ai.vectorstore.milvus.MilvusVectorStore;
  101 +import org.springframework.ai.vectorstore.milvus.autoconfigure.MilvusServiceClientConnectionDetails;
  102 +import org.springframework.ai.vectorstore.milvus.autoconfigure.MilvusServiceClientProperties;
  103 +import org.springframework.ai.vectorstore.milvus.autoconfigure.MilvusVectorStoreAutoConfiguration;
  104 +import org.springframework.ai.vectorstore.milvus.autoconfigure.MilvusVectorStoreProperties;
98 import org.springframework.ai.vectorstore.observation.DefaultVectorStoreObservationConvention; 105 import org.springframework.ai.vectorstore.observation.DefaultVectorStoreObservationConvention;
99 import org.springframework.ai.vectorstore.observation.VectorStoreObservationConvention; 106 import org.springframework.ai.vectorstore.observation.VectorStoreObservationConvention;
100 import org.springframework.ai.vectorstore.qdrant.QdrantVectorStore; 107 import org.springframework.ai.vectorstore.qdrant.QdrantVectorStore;
  108 +import org.springframework.ai.vectorstore.qdrant.autoconfigure.QdrantVectorStoreAutoConfiguration;
  109 +import org.springframework.ai.vectorstore.qdrant.autoconfigure.QdrantVectorStoreProperties;
101 import org.springframework.ai.vectorstore.redis.RedisVectorStore; 110 import org.springframework.ai.vectorstore.redis.RedisVectorStore;
  111 +import org.springframework.ai.vectorstore.redis.autoconfigure.RedisVectorStoreAutoConfiguration;
  112 +import org.springframework.ai.vectorstore.redis.autoconfigure.RedisVectorStoreProperties;
102 import org.springframework.ai.zhipuai.*; 113 import org.springframework.ai.zhipuai.*;
103 import org.springframework.ai.zhipuai.api.ZhiPuAiApi; 114 import org.springframework.ai.zhipuai.api.ZhiPuAiApi;
104 import org.springframework.ai.zhipuai.api.ZhiPuAiImageApi; 115 import org.springframework.ai.zhipuai.api.ZhiPuAiImageApi;
@@ -190,7 +201,7 @@ public class AiModelFactoryImpl implements AiModelFactory { @@ -190,7 +201,7 @@ public class AiModelFactoryImpl implements AiModelFactory {
190 case XING_HUO: 201 case XING_HUO:
191 return SpringUtil.getBean(XingHuoChatModel.class); 202 return SpringUtil.getBean(XingHuoChatModel.class);
192 case BAI_CHUAN: 203 case BAI_CHUAN:
193 - return SpringUtil.getBean(AzureOpenAiChatModel.class); 204 + return SpringUtil.getBean(BaiChuanChatModel.class);
194 case OPENAI: 205 case OPENAI:
195 return SpringUtil.getBean(OpenAiChatModel.class); 206 return SpringUtil.getBean(OpenAiChatModel.class);
196 case AZURE_OPENAI: 207 case AZURE_OPENAI:
@@ -319,27 +330,34 @@ public class AiModelFactoryImpl implements AiModelFactory { @@ -319,27 +330,34 @@ public class AiModelFactoryImpl implements AiModelFactory {
319 // ========== 各种创建 spring-ai 客户端的方法 ========== 330 // ========== 各种创建 spring-ai 客户端的方法 ==========
320 331
321 /** 332 /**
322 - * 可参考 {@link DashScopeAutoConfiguration} 的 dashscopeChatModel 方法 333 + * 可参考 {@link DashScopeChatAutoConfiguration} 的 dashscopeChatModel 方法
323 */ 334 */
324 private static DashScopeChatModel buildTongYiChatModel(String key) { 335 private static DashScopeChatModel buildTongYiChatModel(String key) {
325 - DashScopeApi dashScopeApi = new DashScopeApi(key); 336 + DashScopeApi dashScopeApi = DashScopeApi.builder().apiKey(key).build();
326 DashScopeChatOptions options = DashScopeChatOptions.builder().withModel(DashScopeApi.DEFAULT_CHAT_MODEL) 337 DashScopeChatOptions options = DashScopeChatOptions.builder().withModel(DashScopeApi.DEFAULT_CHAT_MODEL)
327 .withTemperature(0.7).build(); 338 .withTemperature(0.7).build();
328 - return new DashScopeChatModel(dashScopeApi, options, getFunctionCallbackResolver(), DEFAULT_RETRY_TEMPLATE); 339 + return DashScopeChatModel.builder()
  340 + .dashScopeApi(dashScopeApi)
  341 + .defaultOptions(options)
  342 + .toolCallingManager(getToolCallingManager())
  343 + .build();
329 } 344 }
330 345
331 /** 346 /**
332 - * 可参考 {@link DashScopeAutoConfiguration} 的 dashScopeImageModel 方法 347 + * 可参考 {@link DashScopeImageAutoConfiguration} 的 dashScopeImageModel 方法
333 */ 348 */
334 private static DashScopeImageModel buildTongYiImagesModel(String key) { 349 private static DashScopeImageModel buildTongYiImagesModel(String key) {
335 DashScopeImageApi dashScopeImageApi = new DashScopeImageApi(key); 350 DashScopeImageApi dashScopeImageApi = new DashScopeImageApi(key);
336 - return new DashScopeImageModel(dashScopeImageApi); 351 + return DashScopeImageModel.builder()
  352 + .dashScopeApi(dashScopeImageApi)
  353 + .build();
337 } 354 }
338 355
339 /** 356 /**
340 - * 可参考 {@link QianFanAutoConfiguration} 的 qianFanChatModel 方法 357 + * 可参考 {@link QianFanChatAutoConfiguration} 的 qianFanChatModel 方法
341 */ 358 */
342 private static QianFanChatModel buildYiYanChatModel(String key) { 359 private static QianFanChatModel buildYiYanChatModel(String key) {
  360 + // TODO @芋艿:未测试
343 List<String> keys = StrUtil.split(key, '|'); 361 List<String> keys = StrUtil.split(key, '|');
344 Assert.equals(keys.size(), 2, "YiYanChatClient 的密钥需要 (appKey|secretKey) 格式"); 362 Assert.equals(keys.size(), 2, "YiYanChatClient 的密钥需要 (appKey|secretKey) 格式");
345 String appKey = keys.get(0); 363 String appKey = keys.get(0);
@@ -349,9 +367,10 @@ public class AiModelFactoryImpl implements AiModelFactory { @@ -349,9 +367,10 @@ public class AiModelFactoryImpl implements AiModelFactory {
349 } 367 }
350 368
351 /** 369 /**
352 - * 可参考 {@link QianFanAutoConfiguration} 的 qianFanImageModel 方法 370 + * 可参考 {@link QianFanEmbeddingAutoConfiguration} 的 qianFanImageModel 方法
353 */ 371 */
354 private QianFanImageModel buildQianFanImageModel(String key) { 372 private QianFanImageModel buildQianFanImageModel(String key) {
  373 + // TODO @芋艿:未测试
355 List<String> keys = StrUtil.split(key, '|'); 374 List<String> keys = StrUtil.split(key, '|');
356 Assert.equals(keys.size(), 2, "YiYanChatClient 的密钥需要 (appKey|secretKey) 格式"); 375 Assert.equals(keys.size(), 2, "YiYanChatClient 的密钥需要 (appKey|secretKey) 格式");
357 String appKey = keys.get(0); 376 String appKey = keys.get(0);
@@ -361,12 +380,17 @@ public class AiModelFactoryImpl implements AiModelFactory { @@ -361,12 +380,17 @@ public class AiModelFactoryImpl implements AiModelFactory {
361 } 380 }
362 381
363 /** 382 /**
364 - * 可参考 {@link AiAutoConfiguration#deepSeekChatModel(YudaoAiProperties)} 383 + * 可参考 {@link DeepSeekChatAutoConfiguration} 的 deepSeekChatModel 方法
365 */ 384 */
366 private static DeepSeekChatModel buildDeepSeekChatModel(String apiKey) { 385 private static DeepSeekChatModel buildDeepSeekChatModel(String apiKey) {
367 - YudaoAiProperties.DeepSeekProperties properties = new YudaoAiProperties.DeepSeekProperties()  
368 - .setApiKey(apiKey);  
369 - return new AiAutoConfiguration().buildDeepSeekChatModel(properties); 386 + DeepSeekApi deepSeekApi = DeepSeekApi.builder().apiKey(apiKey).build();
  387 + DeepSeekChatOptions options = DeepSeekChatOptions.builder().model(DeepSeekApi.DEFAULT_CHAT_MODEL)
  388 + .temperature(0.7).build();
  389 + return DeepSeekChatModel.builder()
  390 + .deepSeekApi(deepSeekApi)
  391 + .defaultOptions(options)
  392 + .toolCallingManager(getToolCallingManager())
  393 + .build();
370 } 394 }
371 395
372 /** 396 /**
@@ -397,17 +421,18 @@ public class AiModelFactoryImpl implements AiModelFactory { @@ -397,17 +421,18 @@ public class AiModelFactoryImpl implements AiModelFactory {
397 } 421 }
398 422
399 /** 423 /**
400 - * 可参考 {@link ZhiPuAiAutoConfiguration} 的 zhiPuAiChatModel 方法 424 + * 可参考 {@link ZhiPuAiChatAutoConfiguration} 的 zhiPuAiChatModel 方法
401 */ 425 */
402 private ZhiPuAiChatModel buildZhiPuChatModel(String apiKey, String url) { 426 private ZhiPuAiChatModel buildZhiPuChatModel(String apiKey, String url) {
403 ZhiPuAiApi zhiPuAiApi = StrUtil.isEmpty(url) ? new ZhiPuAiApi(apiKey) 427 ZhiPuAiApi zhiPuAiApi = StrUtil.isEmpty(url) ? new ZhiPuAiApi(apiKey)
404 : new ZhiPuAiApi(url, apiKey); 428 : new ZhiPuAiApi(url, apiKey);
405 ZhiPuAiChatOptions options = ZhiPuAiChatOptions.builder().model(ZhiPuAiApi.DEFAULT_CHAT_MODEL).temperature(0.7).build(); 429 ZhiPuAiChatOptions options = ZhiPuAiChatOptions.builder().model(ZhiPuAiApi.DEFAULT_CHAT_MODEL).temperature(0.7).build();
406 - return new ZhiPuAiChatModel(zhiPuAiApi, options, getFunctionCallbackResolver(), DEFAULT_RETRY_TEMPLATE); 430 + return new ZhiPuAiChatModel(zhiPuAiApi, options, getToolCallingManager(), DEFAULT_RETRY_TEMPLATE,
  431 + getObservationRegistry().getIfAvailable());
407 } 432 }
408 433
409 /** 434 /**
410 - * 可参考 {@link ZhiPuAiAutoConfiguration} 的 zhiPuAiImageModel 方法 435 + * 可参考 {@link ZhiPuAiImageAutoConfiguration} 的 zhiPuAiImageModel 方法
411 */ 436 */
412 private ZhiPuAiImageModel buildZhiPuAiImageModel(String apiKey, String url) { 437 private ZhiPuAiImageModel buildZhiPuAiImageModel(String apiKey, String url) {
413 ZhiPuAiImageApi zhiPuAiApi = StrUtil.isEmpty(url) ? new ZhiPuAiImageApi(apiKey) 438 ZhiPuAiImageApi zhiPuAiApi = StrUtil.isEmpty(url) ? new ZhiPuAiImageApi(apiKey)
@@ -416,23 +441,30 @@ public class AiModelFactoryImpl implements AiModelFactory { @@ -416,23 +441,30 @@ public class AiModelFactoryImpl implements AiModelFactory {
416 } 441 }
417 442
418 /** 443 /**
419 - * 可参考 {@link MiniMaxAutoConfiguration} 的 miniMaxChatModel 方法 444 + * 可参考 {@link MiniMaxChatAutoConfiguration} 的 miniMaxChatModel 方法
420 */ 445 */
421 private MiniMaxChatModel buildMiniMaxChatModel(String apiKey, String url) { 446 private MiniMaxChatModel buildMiniMaxChatModel(String apiKey, String url) {
422 MiniMaxApi miniMaxApi = StrUtil.isEmpty(url) ? new MiniMaxApi(apiKey) 447 MiniMaxApi miniMaxApi = StrUtil.isEmpty(url) ? new MiniMaxApi(apiKey)
423 : new MiniMaxApi(url, apiKey); 448 : new MiniMaxApi(url, apiKey);
424 MiniMaxChatOptions options = MiniMaxChatOptions.builder().model(MiniMaxApi.DEFAULT_CHAT_MODEL).temperature(0.7).build(); 449 MiniMaxChatOptions options = MiniMaxChatOptions.builder().model(MiniMaxApi.DEFAULT_CHAT_MODEL).temperature(0.7).build();
425 - return new MiniMaxChatModel(miniMaxApi, options, getFunctionCallbackResolver(), DEFAULT_RETRY_TEMPLATE); 450 + return new MiniMaxChatModel(miniMaxApi, options, getToolCallingManager(), DEFAULT_RETRY_TEMPLATE);
426 } 451 }
427 452
428 /** 453 /**
429 - * 可参考 {@link MoonshotAutoConfiguration} 的 moonshotChatModel 方法 454 + * 可参考 {@link MoonshotChatAutoConfiguration} 的 moonshotChatModel 方法
430 */ 455 */
431 private MoonshotChatModel buildMoonshotChatModel(String apiKey, String url) { 456 private MoonshotChatModel buildMoonshotChatModel(String apiKey, String url) {
432 - MoonshotApi moonshotApi = StrUtil.isEmpty(url)? new MoonshotApi(apiKey)  
433 - : new MoonshotApi(url, apiKey); 457 + MoonshotApi.Builder moonshotApiBuilder = MoonshotApi.builder()
  458 + .apiKey(apiKey);
  459 + if (StrUtil.isNotEmpty(url)) {
  460 + moonshotApiBuilder.baseUrl(url);
  461 + }
434 MoonshotChatOptions options = MoonshotChatOptions.builder().model(MoonshotApi.DEFAULT_CHAT_MODEL).build(); 462 MoonshotChatOptions options = MoonshotChatOptions.builder().model(MoonshotApi.DEFAULT_CHAT_MODEL).build();
435 - return new MoonshotChatModel(moonshotApi, options, getFunctionCallbackResolver(), DEFAULT_RETRY_TEMPLATE); 463 + return MoonshotChatModel.builder()
  464 + .moonshotApi(moonshotApiBuilder.build())
  465 + .defaultOptions(options)
  466 + .toolCallingManager(getToolCallingManager())
  467 + .build();
436 } 468 }
437 469
438 /** 470 /**
@@ -456,33 +488,32 @@ public class AiModelFactoryImpl implements AiModelFactory { @@ -456,33 +488,32 @@ public class AiModelFactoryImpl implements AiModelFactory {
456 } 488 }
457 489
458 /** 490 /**
459 - * 可参考 {@link OpenAiAutoConfiguration} 的 openAiChatModel 方法 491 + * 可参考 {@link OpenAiChatAutoConfiguration} 的 openAiChatModel 方法
460 */ 492 */
461 private static OpenAiChatModel buildOpenAiChatModel(String openAiToken, String url) { 493 private static OpenAiChatModel buildOpenAiChatModel(String openAiToken, String url) {
462 url = StrUtil.blankToDefault(url, OpenAiApiConstants.DEFAULT_BASE_URL); 494 url = StrUtil.blankToDefault(url, OpenAiApiConstants.DEFAULT_BASE_URL);
463 OpenAiApi openAiApi = OpenAiApi.builder().baseUrl(url).apiKey(openAiToken).build(); 495 OpenAiApi openAiApi = OpenAiApi.builder().baseUrl(url).apiKey(openAiToken).build();
464 - return OpenAiChatModel.builder().openAiApi(openAiApi).toolCallingManager(getToolCallingManager()).build(); 496 + return OpenAiChatModel.builder()
  497 + .openAiApi(openAiApi)
  498 + .toolCallingManager(getToolCallingManager())
  499 + .build();
465 } 500 }
466 501
467 - // TODO @芋艿:手头暂时没密钥,使用建议再测试下  
468 /** 502 /**
469 - * 可参考 {@link AzureOpenAiAutoConfiguration} 503 + * 可参考 {@link AzureOpenAiChatAutoConfiguration}
470 */ 504 */
471 private static AzureOpenAiChatModel buildAzureOpenAiChatModel(String apiKey, String url) { 505 private static AzureOpenAiChatModel buildAzureOpenAiChatModel(String apiKey, String url) {
472 - AzureOpenAiAutoConfiguration azureOpenAiAutoConfiguration = new AzureOpenAiAutoConfiguration();  
473 - // 创建 OpenAIClient 对象  
474 - AzureOpenAiConnectionProperties connectionProperties = new AzureOpenAiConnectionProperties();  
475 - connectionProperties.setApiKey(apiKey);  
476 - connectionProperties.setEndpoint(url);  
477 - OpenAIClientBuilder openAIClient = azureOpenAiAutoConfiguration.openAIClientBuilder(connectionProperties, null);  
478 - // 获取 AzureOpenAiChatProperties 对象  
479 - AzureOpenAiChatProperties chatProperties = SpringUtil.getBean(AzureOpenAiChatProperties.class);  
480 - return azureOpenAiAutoConfiguration.azureOpenAiChatModel(openAIClient, chatProperties,  
481 - getToolCallingManager(), null, null); 506 + // TODO @芋艿:使用前,请测试,暂时没密钥!!!
  507 + OpenAIClientBuilder openAIClientBuilder = new OpenAIClientBuilder()
  508 + .endpoint(url).credential(new KeyCredential(apiKey));
  509 + return AzureOpenAiChatModel.builder()
  510 + .openAIClientBuilder(openAIClientBuilder)
  511 + .toolCallingManager(getToolCallingManager())
  512 + .build();
482 } 513 }
483 514
484 /** 515 /**
485 - * 可参考 {@link OpenAiAutoConfiguration} 的 openAiImageModel 方法 516 + * 可参考 {@link OpenAiImageAutoConfiguration} 的 openAiImageModel 方法
486 */ 517 */
487 private OpenAiImageModel buildOpenAiImageModel(String openAiToken, String url) { 518 private OpenAiImageModel buildOpenAiImageModel(String openAiToken, String url) {
488 url = StrUtil.blankToDefault(url, OpenAiApiConstants.DEFAULT_BASE_URL); 519 url = StrUtil.blankToDefault(url, OpenAiApiConstants.DEFAULT_BASE_URL);
@@ -494,16 +525,18 @@ public class AiModelFactoryImpl implements AiModelFactory { @@ -494,16 +525,18 @@ public class AiModelFactoryImpl implements AiModelFactory {
494 * 创建 SiliconFlowImageModel 对象 525 * 创建 SiliconFlowImageModel 对象
495 */ 526 */
496 private SiliconFlowImageModel buildSiliconFlowImageModel(String apiToken, String url) { 527 private SiliconFlowImageModel buildSiliconFlowImageModel(String apiToken, String url) {
  528 + // TODO @芋艿:未测试
497 url = StrUtil.blankToDefault(url, SiliconFlowApiConstants.DEFAULT_BASE_URL); 529 url = StrUtil.blankToDefault(url, SiliconFlowApiConstants.DEFAULT_BASE_URL);
498 SiliconFlowImageApi openAiApi = new SiliconFlowImageApi(url, apiToken); 530 SiliconFlowImageApi openAiApi = new SiliconFlowImageApi(url, apiToken);
499 return new SiliconFlowImageModel(openAiApi); 531 return new SiliconFlowImageModel(openAiApi);
500 } 532 }
501 533
502 /** 534 /**
503 - * 可参考 {@link OllamaAutoConfiguration} 的 ollamaApi 方法 535 + * 可参考 {@link OllamaChatAutoConfiguration} 的 ollamaChatModel 方法
504 */ 536 */
505 private static OllamaChatModel buildOllamaChatModel(String url) { 537 private static OllamaChatModel buildOllamaChatModel(String url) {
506 - OllamaApi ollamaApi = new OllamaApi(url); 538 + // TODO @芋艿:未测试
  539 + OllamaApi ollamaApi = OllamaApi.builder().baseUrl(url).build();
507 return OllamaChatModel.builder().ollamaApi(ollamaApi).toolCallingManager(getToolCallingManager()).build(); 540 return OllamaChatModel.builder().ollamaApi(ollamaApi).toolCallingManager(getToolCallingManager()).build();
508 } 541 }
509 542
@@ -519,16 +552,16 @@ public class AiModelFactoryImpl implements AiModelFactory { @@ -519,16 +552,16 @@ public class AiModelFactoryImpl implements AiModelFactory {
519 // ========== 各种创建 EmbeddingModel 的方法 ========== 552 // ========== 各种创建 EmbeddingModel 的方法 ==========
520 553
521 /** 554 /**
522 - * 可参考 {@link DashScopeAutoConfiguration} 的 dashscopeEmbeddingModel 方法 555 + * 可参考 {@link DashScopeEmbeddingAutoConfiguration} 的 dashscopeEmbeddingModel 方法
523 */ 556 */
524 private DashScopeEmbeddingModel buildTongYiEmbeddingModel(String apiKey, String model) { 557 private DashScopeEmbeddingModel buildTongYiEmbeddingModel(String apiKey, String model) {
525 - DashScopeApi dashScopeApi = new DashScopeApi(apiKey); 558 + DashScopeApi dashScopeApi = DashScopeApi.builder().apiKey(apiKey).build();
526 DashScopeEmbeddingOptions dashScopeEmbeddingOptions = DashScopeEmbeddingOptions.builder().withModel(model).build(); 559 DashScopeEmbeddingOptions dashScopeEmbeddingOptions = DashScopeEmbeddingOptions.builder().withModel(model).build();
527 return new DashScopeEmbeddingModel(dashScopeApi, MetadataMode.EMBED, dashScopeEmbeddingOptions); 560 return new DashScopeEmbeddingModel(dashScopeApi, MetadataMode.EMBED, dashScopeEmbeddingOptions);
528 } 561 }
529 562
530 /** 563 /**
531 - * 可参考 {@link ZhiPuAiAutoConfiguration} 的 zhiPuAiEmbeddingModel 方法 564 + * 可参考 {@link ZhiPuAiEmbeddingAutoConfiguration} 的 zhiPuAiEmbeddingModel 方法
532 */ 565 */
533 private ZhiPuAiEmbeddingModel buildZhiPuEmbeddingModel(String apiKey, String url, String model) { 566 private ZhiPuAiEmbeddingModel buildZhiPuEmbeddingModel(String apiKey, String url, String model) {
534 ZhiPuAiApi zhiPuAiApi = StrUtil.isEmpty(url) ? new ZhiPuAiApi(apiKey) 567 ZhiPuAiApi zhiPuAiApi = StrUtil.isEmpty(url) ? new ZhiPuAiApi(apiKey)
@@ -538,7 +571,7 @@ public class AiModelFactoryImpl implements AiModelFactory { @@ -538,7 +571,7 @@ public class AiModelFactoryImpl implements AiModelFactory {
538 } 571 }
539 572
540 /** 573 /**
541 - * 可参考 {@link MiniMaxAutoConfiguration} 的 miniMaxEmbeddingModel 方法 574 + * 可参考 {@link MiniMaxEmbeddingAutoConfiguration} 的 miniMaxEmbeddingModel 方法
542 */ 575 */
543 private EmbeddingModel buildMiniMaxEmbeddingModel(String apiKey, String url, String model) { 576 private EmbeddingModel buildMiniMaxEmbeddingModel(String apiKey, String url, String model) {
544 MiniMaxApi miniMaxApi = StrUtil.isEmpty(url)? new MiniMaxApi(apiKey) 577 MiniMaxApi miniMaxApi = StrUtil.isEmpty(url)? new MiniMaxApi(apiKey)
@@ -548,7 +581,7 @@ public class AiModelFactoryImpl implements AiModelFactory { @@ -548,7 +581,7 @@ public class AiModelFactoryImpl implements AiModelFactory {
548 } 581 }
549 582
550 /** 583 /**
551 - * 可参考 {@link QianFanAutoConfiguration} 的 qianFanEmbeddingModel 方法 584 + * 可参考 {@link QianFanEmbeddingAutoConfiguration} 的 qianFanEmbeddingModel 方法
552 */ 585 */
553 private QianFanEmbeddingModel buildYiYanEmbeddingModel(String key, String model) { 586 private QianFanEmbeddingModel buildYiYanEmbeddingModel(String key, String model) {
554 List<String> keys = StrUtil.split(key, '|'); 587 List<String> keys = StrUtil.split(key, '|');
@@ -561,13 +594,13 @@ public class AiModelFactoryImpl implements AiModelFactory { @@ -561,13 +594,13 @@ public class AiModelFactoryImpl implements AiModelFactory {
561 } 594 }
562 595
563 private OllamaEmbeddingModel buildOllamaEmbeddingModel(String url, String model) { 596 private OllamaEmbeddingModel buildOllamaEmbeddingModel(String url, String model) {
564 - OllamaApi ollamaApi = new OllamaApi(url); 597 + OllamaApi ollamaApi = OllamaApi.builder().baseUrl(url).build();
565 OllamaOptions ollamaOptions = OllamaOptions.builder().model(model).build(); 598 OllamaOptions ollamaOptions = OllamaOptions.builder().model(model).build();
566 return OllamaEmbeddingModel.builder().ollamaApi(ollamaApi).defaultOptions(ollamaOptions).build(); 599 return OllamaEmbeddingModel.builder().ollamaApi(ollamaApi).defaultOptions(ollamaOptions).build();
567 } 600 }
568 601
569 /** 602 /**
570 - * 可参考 {@link OpenAiAutoConfiguration} 的 openAiEmbeddingModel 方法 603 + * 可参考 {@link OpenAiEmbeddingAutoConfiguration} 的 openAiEmbeddingModel 方法
571 */ 604 */
572 private OpenAiEmbeddingModel buildOpenAiEmbeddingModel(String openAiToken, String url, String model) { 605 private OpenAiEmbeddingModel buildOpenAiEmbeddingModel(String openAiToken, String url, String model) {
573 url = StrUtil.blankToDefault(url, OpenAiApiConstants.DEFAULT_BASE_URL); 606 url = StrUtil.blankToDefault(url, OpenAiApiConstants.DEFAULT_BASE_URL);
@@ -576,21 +609,19 @@ public class AiModelFactoryImpl implements AiModelFactory { @@ -576,21 +609,19 @@ public class AiModelFactoryImpl implements AiModelFactory {
576 return new OpenAiEmbeddingModel(openAiApi, MetadataMode.EMBED, openAiEmbeddingProperties); 609 return new OpenAiEmbeddingModel(openAiApi, MetadataMode.EMBED, openAiEmbeddingProperties);
577 } 610 }
578 611
579 - // TODO @芋艿:手头暂时没密钥,使用建议再测试下  
580 /** 612 /**
581 - * 可参考 {@link AzureOpenAiAutoConfiguration} 的 azureOpenAiEmbeddingModel 方法 613 + * 可参考 {@link AzureOpenAiEmbeddingAutoConfiguration} 的 azureOpenAiEmbeddingModel 方法
582 */ 614 */
583 private AzureOpenAiEmbeddingModel buildAzureOpenAiEmbeddingModel(String apiKey, String url, String model) { 615 private AzureOpenAiEmbeddingModel buildAzureOpenAiEmbeddingModel(String apiKey, String url, String model) {
584 - AzureOpenAiAutoConfiguration azureOpenAiAutoConfiguration = new AzureOpenAiAutoConfiguration();  
585 - // 创建 OpenAIClient 对象  
586 - AzureOpenAiConnectionProperties connectionProperties = new AzureOpenAiConnectionProperties();  
587 - connectionProperties.setApiKey(apiKey);  
588 - connectionProperties.setEndpoint(url);  
589 - OpenAIClientBuilder openAIClient = azureOpenAiAutoConfiguration.openAIClientBuilder(connectionProperties, null); 616 + // TODO @芋艿:手头暂时没密钥,使用建议再测试下
  617 + AzureOpenAiEmbeddingAutoConfiguration azureOpenAiAutoConfiguration = new AzureOpenAiEmbeddingAutoConfiguration();
  618 + // 创建 OpenAIClientBuilder 对象
  619 + OpenAIClientBuilder openAIClientBuilder = new OpenAIClientBuilder()
  620 + .endpoint(url).credential(new KeyCredential(apiKey));
590 // 获取 AzureOpenAiChatProperties 对象 621 // 获取 AzureOpenAiChatProperties 对象
591 AzureOpenAiEmbeddingProperties embeddingProperties = SpringUtil.getBean(AzureOpenAiEmbeddingProperties.class); 622 AzureOpenAiEmbeddingProperties embeddingProperties = SpringUtil.getBean(AzureOpenAiEmbeddingProperties.class);
592 - return azureOpenAiAutoConfiguration.azureOpenAiEmbeddingModel(openAIClient, embeddingProperties,  
593 - null, null); 623 + return azureOpenAiAutoConfiguration.azureOpenAiEmbeddingModel(openAIClientBuilder, embeddingProperties,
  624 + getObservationRegistry(), getEmbeddingModelObservationConvention());
594 } 625 }
595 626
596 // ========== 各种创建 VectorStore 的方法 ========== 627 // ========== 各种创建 VectorStore 的方法 ==========
@@ -657,10 +688,11 @@ public class AiModelFactoryImpl implements AiModelFactory { @@ -657,10 +688,11 @@ public class AiModelFactoryImpl implements AiModelFactory {
657 RedisProperties redisProperties = SpringUtils.getBean(RedisProperties.class); 688 RedisProperties redisProperties = SpringUtils.getBean(RedisProperties.class);
658 JedisPooled jedisPooled = new JedisPooled(redisProperties.getHost(), redisProperties.getPort()); 689 JedisPooled jedisPooled = new JedisPooled(redisProperties.getHost(), redisProperties.getPort());
659 // 创建 RedisVectorStoreProperties 对象 690 // 创建 RedisVectorStoreProperties 对象
  691 + // TODO @芋艿:index-name 可能影响索引名;
660 RedisVectorStoreAutoConfiguration configuration = new RedisVectorStoreAutoConfiguration(); 692 RedisVectorStoreAutoConfiguration configuration = new RedisVectorStoreAutoConfiguration();
661 RedisVectorStoreProperties properties = SpringUtil.getBean(RedisVectorStoreProperties.class); 693 RedisVectorStoreProperties properties = SpringUtil.getBean(RedisVectorStoreProperties.class);
662 RedisVectorStore redisVectorStore = RedisVectorStore.builder(jedisPooled, embeddingModel) 694 RedisVectorStore redisVectorStore = RedisVectorStore.builder(jedisPooled, embeddingModel)
663 - .indexName(properties.getIndex()).prefix(properties.getPrefix()) 695 + .indexName(properties.getIndexName()).prefix(properties.getPrefix())
664 .initializeSchema(properties.isInitializeSchema()) 696 .initializeSchema(properties.isInitializeSchema())
665 .metadataFields(convertList(metadataFields.entrySet(), entry -> { 697 .metadataFields(convertList(metadataFields.entrySet(), entry -> {
666 String fieldName = entry.getKey(); 698 String fieldName = entry.getKey();
@@ -730,10 +762,12 @@ public class AiModelFactoryImpl implements AiModelFactory { @@ -730,10 +762,12 @@ public class AiModelFactoryImpl implements AiModelFactory {
730 762
731 private static ObjectProvider<VectorStoreObservationConvention> getCustomObservationConvention() { 763 private static ObjectProvider<VectorStoreObservationConvention> getCustomObservationConvention() {
732 return new ObjectProvider<>() { 764 return new ObjectProvider<>() {
  765 +
733 @Override 766 @Override
734 public VectorStoreObservationConvention getObject() throws BeansException { 767 public VectorStoreObservationConvention getObject() throws BeansException {
735 return new DefaultVectorStoreObservationConvention(); 768 return new DefaultVectorStoreObservationConvention();
736 } 769 }
  770 +
737 }; 771 };
738 } 772 }
739 773
@@ -745,8 +779,15 @@ public class AiModelFactoryImpl implements AiModelFactory { @@ -745,8 +779,15 @@ public class AiModelFactoryImpl implements AiModelFactory {
745 return SpringUtil.getBean(ToolCallingManager.class); 779 return SpringUtil.getBean(ToolCallingManager.class);
746 } 780 }
747 781
748 - private static FunctionCallbackResolver getFunctionCallbackResolver() {  
749 - return SpringUtil.getBean(FunctionCallbackResolver.class); 782 + private static ObjectProvider<EmbeddingModelObservationConvention> getEmbeddingModelObservationConvention() {
  783 + return new ObjectProvider<>() {
  784 +
  785 + @Override
  786 + public EmbeddingModelObservationConvention getObject() throws BeansException {
  787 + return SpringUtil.getBean(EmbeddingModelObservationConvention.class);
  788 + }
  789 +
  790 + };
750 } 791 }
751 792
752 } 793 }
yudao-module-ai/src/test/java/cn/iocoder/yudao/module/ai/framework/ai/core/model/chat/AzureOpenAIChatModelTests.java
@@ -2,7 +2,6 @@ package cn.iocoder.yudao.module.ai.framework.ai.core.model.chat; @@ -2,7 +2,6 @@ package cn.iocoder.yudao.module.ai.framework.ai.core.model.chat;
2 2
3 import com.azure.ai.openai.OpenAIClientBuilder; 3 import com.azure.ai.openai.OpenAIClientBuilder;
4 import com.azure.core.credential.AzureKeyCredential; 4 import com.azure.core.credential.AzureKeyCredential;
5 -import com.azure.core.util.ClientOptions;  
6 import org.junit.jupiter.api.Disabled; 5 import org.junit.jupiter.api.Disabled;
7 import org.junit.jupiter.api.Test; 6 import org.junit.jupiter.api.Test;
8 import org.springframework.ai.azure.openai.AzureOpenAiChatModel; 7 import org.springframework.ai.azure.openai.AzureOpenAiChatModel;
@@ -17,7 +16,7 @@ import reactor.core.publisher.Flux; @@ -17,7 +16,7 @@ import reactor.core.publisher.Flux;
17 import java.util.ArrayList; 16 import java.util.ArrayList;
18 import java.util.List; 17 import java.util.List;
19 18
20 -import static org.springframework.ai.autoconfigure.azure.openai.AzureOpenAiChatProperties.DEFAULT_DEPLOYMENT_NAME; 19 +import static org.springframework.ai.model.azure.openai.autoconfigure.AzureOpenAiChatProperties.DEFAULT_DEPLOYMENT_NAME;
21 20
22 /** 21 /**
23 * {@link AzureOpenAiChatModel} 集成测试 22 * {@link AzureOpenAiChatModel} 集成测试
@@ -29,10 +28,13 @@ public class AzureOpenAIChatModelTests { @@ -29,10 +28,13 @@ public class AzureOpenAIChatModelTests {
29 // TODO @芋艿:晚点在调整 28 // TODO @芋艿:晚点在调整
30 private final OpenAIClientBuilder openAiApi = new OpenAIClientBuilder() 29 private final OpenAIClientBuilder openAiApi = new OpenAIClientBuilder()
31 .endpoint("https://eastusprejade.openai.azure.com") 30 .endpoint("https://eastusprejade.openai.azure.com")
32 - .credential(new AzureKeyCredential("xxx"))  
33 - .clientOptions((new ClientOptions()).setApplicationId("spring-ai"));  
34 - private final AzureOpenAiChatModel chatModel = new AzureOpenAiChatModel(openAiApi,  
35 - AzureOpenAiChatOptions.builder().deploymentName(DEFAULT_DEPLOYMENT_NAME).build()); 31 + .credential(new AzureKeyCredential("xxx"));
  32 + private final AzureOpenAiChatModel chatModel = AzureOpenAiChatModel.builder()
  33 + .openAIClientBuilder(openAiApi)
  34 + .defaultOptions(AzureOpenAiChatOptions.builder()
  35 + .deploymentName(DEFAULT_DEPLOYMENT_NAME)
  36 + .build())
  37 + .build();
36 38
37 @Test 39 @Test
38 @Disabled 40 @Disabled
yudao-module-ai/src/test/java/cn/iocoder/yudao/module/ai/framework/ai/core/model/chat/BaiChuanChatModelTests.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 cn.iocoder.yudao.module.ai.framework.ai.core.model.baichuan.BaiChuanChatModel; 3 import cn.iocoder.yudao.module.ai.framework.ai.core.model.baichuan.BaiChuanChatModel;
4 -import cn.iocoder.yudao.module.ai.framework.ai.core.model.deepseek.DeepSeekChatModel;  
5 import org.junit.jupiter.api.Disabled; 4 import org.junit.jupiter.api.Disabled;
6 import org.junit.jupiter.api.Test; 5 import org.junit.jupiter.api.Test;
7 import org.springframework.ai.chat.messages.Message; 6 import org.springframework.ai.chat.messages.Message;
@@ -35,7 +34,7 @@ public class BaiChuanChatModelTests { @@ -35,7 +34,7 @@ public class BaiChuanChatModelTests {
35 .build()) 34 .build())
36 .build(); 35 .build();
37 36
38 - private final DeepSeekChatModel chatModel = new DeepSeekChatModel(openAiChatModel); 37 + private final BaiChuanChatModel chatModel = new BaiChuanChatModel(openAiChatModel);
39 38
40 @Test 39 @Test
41 @Disabled 40 @Disabled
yudao-module-ai/src/test/java/cn/iocoder/yudao/module/ai/framework/ai/core/model/chat/MoonshotChatModelTests.java
@@ -2,14 +2,14 @@ package cn.iocoder.yudao.module.ai.framework.ai.core.model.chat; @@ -2,14 +2,14 @@ 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.moonshot.MoonshotChatModel;
  6 +import org.springaicommunity.moonshot.MoonshotChatOptions;
  7 +import org.springaicommunity.moonshot.api.MoonshotApi;
5 import org.springframework.ai.chat.messages.Message; 8 import org.springframework.ai.chat.messages.Message;
6 import org.springframework.ai.chat.messages.SystemMessage; 9 import org.springframework.ai.chat.messages.SystemMessage;
7 import org.springframework.ai.chat.messages.UserMessage; 10 import org.springframework.ai.chat.messages.UserMessage;
8 import org.springframework.ai.chat.model.ChatResponse; 11 import org.springframework.ai.chat.model.ChatResponse;
9 import org.springframework.ai.chat.prompt.Prompt; 12 import org.springframework.ai.chat.prompt.Prompt;
10 -import org.springframework.ai.moonshot.MoonshotChatModel;  
11 -import org.springframework.ai.moonshot.MoonshotChatOptions;  
12 -import org.springframework.ai.moonshot.api.MoonshotApi;  
13 import reactor.core.publisher.Flux; 13 import reactor.core.publisher.Flux;
14 14
15 import java.util.ArrayList; 15 import java.util.ArrayList;
@@ -22,11 +22,15 @@ import java.util.List; @@ -22,11 +22,15 @@ import java.util.List;
22 */ 22 */
23 public class MoonshotChatModelTests { 23 public class MoonshotChatModelTests {
24 24
25 - private final MoonshotChatModel chatModel = new MoonshotChatModel(  
26 - new MoonshotApi("sk-aHYYV1SARscItye5QQRRNbXij4fy65Ee7pNZlC9gsSQnUKXA"), // 密钥  
27 - MoonshotChatOptions.builder()  
28 - .model("moonshot-v1-8k") // 模型  
29 - .build()); 25 + private final MoonshotChatModel chatModel = MoonshotChatModel.builder()
  26 + .moonshotApi(MoonshotApi.builder()
  27 + .apiKey("sk-aHYYV1SARscItye5QQRRNbXij4fy65Ee7pNZlC9gsSQnUKXA") // 密钥
  28 + .build())
  29 + .defaultOptions(MoonshotChatOptions.builder()
  30 + .model("kimi-k2-0711-preview") // 模型
  31 + .build())
  32 + .build();
  33 +
30 @Test 34 @Test
31 @Disabled 35 @Disabled
32 public void testCall() { 36 public void testCall() {
yudao-module-ai/src/test/java/cn/iocoder/yudao/module/ai/framework/ai/core/model/image/StabilityAiImageModelTests.java
@@ -31,8 +31,8 @@ public class StabilityAiImageModelTests { @@ -31,8 +31,8 @@ public class StabilityAiImageModelTests {
31 public void testCall() { 31 public void testCall() {
32 // 准备参数 32 // 准备参数
33 ImageOptions options = OpenAiImageOptions.builder() 33 ImageOptions options = OpenAiImageOptions.builder()
34 - .withModel("stable-diffusion-v1-6")  
35 - .withHeight(320).withWidth(320) 34 + .model("stable-diffusion-v1-6")
  35 + .height(320).width(320)
36 .build(); 36 .build();
37 ImagePrompt prompt = new ImagePrompt("great wall", options); 37 ImagePrompt prompt = new ImagePrompt("great wall", options);
38 38
yudao-server/src/main/resources/application.yaml
@@ -188,13 +188,14 @@ spring: @@ -188,13 +188,14 @@ spring:
188 api-key: xxxx 188 api-key: xxxx
189 moonshot: # 月之暗灭(KIMI) 189 moonshot: # 月之暗灭(KIMI)
190 api-key: sk-abc 190 api-key: sk-abc
  191 + deepseek: # DeepSeek
  192 + api-key: sk-e94db327cc7d457d99a8de8810fc6b12
  193 + chat:
  194 + options:
  195 + model: deepseek-chat
191 196
192 yudao: 197 yudao:
193 ai: 198 ai:
194 - deep-seek: # DeepSeek  
195 - enable: true  
196 - api-key: sk-e94db327cc7d457d99a8de8810fc6b12  
197 - model: deepseek-chat  
198 doubao: # 字节豆包 199 doubao: # 字节豆包
199 enable: true 200 enable: true
200 api-key: 5c1b5747-26d2-4ebd-a4e0-dd0e8d8b4272 201 api-key: 5c1b5747-26d2-4ebd-a4e0-dd0e8d8b4272