3 天以前 83e1b4d0e661f11a407fd6ea86e906b9b87b7180
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
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();
    }
 
}