package cn.iocoder.yudao.module.ai.framework.ai.config;
|
|
import cn.hutool.core.util.StrUtil;
|
import cn.iocoder.yudao.module.ai.framework.ai.core.model.AiModelFactory;
|
import cn.iocoder.yudao.module.ai.framework.ai.core.model.AiModelFactoryImpl;
|
import io.micrometer.observation.ObservationRegistry;
|
import lombok.extern.slf4j.Slf4j;
|
import org.springframework.ai.document.MetadataMode;
|
import org.springframework.ai.embedding.BatchingStrategy;
|
import org.springframework.ai.embedding.TokenCountBatchingStrategy;
|
import org.springframework.ai.model.tool.ToolCallingManager;
|
import org.springframework.ai.openai.OpenAiChatModel;
|
import org.springframework.ai.openai.OpenAiChatOptions;
|
import org.springframework.ai.openai.OpenAiEmbeddingModel;
|
import org.springframework.ai.openai.OpenAiEmbeddingOptions;
|
import org.springframework.ai.retry.RetryUtils;
|
import org.springframework.ai.tokenizer.JTokkitTokenCountEstimator;
|
import org.springframework.ai.tokenizer.TokenCountEstimator;
|
import org.springframework.ai.vectorstore.milvus.autoconfigure.MilvusServiceClientProperties;
|
import org.springframework.ai.vectorstore.milvus.autoconfigure.MilvusVectorStoreProperties;
|
import org.springframework.ai.vectorstore.qdrant.autoconfigure.QdrantVectorStoreProperties;
|
import org.springframework.ai.vectorstore.redis.autoconfigure.RedisVectorStoreProperties;
|
import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean;
|
import org.springframework.context.annotation.Bean;
|
import org.springframework.context.annotation.Configuration;
|
import org.springframework.boot.context.properties.EnableConfigurationProperties;
|
|
/**
|
* 芋道 AI 自动配置
|
*
|
* 使用 OpenAI 兼容接口对接通义千问 DashScope
|
*/
|
@Configuration
|
@EnableConfigurationProperties({
|
YudaoAiProperties.class,
|
QdrantVectorStoreProperties.class,
|
RedisVectorStoreProperties.class,
|
MilvusVectorStoreProperties.class,
|
MilvusServiceClientProperties.class
|
})
|
@Slf4j
|
public class AiAutoConfiguration {
|
|
private static final String DASHSCOPE_BASE_URL = "https://dashscope.aliyuncs.com/compatible-mode/v1";
|
|
@Bean
|
public AiModelFactory aiModelFactory() {
|
return new AiModelFactoryImpl();
|
}
|
|
@Bean
|
@ConditionalOnMissingBean
|
public ObservationRegistry observationRegistry() {
|
return ObservationRegistry.NOOP;
|
}
|
|
@Bean
|
@ConditionalOnMissingBean
|
public BatchingStrategy batchingStrategy() {
|
return new TokenCountBatchingStrategy();
|
}
|
|
@Bean
|
@ConditionalOnMissingBean
|
public TokenCountEstimator tokenCountEstimator() {
|
return new JTokkitTokenCountEstimator();
|
}
|
|
// ========== 通义千问 Chat(通过 OpenAI 兼容接口)==========
|
|
public static OpenAiChatModel buildTongYiChatModel(String apiKey, String model) {
|
return OpenAiChatModel.builder()
|
.options(OpenAiChatOptions.builder()
|
.baseUrl(DASHSCOPE_BASE_URL)
|
.apiKey(apiKey)
|
.model(StrUtil.blankToDefault(model, "qwen-plus"))
|
.temperature(0.7)
|
.build())
|
.toolCallingManager(ToolCallingManager.builder().build())
|
.build();
|
}
|
|
// ========== 通义千问 Embedding(通过 OpenAI 兼容接口)==========
|
|
public static OpenAiEmbeddingModel buildTongYiEmbeddingModel(String apiKey, String model) {
|
return OpenAiEmbeddingModel.builder()
|
.options(OpenAiEmbeddingOptions.builder()
|
.baseUrl(DASHSCOPE_BASE_URL)
|
.apiKey(apiKey)
|
.model(StrUtil.blankToDefault(model, "text-embedding-v3"))
|
.build())
|
.metadataMode(MetadataMode.EMBED)
|
.build();
|
}
|
|
}
|