Commit 83bd96d6725b0769808ea5c83b43d54e04859c6e
1 parent
b4538568
【功能新增】AI:集成 Azure 的 OpenAI 模型
Showing
7 changed files
with
47 additions
and
6 deletions
yudao-module-ai/yudao-module-ai-biz/src/main/java/cn/iocoder/yudao/module/ai/service/knowledge/DocServiceImpl.java
| @@ -7,7 +7,6 @@ import org.springframework.ai.reader.tika.TikaDocumentReader; | @@ -7,7 +7,6 @@ import org.springframework.ai.reader.tika.TikaDocumentReader; | ||
| 7 | import org.springframework.ai.transformer.splitter.TokenTextSplitter; | 7 | import org.springframework.ai.transformer.splitter.TokenTextSplitter; |
| 8 | import org.springframework.ai.vectorstore.RedisVectorStore; | 8 | import org.springframework.ai.vectorstore.RedisVectorStore; |
| 9 | import org.springframework.beans.factory.annotation.Value; | 9 | import org.springframework.beans.factory.annotation.Value; |
| 10 | -import org.springframework.stereotype.Service; | ||
| 11 | 10 | ||
| 12 | import java.util.List; | 11 | import java.util.List; |
| 13 | 12 | ||
| @@ -16,7 +15,7 @@ import java.util.List; | @@ -16,7 +15,7 @@ import java.util.List; | ||
| 16 | * | 15 | * |
| 17 | * @author xiaoxin | 16 | * @author xiaoxin |
| 18 | */ | 17 | */ |
| 19 | -@Service | 18 | +//@Service // TODO 芋艿:临时注释,避免无法启动 |
| 20 | @Slf4j | 19 | @Slf4j |
| 21 | public class DocServiceImpl implements DocService { | 20 | public class DocServiceImpl implements DocService { |
| 22 | 21 |
yudao-module-ai/yudao-spring-boot-starter-ai/pom.xml
| @@ -23,7 +23,6 @@ | @@ -23,7 +23,6 @@ | ||
| 23 | <artifactId>spring-ai-zhipuai-spring-boot-starter</artifactId> | 23 | <artifactId>spring-ai-zhipuai-spring-boot-starter</artifactId> |
| 24 | <version>${spring-ai.version}</version> | 24 | <version>${spring-ai.version}</version> |
| 25 | </dependency> | 25 | </dependency> |
| 26 | - | ||
| 27 | <dependency> | 26 | <dependency> |
| 28 | <groupId>org.springframework.ai</groupId> | 27 | <groupId>org.springframework.ai</groupId> |
| 29 | <artifactId>spring-ai-openai-spring-boot-starter</artifactId> | 28 | <artifactId>spring-ai-openai-spring-boot-starter</artifactId> |
| @@ -31,6 +30,11 @@ | @@ -31,6 +30,11 @@ | ||
| 31 | </dependency> | 30 | </dependency> |
| 32 | <dependency> | 31 | <dependency> |
| 33 | <groupId>org.springframework.ai</groupId> | 32 | <groupId>org.springframework.ai</groupId> |
| 33 | + <artifactId>spring-ai-azure-openai-spring-boot-starter</artifactId> | ||
| 34 | + <version>${spring-ai.version}</version> | ||
| 35 | + </dependency> | ||
| 36 | + <dependency> | ||
| 37 | + <groupId>org.springframework.ai</groupId> | ||
| 34 | <artifactId>spring-ai-ollama-spring-boot-starter</artifactId> | 38 | <artifactId>spring-ai-ollama-spring-boot-starter</artifactId> |
| 35 | <version>${spring-ai.version}</version> | 39 | <version>${spring-ai.version}</version> |
| 36 | </dependency> | 40 | </dependency> |
yudao-module-ai/yudao-spring-boot-starter-ai/src/main/java/cn/iocoder/yudao/framework/ai/config/YudaoAiAutoConfiguration.java
| @@ -12,6 +12,7 @@ import com.alibaba.cloud.ai.tongyi.TongYiAutoConfiguration; | @@ -12,6 +12,7 @@ import com.alibaba.cloud.ai.tongyi.TongYiAutoConfiguration; | ||
| 12 | import lombok.extern.slf4j.Slf4j; | 12 | import lombok.extern.slf4j.Slf4j; |
| 13 | import org.springframework.ai.autoconfigure.vectorstore.redis.RedisVectorStoreProperties; | 13 | import org.springframework.ai.autoconfigure.vectorstore.redis.RedisVectorStoreProperties; |
| 14 | import org.springframework.ai.document.MetadataMode; | 14 | import org.springframework.ai.document.MetadataMode; |
| 15 | +import org.springframework.ai.embedding.EmbeddingModel; | ||
| 15 | import org.springframework.ai.transformer.splitter.TokenTextSplitter; | 16 | import org.springframework.ai.transformer.splitter.TokenTextSplitter; |
| 16 | import org.springframework.ai.transformers.TransformersEmbeddingModel; | 17 | import org.springframework.ai.transformers.TransformersEmbeddingModel; |
| 17 | import org.springframework.ai.vectorstore.RedisVectorStore; | 18 | import org.springframework.ai.vectorstore.RedisVectorStore; |
| @@ -21,6 +22,7 @@ import org.springframework.boot.autoconfigure.data.redis.RedisProperties; | @@ -21,6 +22,7 @@ import org.springframework.boot.autoconfigure.data.redis.RedisProperties; | ||
| 21 | import org.springframework.boot.context.properties.EnableConfigurationProperties; | 22 | import org.springframework.boot.context.properties.EnableConfigurationProperties; |
| 22 | import org.springframework.context.annotation.Bean; | 23 | import org.springframework.context.annotation.Bean; |
| 23 | import org.springframework.context.annotation.Import; | 24 | import org.springframework.context.annotation.Import; |
| 25 | +import org.springframework.context.annotation.Lazy; | ||
| 24 | import redis.clients.jedis.JedisPooled; | 26 | import redis.clients.jedis.JedisPooled; |
| 25 | 27 | ||
| 26 | /** | 28 | /** |
| @@ -82,7 +84,8 @@ public class YudaoAiAutoConfiguration { | @@ -82,7 +84,8 @@ public class YudaoAiAutoConfiguration { | ||
| 82 | 84 | ||
| 83 | // ========== rag 相关 ========== | 85 | // ========== rag 相关 ========== |
| 84 | @Bean | 86 | @Bean |
| 85 | - public TransformersEmbeddingModel transformersEmbeddingClient() { | 87 | + @Lazy // TODO 芋艿:临时注释,避免无法启动 |
| 88 | + public EmbeddingModel transformersEmbeddingClient() { | ||
| 86 | return new TransformersEmbeddingModel(MetadataMode.EMBED); | 89 | return new TransformersEmbeddingModel(MetadataMode.EMBED); |
| 87 | } | 90 | } |
| 88 | 91 | ||
| @@ -90,6 +93,7 @@ public class YudaoAiAutoConfiguration { | @@ -90,6 +93,7 @@ public class YudaoAiAutoConfiguration { | ||
| 90 | * 我们启动有加载很多 Embedding 模型,不晓得取哪个好,先 new 个 TransformersEmbeddingModel 跑 | 93 | * 我们启动有加载很多 Embedding 模型,不晓得取哪个好,先 new 个 TransformersEmbeddingModel 跑 |
| 91 | */ | 94 | */ |
| 92 | @Bean | 95 | @Bean |
| 96 | + @Lazy // TODO 芋艿:临时注释,避免无法启动 | ||
| 93 | public RedisVectorStore vectorStore(TransformersEmbeddingModel transformersEmbeddingModel, RedisVectorStoreProperties properties, | 97 | public RedisVectorStore vectorStore(TransformersEmbeddingModel transformersEmbeddingModel, RedisVectorStoreProperties properties, |
| 94 | RedisProperties redisProperties) { | 98 | RedisProperties redisProperties) { |
| 95 | var config = RedisVectorStore.RedisVectorStoreConfig.builder() | 99 | var config = RedisVectorStore.RedisVectorStoreConfig.builder() |
| @@ -105,6 +109,7 @@ public class YudaoAiAutoConfiguration { | @@ -105,6 +109,7 @@ public class YudaoAiAutoConfiguration { | ||
| 105 | } | 109 | } |
| 106 | 110 | ||
| 107 | @Bean | 111 | @Bean |
| 112 | + @Lazy // TODO 芋艿:临时注释,避免无法启动 | ||
| 108 | public TokenTextSplitter tokenTextSplitter() { | 113 | public TokenTextSplitter tokenTextSplitter() { |
| 109 | return new TokenTextSplitter(500, 100, 5, 10000, true); | 114 | return new TokenTextSplitter(500, 100, 5, 10000, true); |
| 110 | } | 115 | } |
yudao-module-ai/yudao-spring-boot-starter-ai/src/main/java/cn/iocoder/yudao/framework/ai/core/enums/AiPlatformEnum.java
| @@ -22,7 +22,8 @@ public enum AiPlatformEnum { | @@ -22,7 +22,8 @@ public enum AiPlatformEnum { | ||
| 22 | 22 | ||
| 23 | // ========== 国外平台 ========== | 23 | // ========== 国外平台 ========== |
| 24 | 24 | ||
| 25 | - OPENAI("OpenAI", "OpenAI"), | 25 | + OPENAI("OpenAI", "OpenAI"), // OpenAI 官方 |
| 26 | + AZURE_OPENAI("AzureOpenAI", "AzureOpenAI"), // OpenAI 微软 | ||
| 26 | OLLAMA("Ollama", "Ollama"), | 27 | OLLAMA("Ollama", "Ollama"), |
| 27 | 28 | ||
| 28 | STABLE_DIFFUSION("StableDiffusion", "StableDiffusion"), // Stability AI | 29 | STABLE_DIFFUSION("StableDiffusion", "StableDiffusion"), // Stability AI |
yudao-module-ai/yudao-spring-boot-starter-ai/src/main/java/cn/iocoder/yudao/framework/ai/core/factory/AiModelFactoryImpl.java
| @@ -21,6 +21,10 @@ import com.alibaba.cloud.ai.tongyi.image.TongYiImagesModel; | @@ -21,6 +21,10 @@ import com.alibaba.cloud.ai.tongyi.image.TongYiImagesModel; | ||
| 21 | import com.alibaba.cloud.ai.tongyi.image.TongYiImagesProperties; | 21 | import com.alibaba.cloud.ai.tongyi.image.TongYiImagesProperties; |
| 22 | import com.alibaba.dashscope.aigc.generation.Generation; | 22 | import com.alibaba.dashscope.aigc.generation.Generation; |
| 23 | import com.alibaba.dashscope.aigc.imagesynthesis.ImageSynthesis; | 23 | import com.alibaba.dashscope.aigc.imagesynthesis.ImageSynthesis; |
| 24 | +import com.azure.ai.openai.OpenAIClient; | ||
| 25 | +import org.springframework.ai.autoconfigure.azure.openai.AzureOpenAiAutoConfiguration; | ||
| 26 | +import org.springframework.ai.autoconfigure.azure.openai.AzureOpenAiChatProperties; | ||
| 27 | +import org.springframework.ai.autoconfigure.azure.openai.AzureOpenAiConnectionProperties; | ||
| 24 | import org.springframework.ai.autoconfigure.ollama.OllamaAutoConfiguration; | 28 | import org.springframework.ai.autoconfigure.ollama.OllamaAutoConfiguration; |
| 25 | import org.springframework.ai.autoconfigure.openai.OpenAiAutoConfiguration; | 29 | import org.springframework.ai.autoconfigure.openai.OpenAiAutoConfiguration; |
| 26 | import org.springframework.ai.autoconfigure.qianfan.QianFanAutoConfiguration; | 30 | import org.springframework.ai.autoconfigure.qianfan.QianFanAutoConfiguration; |
| @@ -31,6 +35,7 @@ import org.springframework.ai.autoconfigure.zhipuai.ZhiPuAiAutoConfiguration; | @@ -31,6 +35,7 @@ import org.springframework.ai.autoconfigure.zhipuai.ZhiPuAiAutoConfiguration; | ||
| 31 | import org.springframework.ai.autoconfigure.zhipuai.ZhiPuAiChatProperties; | 35 | import org.springframework.ai.autoconfigure.zhipuai.ZhiPuAiChatProperties; |
| 32 | import org.springframework.ai.autoconfigure.zhipuai.ZhiPuAiConnectionProperties; | 36 | import org.springframework.ai.autoconfigure.zhipuai.ZhiPuAiConnectionProperties; |
| 33 | import org.springframework.ai.autoconfigure.zhipuai.ZhiPuAiImageProperties; | 37 | import org.springframework.ai.autoconfigure.zhipuai.ZhiPuAiImageProperties; |
| 38 | +import org.springframework.ai.azure.openai.AzureOpenAiChatModel; | ||
| 34 | import org.springframework.ai.chat.model.ChatModel; | 39 | import org.springframework.ai.chat.model.ChatModel; |
| 35 | import org.springframework.ai.image.ImageModel; | 40 | import org.springframework.ai.image.ImageModel; |
| 36 | import org.springframework.ai.model.function.FunctionCallbackContext; | 41 | import org.springframework.ai.model.function.FunctionCallbackContext; |
| @@ -82,6 +87,8 @@ public class AiModelFactoryImpl implements AiModelFactory { | @@ -82,6 +87,8 @@ public class AiModelFactoryImpl implements AiModelFactory { | ||
| 82 | return buildXingHuoChatModel(apiKey); | 87 | return buildXingHuoChatModel(apiKey); |
| 83 | case OPENAI: | 88 | case OPENAI: |
| 84 | return buildOpenAiChatModel(apiKey, url); | 89 | return buildOpenAiChatModel(apiKey, url); |
| 90 | + case AZURE_OPENAI: | ||
| 91 | + return buildAzureOpenAiChatModel(apiKey, url); | ||
| 85 | case OLLAMA: | 92 | case OLLAMA: |
| 86 | return buildOllamaChatModel(url); | 93 | return buildOllamaChatModel(url); |
| 87 | default: | 94 | default: |
| @@ -106,6 +113,8 @@ public class AiModelFactoryImpl implements AiModelFactory { | @@ -106,6 +113,8 @@ public class AiModelFactoryImpl implements AiModelFactory { | ||
| 106 | return SpringUtil.getBean(XingHuoChatModel.class); | 113 | return SpringUtil.getBean(XingHuoChatModel.class); |
| 107 | case OPENAI: | 114 | case OPENAI: |
| 108 | return SpringUtil.getBean(OpenAiChatModel.class); | 115 | return SpringUtil.getBean(OpenAiChatModel.class); |
| 116 | + case AZURE_OPENAI: | ||
| 117 | + return SpringUtil.getBean(AzureOpenAiChatModel.class); | ||
| 109 | case OLLAMA: | 118 | case OLLAMA: |
| 110 | return SpringUtil.getBean(OllamaChatModel.class); | 119 | return SpringUtil.getBean(OllamaChatModel.class); |
| 111 | default: | 120 | default: |
| @@ -269,6 +278,21 @@ public class AiModelFactoryImpl implements AiModelFactory { | @@ -269,6 +278,21 @@ public class AiModelFactoryImpl implements AiModelFactory { | ||
| 269 | } | 278 | } |
| 270 | 279 | ||
| 271 | /** | 280 | /** |
| 281 | + * 可参考 {@link AzureOpenAiAutoConfiguration} | ||
| 282 | + */ | ||
| 283 | + private static AzureOpenAiChatModel buildAzureOpenAiChatModel(String apiKey, String url) { | ||
| 284 | + AzureOpenAiAutoConfiguration azureOpenAiAutoConfiguration = new AzureOpenAiAutoConfiguration(); | ||
| 285 | + // 创建 OpenAIClient 对象 | ||
| 286 | + AzureOpenAiConnectionProperties connectionProperties = new AzureOpenAiConnectionProperties(); | ||
| 287 | + connectionProperties.setApiKey(apiKey); | ||
| 288 | + connectionProperties.setEndpoint(url); | ||
| 289 | + OpenAIClient openAIClient = azureOpenAiAutoConfiguration.openAIClient(connectionProperties); | ||
| 290 | + // 获取 AzureOpenAiChatProperties 对象 | ||
| 291 | + AzureOpenAiChatProperties chatProperties = SpringUtil.getBean(AzureOpenAiChatProperties.class); | ||
| 292 | + return azureOpenAiAutoConfiguration.azureOpenAiChatModel(openAIClient, chatProperties, null, null); | ||
| 293 | + } | ||
| 294 | + | ||
| 295 | + /** | ||
| 272 | * 可参考 {@link OpenAiAutoConfiguration} | 296 | * 可参考 {@link OpenAiAutoConfiguration} |
| 273 | */ | 297 | */ |
| 274 | private OpenAiImageModel buildOpenAiImageModel(String openAiToken, String url) { | 298 | private OpenAiImageModel buildOpenAiImageModel(String openAiToken, String url) { |
yudao-module-ai/yudao-spring-boot-starter-ai/src/main/java/cn/iocoder/yudao/framework/ai/core/util/AiUtils.java
| @@ -5,6 +5,7 @@ import cn.iocoder.yudao.framework.ai.core.enums.AiPlatformEnum; | @@ -5,6 +5,7 @@ import cn.iocoder.yudao.framework.ai.core.enums.AiPlatformEnum; | ||
| 5 | import cn.iocoder.yudao.framework.ai.core.model.deepseek.DeepSeekChatOptions; | 5 | import cn.iocoder.yudao.framework.ai.core.model.deepseek.DeepSeekChatOptions; |
| 6 | import cn.iocoder.yudao.framework.ai.core.model.xinghuo.XingHuoChatOptions; | 6 | import cn.iocoder.yudao.framework.ai.core.model.xinghuo.XingHuoChatOptions; |
| 7 | import com.alibaba.cloud.ai.tongyi.chat.TongYiChatOptions; | 7 | import com.alibaba.cloud.ai.tongyi.chat.TongYiChatOptions; |
| 8 | +import org.springframework.ai.azure.openai.AzureOpenAiChatOptions; | ||
| 8 | import org.springframework.ai.chat.messages.*; | 9 | import org.springframework.ai.chat.messages.*; |
| 9 | import org.springframework.ai.chat.prompt.ChatOptions; | 10 | import org.springframework.ai.chat.prompt.ChatOptions; |
| 10 | import org.springframework.ai.ollama.api.OllamaOptions; | 11 | import org.springframework.ai.ollama.api.OllamaOptions; |
| @@ -35,6 +36,9 @@ public class AiUtils { | @@ -35,6 +36,9 @@ public class AiUtils { | ||
| 35 | return XingHuoChatOptions.builder().model(model).temperature(temperatureF).maxTokens(maxTokens).build(); | 36 | return XingHuoChatOptions.builder().model(model).temperature(temperatureF).maxTokens(maxTokens).build(); |
| 36 | case OPENAI: | 37 | case OPENAI: |
| 37 | return OpenAiChatOptions.builder().withModel(model).withTemperature(temperatureF).withMaxTokens(maxTokens).build(); | 38 | return OpenAiChatOptions.builder().withModel(model).withTemperature(temperatureF).withMaxTokens(maxTokens).build(); |
| 39 | + case AZURE_OPENAI: | ||
| 40 | + // TODO 芋艿:貌似没 model 字段???! | ||
| 41 | + return AzureOpenAiChatOptions.builder().withDeploymentName(model).withTemperature(temperatureF).withMaxTokens(maxTokens).build(); | ||
| 38 | case OLLAMA: | 42 | case OLLAMA: |
| 39 | return OllamaOptions.create().withModel(model).withTemperature(temperatureF).withNumPredict(maxTokens); | 43 | return OllamaOptions.create().withModel(model).withTemperature(temperatureF).withNumPredict(maxTokens); |
| 40 | default: | 44 | default: |
yudao-server/src/main/resources/application.yaml
| @@ -162,9 +162,13 @@ spring: | @@ -162,9 +162,13 @@ spring: | ||
| 162 | secret-key: R9mYF9dl9KASgi5RUq0FQt3wRisSnOcK | 162 | secret-key: R9mYF9dl9KASgi5RUq0FQt3wRisSnOcK |
| 163 | zhipuai: # 智谱 AI | 163 | zhipuai: # 智谱 AI |
| 164 | api-key: 32f84543e54eee31f8d56b2bd6020573.3vh9idLJZ2ZhxDEs | 164 | api-key: 32f84543e54eee31f8d56b2bd6020573.3vh9idLJZ2ZhxDEs |
| 165 | - openai: | 165 | + openai: # OpenAI 官方 |
| 166 | api-key: sk-yzKea6d8e8212c3bdd99f9f44ced1cae37c097e5aa3BTS7z | 166 | api-key: sk-yzKea6d8e8212c3bdd99f9f44ced1cae37c097e5aa3BTS7z |
| 167 | base-url: https://api.gptsapi.net | 167 | base-url: https://api.gptsapi.net |
| 168 | + azure: # OpenAI 微软 | ||
| 169 | + openai: | ||
| 170 | + endpoint: https://eastusprejade.openai.azure.com | ||
| 171 | + api-key: xxx | ||
| 168 | ollama: | 172 | ollama: |
| 169 | base-url: http://127.0.0.1:11434 | 173 | base-url: http://127.0.0.1:11434 |
| 170 | chat: | 174 | chat: |