Commit 9d149f414747278cab75b3e12038bafb7dab3d58

Authored by YunaiV
1 parent 96a74315

feat:【ai 大模型】增加 gemini 接入

yudao-module-ai/src/main/java/cn/iocoder/yudao/module/ai/enums/model/AiPlatformEnum.java
@@ -34,6 +34,7 @@ public enum AiPlatformEnum implements ArrayValuable<String> { @@ -34,6 +34,7 @@ public enum AiPlatformEnum implements ArrayValuable<String> {
34 OPENAI("OpenAI", "OpenAI"), // OpenAI 官方 34 OPENAI("OpenAI", "OpenAI"), // OpenAI 官方
35 AZURE_OPENAI("AzureOpenAI", "AzureOpenAI"), // OpenAI 微软 35 AZURE_OPENAI("AzureOpenAI", "AzureOpenAI"), // OpenAI 微软
36 ANTHROPIC("Anthropic", "Anthropic"), // Anthropic Claude 36 ANTHROPIC("Anthropic", "Anthropic"), // Anthropic Claude
  37 + GEMINI("Gemini", "Gemini"), // 谷歌 Gemini
37 OLLAMA("Ollama", "Ollama"), 38 OLLAMA("Ollama", "Ollama"),
38 39
39 STABLE_DIFFUSION("StableDiffusion", "StableDiffusion"), // Stability AI 40 STABLE_DIFFUSION("StableDiffusion", "StableDiffusion"), // Stability AI
yudao-module-ai/src/main/java/cn/iocoder/yudao/module/ai/framework/ai/config/AiAutoConfiguration.java
@@ -6,6 +6,7 @@ import cn.iocoder.yudao.module.ai.framework.ai.core.AiModelFactory; @@ -6,6 +6,7 @@ import cn.iocoder.yudao.module.ai.framework.ai.core.AiModelFactory;
6 import cn.iocoder.yudao.module.ai.framework.ai.core.AiModelFactoryImpl; 6 import cn.iocoder.yudao.module.ai.framework.ai.core.AiModelFactoryImpl;
7 import cn.iocoder.yudao.module.ai.framework.ai.core.model.baichuan.BaiChuanChatModel; 7 import cn.iocoder.yudao.module.ai.framework.ai.core.model.baichuan.BaiChuanChatModel;
8 import cn.iocoder.yudao.module.ai.framework.ai.core.model.doubao.DouBaoChatModel; 8 import cn.iocoder.yudao.module.ai.framework.ai.core.model.doubao.DouBaoChatModel;
  9 +import cn.iocoder.yudao.module.ai.framework.ai.core.model.gemini.GeminiChatModel;
9 import cn.iocoder.yudao.module.ai.framework.ai.core.model.hunyuan.HunYuanChatModel; 10 import cn.iocoder.yudao.module.ai.framework.ai.core.model.hunyuan.HunYuanChatModel;
10 import cn.iocoder.yudao.module.ai.framework.ai.core.model.midjourney.api.MidjourneyApi; 11 import cn.iocoder.yudao.module.ai.framework.ai.core.model.midjourney.api.MidjourneyApi;
11 import cn.iocoder.yudao.module.ai.framework.ai.core.model.siliconflow.SiliconFlowApiConstants; 12 import cn.iocoder.yudao.module.ai.framework.ai.core.model.siliconflow.SiliconFlowApiConstants;
@@ -52,6 +53,34 @@ public class AiAutoConfiguration { @@ -52,6 +53,34 @@ public class AiAutoConfiguration {
52 // ========== 各种 AI Client 创建 ========== 53 // ========== 各种 AI Client 创建 ==========
53 54
54 @Bean 55 @Bean
  56 + @ConditionalOnProperty(value = "yudao.ai.gemini.enable", havingValue = "true")
  57 + public GeminiChatModel geminiChatModel(YudaoAiProperties yudaoAiProperties) {
  58 + YudaoAiProperties.GeminiProperties properties = yudaoAiProperties.getGemini();
  59 + return buildGeminiChatClient(properties);
  60 + }
  61 +
  62 + public GeminiChatModel buildGeminiChatClient(YudaoAiProperties.GeminiProperties properties) {
  63 + if (StrUtil.isEmpty(properties.getModel())) {
  64 + properties.setModel(GeminiChatModel.MODEL_DEFAULT);
  65 + }
  66 + OpenAiChatModel openAiChatModel = OpenAiChatModel.builder()
  67 + .openAiApi(OpenAiApi.builder()
  68 + .baseUrl(GeminiChatModel.BASE_URL)
  69 + .completionsPath(GeminiChatModel.COMPLETE_PATH)
  70 + .apiKey(properties.getApiKey())
  71 + .build())
  72 + .defaultOptions(OpenAiChatOptions.builder()
  73 + .model(properties.getModel())
  74 + .temperature(properties.getTemperature())
  75 + .maxTokens(properties.getMaxTokens())
  76 + .topP(properties.getTopP())
  77 + .build())
  78 + .toolCallingManager(getToolCallingManager())
  79 + .build();
  80 + return new GeminiChatModel(openAiChatModel);
  81 + }
  82 +
  83 + @Bean
55 @ConditionalOnProperty(value = "yudao.ai.doubao.enable", havingValue = "true") 84 @ConditionalOnProperty(value = "yudao.ai.doubao.enable", havingValue = "true")
56 public DouBaoChatModel douBaoChatClient(YudaoAiProperties yudaoAiProperties) { 85 public DouBaoChatModel douBaoChatClient(YudaoAiProperties yudaoAiProperties) {
57 YudaoAiProperties.DouBaoProperties properties = yudaoAiProperties.getDoubao(); 86 YudaoAiProperties.DouBaoProperties properties = yudaoAiProperties.getDoubao();
@@ -150,17 +179,22 @@ public class AiAutoConfiguration { @@ -150,17 +179,22 @@ public class AiAutoConfiguration {
150 if (StrUtil.isEmpty(properties.getModel())) { 179 if (StrUtil.isEmpty(properties.getModel())) {
151 properties.setModel(XingHuoChatModel.MODEL_DEFAULT); 180 properties.setModel(XingHuoChatModel.MODEL_DEFAULT);
152 } 181 }
  182 + OpenAiApi.Builder builder = OpenAiApi.builder()
  183 + .baseUrl(XingHuoChatModel.BASE_URL_V1)
  184 + .apiKey(properties.getAppKey() + ":" + properties.getSecretKey());
  185 + if ("x1".equals(properties.getModel())) {
  186 + builder.baseUrl(XingHuoChatModel.BASE_URL_V2)
  187 + .completionsPath(XingHuoChatModel.BASE_COMPLETIONS_PATH_V2);
  188 + }
153 OpenAiChatModel openAiChatModel = OpenAiChatModel.builder() 189 OpenAiChatModel openAiChatModel = OpenAiChatModel.builder()
154 - .openAiApi(OpenAiApi.builder()  
155 - .baseUrl(XingHuoChatModel.BASE_URL)  
156 - .apiKey(properties.getAppKey() + ":" + properties.getSecretKey())  
157 - .build()) 190 + .openAiApi(builder.build())
158 .defaultOptions(OpenAiChatOptions.builder() 191 .defaultOptions(OpenAiChatOptions.builder()
159 .model(properties.getModel()) 192 .model(properties.getModel())
160 .temperature(properties.getTemperature()) 193 .temperature(properties.getTemperature())
161 .maxTokens(properties.getMaxTokens()) 194 .maxTokens(properties.getMaxTokens())
162 .topP(properties.getTopP()) 195 .topP(properties.getTopP())
163 .build()) 196 .build())
  197 + // TODO @芋艿:星火的 function call 有 bug,会报 ToolResponseMessage must have an id 错误!!!
164 .toolCallingManager(getToolCallingManager()) 198 .toolCallingManager(getToolCallingManager())
165 .build(); 199 .build();
166 return new XingHuoChatModel(openAiChatModel); 200 return new XingHuoChatModel(openAiChatModel);
yudao-module-ai/src/main/java/cn/iocoder/yudao/module/ai/framework/ai/config/YudaoAiProperties.java
@@ -14,6 +14,11 @@ import org.springframework.boot.context.properties.ConfigurationProperties; @@ -14,6 +14,11 @@ import org.springframework.boot.context.properties.ConfigurationProperties;
14 public class YudaoAiProperties { 14 public class YudaoAiProperties {
15 15
16 /** 16 /**
  17 + * 谷歌 Gemini
  18 + */
  19 + private GeminiProperties gemini;
  20 +
  21 + /**
17 * 字节豆包 22 * 字节豆包
18 */ 23 */
19 @SuppressWarnings("SpellCheckingInspection") 24 @SuppressWarnings("SpellCheckingInspection")
@@ -55,6 +60,19 @@ public class YudaoAiProperties { @@ -55,6 +60,19 @@ public class YudaoAiProperties {
55 private SunoProperties suno; 60 private SunoProperties suno;
56 61
57 @Data 62 @Data
  63 + public static class GeminiProperties {
  64 +
  65 + private String enable;
  66 + private String apiKey;
  67 +
  68 + private String model;
  69 + private Double temperature;
  70 + private Integer maxTokens;
  71 + private Double topP;
  72 +
  73 + }
  74 +
  75 + @Data
58 public static class DouBaoProperties { 76 public static class DouBaoProperties {
59 77
60 private String enable; 78 private String enable;
yudao-module-ai/src/main/java/cn/iocoder/yudao/module/ai/framework/ai/core/AiModelFactoryImpl.java
@@ -14,6 +14,7 @@ import cn.iocoder.yudao.module.ai.framework.ai.config.AiAutoConfiguration; @@ -14,6 +14,7 @@ import cn.iocoder.yudao.module.ai.framework.ai.config.AiAutoConfiguration;
14 import cn.iocoder.yudao.module.ai.framework.ai.config.YudaoAiProperties; 14 import cn.iocoder.yudao.module.ai.framework.ai.config.YudaoAiProperties;
15 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;
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.gemini.GeminiChatModel;
17 import cn.iocoder.yudao.module.ai.framework.ai.core.model.hunyuan.HunYuanChatModel; 18 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; 19 import cn.iocoder.yudao.module.ai.framework.ai.core.model.midjourney.api.MidjourneyApi;
19 import cn.iocoder.yudao.module.ai.framework.ai.core.model.siliconflow.SiliconFlowApiConstants; 20 import cn.iocoder.yudao.module.ai.framework.ai.core.model.siliconflow.SiliconFlowApiConstants;
@@ -173,6 +174,8 @@ public class AiModelFactoryImpl implements AiModelFactory { @@ -173,6 +174,8 @@ public class AiModelFactoryImpl implements AiModelFactory {
173 return buildAzureOpenAiChatModel(apiKey, url); 174 return buildAzureOpenAiChatModel(apiKey, url);
174 case ANTHROPIC: 175 case ANTHROPIC:
175 return buildAnthropicChatModel(apiKey, url); 176 return buildAnthropicChatModel(apiKey, url);
  177 + case GEMINI:
  178 + return buildGeminiChatModel(apiKey);
176 case OLLAMA: 179 case OLLAMA:
177 return buildOllamaChatModel(url); 180 return buildOllamaChatModel(url);
178 default: 181 default:
@@ -213,6 +216,8 @@ public class AiModelFactoryImpl implements AiModelFactory { @@ -213,6 +216,8 @@ public class AiModelFactoryImpl implements AiModelFactory {
213 return SpringUtil.getBean(AzureOpenAiChatModel.class); 216 return SpringUtil.getBean(AzureOpenAiChatModel.class);
214 case ANTHROPIC: 217 case ANTHROPIC:
215 return SpringUtil.getBean(AnthropicChatModel.class); 218 return SpringUtil.getBean(AnthropicChatModel.class);
  219 + case GEMINI:
  220 + return SpringUtil.getBean(GeminiChatModel.class);
216 case OLLAMA: 221 case OLLAMA:
217 return SpringUtil.getBean(OllamaChatModel.class); 222 return SpringUtil.getBean(OllamaChatModel.class);
218 default: 223 default:
@@ -535,6 +540,15 @@ public class AiModelFactoryImpl implements AiModelFactory { @@ -535,6 +540,15 @@ public class AiModelFactoryImpl implements AiModelFactory {
535 } 540 }
536 541
537 /** 542 /**
  543 + * 可参考 {@link AiAutoConfiguration#buildGeminiChatClient(YudaoAiProperties.GeminiProperties)}
  544 + */
  545 + private static GeminiChatModel buildGeminiChatModel(String apiKey) {
  546 + YudaoAiProperties.GeminiProperties properties = SpringUtil.getBean(YudaoAiProperties.class)
  547 + .getGemini().setApiKey(apiKey);
  548 + return new AiAutoConfiguration().buildGeminiChatClient(properties);
  549 + }
  550 +
  551 + /**
538 * 可参考 {@link OpenAiImageAutoConfiguration} 的 openAiImageModel 方法 552 * 可参考 {@link OpenAiImageAutoConfiguration} 的 openAiImageModel 方法
539 */ 553 */
540 private OpenAiImageModel buildOpenAiImageModel(String openAiToken, String url) { 554 private OpenAiImageModel buildOpenAiImageModel(String openAiToken, String url) {
yudao-module-ai/src/main/java/cn/iocoder/yudao/module/ai/framework/ai/core/model/gemini/GeminiChatModel.java 0 → 100644
  1 +package cn.iocoder.yudao.module.ai.framework.ai.core.model.gemini;
  2 +
  3 +import lombok.RequiredArgsConstructor;
  4 +import lombok.extern.slf4j.Slf4j;
  5 +import org.springframework.ai.chat.model.ChatModel;
  6 +import org.springframework.ai.chat.model.ChatResponse;
  7 +import org.springframework.ai.chat.prompt.ChatOptions;
  8 +import org.springframework.ai.chat.prompt.Prompt;
  9 +import org.springframework.ai.openai.OpenAiChatModel;
  10 +import reactor.core.publisher.Flux;
  11 +
  12 +/**
  13 + * 谷歌 Gemini {@link ChatModel} 实现类,基于 Google AI Studio 提供的 <a href="https://ai.google.dev/gemini-api/docs/openai">OpenAI 兼容方案</a>
  14 + *
  15 + * @author 芋道源码
  16 + */
  17 +@Slf4j
  18 +@RequiredArgsConstructor
  19 +public class GeminiChatModel implements ChatModel {
  20 +
  21 + public static final String BASE_URL = "https://generativelanguage.googleapis.com/v1beta/openai/";
  22 + public static final String COMPLETE_PATH = "/chat/completions";
  23 +
  24 + public static final String MODEL_DEFAULT = "gemini-2.5-flash";
  25 +
  26 + /**
  27 + * 兼容 OpenAI 接口,进行复用
  28 + */
  29 + private final OpenAiChatModel openAiChatModel;
  30 +
  31 + @Override
  32 + public ChatResponse call(Prompt prompt) {
  33 + return openAiChatModel.call(prompt);
  34 + }
  35 +
  36 + @Override
  37 + public Flux<ChatResponse> stream(Prompt prompt) {
  38 + return openAiChatModel.stream(prompt);
  39 + }
  40 +
  41 + @Override
  42 + public ChatOptions getDefaultOptions() {
  43 + return openAiChatModel.getDefaultOptions();
  44 + }
  45 +
  46 +}
yudao-module-ai/src/main/java/cn/iocoder/yudao/module/ai/framework/ai/core/model/xinghuo/XingHuoChatModel.java
@@ -18,28 +18,34 @@ import reactor.core.publisher.Flux; @@ -18,28 +18,34 @@ import reactor.core.publisher.Flux;
18 @RequiredArgsConstructor 18 @RequiredArgsConstructor
19 public class XingHuoChatModel implements ChatModel { 19 public class XingHuoChatModel implements ChatModel {
20 20
21 - public static final String BASE_URL = "https://spark-api-open.xf-yun.com"; 21 + public static final String BASE_URL_V1 = "https://spark-api-open.xf-yun.com";
22 22
23 - public static final String MODEL_DEFAULT = "generalv3.5"; 23 + public static final String BASE_URL_V2 = "https://spark-api-open.xf-yun.com";
  24 + public static final String BASE_COMPLETIONS_PATH_V2 = "/v2/chat/completions";
24 25
25 /** 26 /**
26 - * 兼容 OpenAI 接口,进行复用 27 + * 已知模型名列表:x1、4.0Ultra、generalv3.5、max-32k、generalv3、pro-128k、lite
27 */ 28 */
28 - private final OpenAiChatModel openAiChatModel; 29 + public static final String MODEL_DEFAULT = "4.0Ultra";
  30 +
  31 + /**
  32 + * v1 兼容 OpenAI 接口,进行复用
  33 + */
  34 + private final OpenAiChatModel openAiChatModelV1;
29 35
30 @Override 36 @Override
31 public ChatResponse call(Prompt prompt) { 37 public ChatResponse call(Prompt prompt) {
32 - return openAiChatModel.call(prompt); 38 + return openAiChatModelV1.call(prompt);
33 } 39 }
34 40
35 @Override 41 @Override
36 public Flux<ChatResponse> stream(Prompt prompt) { 42 public Flux<ChatResponse> stream(Prompt prompt) {
37 - return openAiChatModel.stream(prompt); 43 + return openAiChatModelV1.stream(prompt);
38 } 44 }
39 45
40 @Override 46 @Override
41 public ChatOptions getDefaultOptions() { 47 public ChatOptions getDefaultOptions() {
42 - return openAiChatModel.getDefaultOptions(); 48 + return openAiChatModelV1.getDefaultOptions();
43 } 49 }
44 50
45 } 51 }
yudao-module-ai/src/main/java/cn/iocoder/yudao/module/ai/util/AiUtils.java
@@ -12,6 +12,7 @@ import org.springframework.ai.anthropic.AnthropicChatOptions; @@ -12,6 +12,7 @@ import org.springframework.ai.anthropic.AnthropicChatOptions;
12 import org.springframework.ai.azure.openai.AzureOpenAiChatOptions; 12 import org.springframework.ai.azure.openai.AzureOpenAiChatOptions;
13 import org.springframework.ai.chat.messages.*; 13 import org.springframework.ai.chat.messages.*;
14 import org.springframework.ai.chat.prompt.ChatOptions; 14 import org.springframework.ai.chat.prompt.ChatOptions;
  15 +import org.springframework.ai.deepseek.DeepSeekChatOptions;
15 import org.springframework.ai.minimax.MiniMaxChatOptions; 16 import org.springframework.ai.minimax.MiniMaxChatOptions;
16 import org.springframework.ai.ollama.api.OllamaOptions; 17 import org.springframework.ai.ollama.api.OllamaOptions;
17 import org.springframework.ai.openai.OpenAiChatOptions; 18 import org.springframework.ai.openai.OpenAiChatOptions;
@@ -47,6 +48,9 @@ public class AiUtils { @@ -47,6 +48,9 @@ public class AiUtils {
47 .withToolNames(toolNames).withToolContext(toolContext).build(); 48 .withToolNames(toolNames).withToolContext(toolContext).build();
48 case YI_YAN: 49 case YI_YAN:
49 return QianFanChatOptions.builder().model(model).temperature(temperature).maxTokens(maxTokens).build(); 50 return QianFanChatOptions.builder().model(model).temperature(temperature).maxTokens(maxTokens).build();
  51 + case DEEP_SEEK:
  52 + return DeepSeekChatOptions.builder().model(model).temperature(temperature).maxTokens(maxTokens)
  53 + .toolNames(toolNames).toolContext(toolContext).build();
50 case ZHI_PU: 54 case ZHI_PU:
51 return ZhiPuAiChatOptions.builder().model(model).temperature(temperature).maxTokens(maxTokens) 55 return ZhiPuAiChatOptions.builder().model(model).temperature(temperature).maxTokens(maxTokens)
52 .toolNames(toolNames).toolContext(toolContext).build(); 56 .toolNames(toolNames).toolContext(toolContext).build();
@@ -57,7 +61,7 @@ public class AiUtils { @@ -57,7 +61,7 @@ public class AiUtils {
57 return MoonshotChatOptions.builder().model(model).temperature(temperature).maxTokens(maxTokens) 61 return MoonshotChatOptions.builder().model(model).temperature(temperature).maxTokens(maxTokens)
58 .toolNames(toolNames).toolContext(toolContext).build(); 62 .toolNames(toolNames).toolContext(toolContext).build();
59 case OPENAI: 63 case OPENAI:
60 - case DEEP_SEEK: // 复用 OpenAI 客户端 64 + case GEMINI: // 复用 OpenAI 客户端
61 case DOU_BAO: // 复用 OpenAI 客户端 65 case DOU_BAO: // 复用 OpenAI 客户端
62 case HUN_YUAN: // 复用 OpenAI 客户端 66 case HUN_YUAN: // 复用 OpenAI 客户端
63 case XING_HUO: // 复用 OpenAI 客户端 67 case XING_HUO: // 复用 OpenAI 客户端
yudao-module-ai/src/test/java/cn/iocoder/yudao/module/ai/framework/ai/core/model/chat/GeminiChatModelTests.java 0 → 100644
  1 +package cn.iocoder.yudao.module.ai.framework.ai.core.model.chat;
  2 +
  3 +import cn.iocoder.yudao.module.ai.framework.ai.core.model.gemini.GeminiChatModel;
  4 +import org.junit.jupiter.api.Disabled;
  5 +import org.junit.jupiter.api.Test;
  6 +import org.springframework.ai.chat.messages.Message;
  7 +import org.springframework.ai.chat.messages.SystemMessage;
  8 +import org.springframework.ai.chat.messages.UserMessage;
  9 +import org.springframework.ai.chat.model.ChatResponse;
  10 +import org.springframework.ai.chat.prompt.Prompt;
  11 +import org.springframework.ai.openai.OpenAiChatModel;
  12 +import org.springframework.ai.openai.OpenAiChatOptions;
  13 +import org.springframework.ai.openai.api.OpenAiApi;
  14 +import reactor.core.publisher.Flux;
  15 +
  16 +import java.util.ArrayList;
  17 +import java.util.List;
  18 +
  19 +/**
  20 + * {@link GeminiChatModel} 集成测试
  21 + *
  22 + * @author 芋道源码
  23 + */
  24 +public class GeminiChatModelTests {
  25 +
  26 + private final OpenAiChatModel openAiChatModel = OpenAiChatModel.builder()
  27 + .openAiApi(OpenAiApi.builder()
  28 + .baseUrl(GeminiChatModel.BASE_URL)
  29 + .completionsPath(GeminiChatModel.COMPLETE_PATH)
  30 + .apiKey("AIzaSyAVoBxgoFvvte820vEQMma2LKBnC98bqMQ")
  31 + .build())
  32 + .defaultOptions(OpenAiChatOptions.builder()
  33 + .model(GeminiChatModel.MODEL_DEFAULT) // 模型
  34 + .temperature(0.7)
  35 + .build())
  36 + .build();
  37 +
  38 + private final GeminiChatModel chatModel = new GeminiChatModel(openAiChatModel);
  39 +
  40 + @Test
  41 + @Disabled
  42 + public void testCall() {
  43 + // 准备参数
  44 + List<Message> messages = new ArrayList<>();
  45 + messages.add(new SystemMessage("你是一个优质的文言文作者,用文言文描述着各城市的人文风景。"));
  46 + messages.add(new UserMessage("1 + 1 = ?"));
  47 +
  48 + // 调用
  49 + ChatResponse response = chatModel.call(new Prompt(messages));
  50 + // 打印结果
  51 + System.out.println(response);
  52 + }
  53 +
  54 + @Test
  55 + @Disabled
  56 + public void testStream() {
  57 + // 准备参数
  58 + List<Message> messages = new ArrayList<>();
  59 + messages.add(new SystemMessage("你是一个优质的文言文作者,用文言文描述着各城市的人文风景。"));
  60 + messages.add(new UserMessage("1 + 1 = ?"));
  61 +
  62 + // 调用
  63 + Flux<ChatResponse> flux = chatModel.stream(new Prompt(messages));
  64 + // 打印结果
  65 + flux.doOnNext(System.out::println).then().block();
  66 + }
  67 +
  68 +}
yudao-module-ai/src/test/java/cn/iocoder/yudao/module/ai/framework/ai/core/model/chat/XingHuoChatModelTests.java
@@ -25,11 +25,13 @@ public class XingHuoChatModelTests { @@ -25,11 +25,13 @@ public class XingHuoChatModelTests {
25 25
26 private final OpenAiChatModel openAiChatModel = OpenAiChatModel.builder() 26 private final OpenAiChatModel openAiChatModel = OpenAiChatModel.builder()
27 .openAiApi(OpenAiApi.builder() 27 .openAiApi(OpenAiApi.builder()
28 - .baseUrl(XingHuoChatModel.BASE_URL) 28 + .baseUrl(XingHuoChatModel.BASE_URL_V2)
  29 + .completionsPath(XingHuoChatModel.BASE_COMPLETIONS_PATH_V2)
29 .apiKey("75b161ed2aef4719b275d6e7f2a4d4cd:YWYxYWI2MTA4ODI2NGZlYTQyNjAzZTcz") // appKey:secretKey 30 .apiKey("75b161ed2aef4719b275d6e7f2a4d4cd:YWYxYWI2MTA4ODI2NGZlYTQyNjAzZTcz") // appKey:secretKey
30 .build()) 31 .build())
31 .defaultOptions(OpenAiChatOptions.builder() 32 .defaultOptions(OpenAiChatOptions.builder()
32 - .model("generalv3.5") // 模型 33 +// .model("generalv3.5") // 模型
  34 + .model("x1") // 模型
33 .temperature(0.7) 35 .temperature(0.7)
34 .build()) 36 .build())
35 .build(); 37 .build();
yudao-server/src/main/resources/application.yaml
@@ -197,6 +197,10 @@ spring: @@ -197,6 +197,10 @@ spring:
197 197
198 yudao: 198 yudao:
199 ai: 199 ai:
  200 + gemini: # 谷歌 Gemini
  201 + enable: true
  202 + api-key: AIzaSyAVoBxgoFvvte820vEQMma2LKBnC98bqMQ
  203 + model: gemini-2.5-flash
200 doubao: # 字节豆包 204 doubao: # 字节豆包
201 enable: true 205 enable: true
202 api-key: 5c1b5747-26d2-4ebd-a4e0-dd0e8d8b4272 206 api-key: 5c1b5747-26d2-4ebd-a4e0-dd0e8d8b4272