init embedding

This commit is contained in:
Chuck1sn
2025-05-25 16:20:00 +08:00
parent 6e2cf11ec3
commit b6f72942ad
15 changed files with 1818 additions and 1674 deletions

View File

@@ -14,17 +14,17 @@ import org.springframework.context.annotation.DependsOn;
@Configuration
@RequiredArgsConstructor
public class ChatModelConfig {
public class ChatModelInitializer {
private final LlmService llmService;
private final PromptConfiguration promptConfiguration;
@Bean
@DependsOn("flywayInitializer")
public ZhipuAiStreamingChatModel zhipuChatModel(ZhiPuConfiguration zhiPuConfiguration) {
public ZhipuAiStreamingChatModel zhipuChatModel(ZhiPuChatModelConfig zhiPuChatModelConfig) {
return ZhipuAiStreamingChatModel.builder()
.model(zhiPuConfiguration.getModelName())
.apiKey(zhiPuConfiguration.getApiKey())
.model(zhiPuChatModelConfig.getModelName())
.apiKey(zhiPuChatModelConfig.getApiKey())
.logRequests(true)
.logResponses(true)
.build();
@@ -32,11 +32,12 @@ public class ChatModelConfig {
@Bean
@DependsOn("flywayInitializer")
public OpenAiStreamingChatModel deepSeekChatModel(DeepSeekConfiguration deepSeekConfiguration) {
public OpenAiStreamingChatModel deepSeekChatModel(
DeepSeekChatModelConfig deepSeekChatModelConfig) {
return OpenAiStreamingChatModel.builder()
.baseUrl(deepSeekConfiguration.getBaseUrl())
.apiKey(deepSeekConfiguration.getApiKey())
.modelName(deepSeekConfiguration.getModelName())
.baseUrl(deepSeekChatModelConfig.getBaseUrl())
.apiKey(deepSeekChatModelConfig.getApiKey())
.modelName(deepSeekChatModelConfig.getModelName())
.build();
}
@@ -62,19 +63,19 @@ public class ChatModelConfig {
@Bean
@DependsOn("flywayInitializer")
public DeepSeekConfiguration deepSeekConfiguration() {
DeepSeekConfiguration deepSeekConfiguration = new DeepSeekConfiguration();
public DeepSeekChatModelConfig deepSeekConfiguration() {
DeepSeekChatModelConfig deepSeekChatModelConfig = new DeepSeekChatModelConfig();
AiLlmConfig deepSeek = llmService.loadConfig(LlmCodeEnum.DEEP_SEEK);
deepSeekConfiguration.init(deepSeek);
return deepSeekConfiguration;
deepSeekChatModelConfig.init(deepSeek);
return deepSeekChatModelConfig;
}
@Bean
@DependsOn("flywayInitializer")
public ZhiPuConfiguration zhiPuConfiguration() {
ZhiPuConfiguration zhiPuConfiguration = new ZhiPuConfiguration();
public ZhiPuChatModelConfig zhiPuConfiguration() {
ZhiPuChatModelConfig zhiPuChatModelConfig = new ZhiPuChatModelConfig();
AiLlmConfig aiLlmConfig = llmService.loadConfig(LlmCodeEnum.ZHI_PU);
zhiPuConfiguration.init(aiLlmConfig);
return zhiPuConfiguration;
zhiPuChatModelConfig.init(aiLlmConfig);
return zhiPuChatModelConfig;
}
}

View File

@@ -2,21 +2,17 @@ package com.zl.mjga.config.ai;
import lombok.Data;
import org.jooq.generated.mjga.tables.pojos.AiLlmConfig;
import org.springframework.stereotype.Component;
@Data
@Component
public class ZhiPuConfiguration {
public class DeepSeekChatModelConfig {
private String baseUrl;
private String apiKey;
private String modelName;
private String embeddingModel;
public void init(AiLlmConfig config) {
this.baseUrl = config.getUrl();
this.apiKey = config.getApiKey();
this.modelName = config.getModelName();
this.embeddingModel = config.getEmbeddingModel();
}
}

View File

@@ -1,5 +1,6 @@
package com.zl.mjga.config.ai;
import com.zl.mjga.service.LlmService;
import dev.langchain4j.community.model.zhipu.ZhipuAiEmbeddingModel;
import dev.langchain4j.data.segment.TextSegment;
import dev.langchain4j.model.embedding.EmbeddingModel;
@@ -7,6 +8,8 @@ import dev.langchain4j.store.embedding.EmbeddingStore;
import dev.langchain4j.store.embedding.pgvector.PgVectorEmbeddingStore;
import jakarta.annotation.Resource;
import lombok.RequiredArgsConstructor;
import org.jooq.generated.mjga.enums.LlmCodeEnum;
import org.jooq.generated.mjga.tables.pojos.AiLlmConfig;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.DependsOn;
@@ -14,16 +17,26 @@ import org.springframework.core.env.Environment;
@Configuration
@RequiredArgsConstructor
public class EmbeddingConfig {
public class EmbeddingInitializer {
@Resource private Environment env;
private final LlmService llmService;
@Bean
@DependsOn("flywayInitializer")
public EmbeddingModel zhipuEmbeddingModel(ZhiPuConfiguration zhiPuConfiguration) {
public ZhiPuEmbeddingModelConfig zhiPuEmbeddingModelConfig() {
ZhiPuEmbeddingModelConfig zhiPuEmbeddingModelConfig = new ZhiPuEmbeddingModelConfig();
AiLlmConfig aiLlmConfig = llmService.loadConfig(LlmCodeEnum.ZHI_PU_EMBEDDING);
zhiPuEmbeddingModelConfig.init(aiLlmConfig);
return zhiPuEmbeddingModelConfig;
}
@Bean
@DependsOn("flywayInitializer")
public EmbeddingModel zhipuEmbeddingModel(ZhiPuEmbeddingModelConfig zhiPuEmbeddingModelConfig) {
return ZhipuAiEmbeddingModel.builder()
.apiKey(zhiPuConfiguration.getApiKey())
.model(zhiPuConfiguration.getEmbeddingModel())
.apiKey(zhiPuEmbeddingModelConfig.getApiKey())
.model(zhiPuEmbeddingModelConfig.getModelName())
.dimensions(2048)
.build();
}

View File

@@ -4,7 +4,7 @@ import lombok.Data;
import org.jooq.generated.mjga.tables.pojos.AiLlmConfig;
@Data
public class DeepSeekConfiguration {
public class ZhiPuChatModelConfig {
private String baseUrl;
private String apiKey;

View File

@@ -0,0 +1,20 @@
package com.zl.mjga.config.ai;
import lombok.Data;
import org.jooq.generated.mjga.tables.pojos.AiLlmConfig;
@Data
public class ZhiPuEmbeddingModelConfig {
private String baseUrl;
private String apiKey;
private String modelName;
private Boolean enable;
public void init(AiLlmConfig config) {
this.baseUrl = config.getUrl();
this.apiKey = config.getApiKey();
this.modelName = config.getModelName();
this.enable = config.getEnable();
}
}

View File

@@ -1,3 +1,3 @@
package com.zl.mjga.dto.ai;
public record LlmQueryDto(String name) {}
public record LlmQueryDto(String name, String type) {}

View File

@@ -9,6 +9,7 @@ import org.apache.commons.lang3.StringUtils;
import org.jooq.Configuration;
import org.jooq.Record;
import org.jooq.Result;
import org.jooq.generated.default_schema.enums.LlmTypeEnum;
import org.jooq.generated.mjga.tables.daos.AiLlmConfigDao;
import org.jooq.impl.DSL;
import org.springframework.beans.factory.annotation.Autowired;
@@ -31,6 +32,10 @@ public class LlmRepository extends AiLlmConfigDao {
StringUtils.isNotEmpty(llmQueryDto.name())
? AI_LLM_CONFIG.NAME.eq(llmQueryDto.name())
: noCondition())
.and(
StringUtils.isNotEmpty(llmQueryDto.type())
? AI_LLM_CONFIG.TYPE.eq(LlmTypeEnum.lookupLiteral(llmQueryDto.type()))
: noCondition())
.orderBy(pageRequestDto.getSortFields())
.limit(pageRequestDto.getSize())
.offset(pageRequestDto.getOffset())

View File

@@ -28,12 +28,13 @@ public class AiChatService {
}
public TokenStream chatPrecedenceLlmWith(String sessionIdentifier, String userMessage) {
Optional<AiLlmConfig> precedenceLlmBy = llmService.getPrecedenceLlmBy(true);
Optional<AiLlmConfig> precedenceLlmBy = llmService.getPrecedenceChatLlmBy(true);
AiLlmConfig aiLlmConfig = precedenceLlmBy.orElseThrow(() -> new BusinessException("没有开启的大模型"));
LlmCodeEnum code = aiLlmConfig.getCode();
return switch (code) {
case ZHI_PU -> zhiPuChatAssistant.chat(sessionIdentifier, userMessage);
case DEEP_SEEK -> deepSeekChatAssistant.chat(sessionIdentifier, userMessage);
default -> throw new BusinessException(String.format("无效的模型代码 %s", code));
};
}
}

View File

@@ -2,6 +2,7 @@ package com.zl.mjga.service;
import static dev.langchain4j.store.embedding.filter.MetadataFilterBuilder.metadataKey;
import com.zl.mjga.config.ai.ZhiPuEmbeddingModelConfig;
import com.zl.mjga.model.urp.Actions;
import dev.langchain4j.data.document.Metadata;
import dev.langchain4j.data.embedding.Embedding;
@@ -27,6 +28,8 @@ public class EmbeddingService {
private final EmbeddingStore<TextSegment> zhiPuEmbeddingStore;
private final ZhiPuEmbeddingModelConfig zhiPuEmbeddingModelConfig;
public Map<String, Object> searchAction(String message) {
Map<String, Object> result = new HashMap<>();
EmbeddingSearchRequest embeddingSearchRequest =
@@ -43,6 +46,9 @@ public class EmbeddingService {
@PostConstruct
public void initActionIndex() {
if (!zhiPuEmbeddingModelConfig.getEnable()) {
return;
}
for (Actions action : Actions.values()) {
Embedding queryEmbedding = zhipuEmbeddingModel.embed(action.getContent()).content();
Filter createUserFilter = metadataKey(Actions.INDEX_KEY).isEqualTo(action.getCode());

View File

@@ -12,6 +12,7 @@ import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.jooq.Record;
import org.jooq.Result;
import org.jooq.generated.default_schema.enums.LlmTypeEnum;
import org.jooq.generated.mjga.enums.LlmCodeEnum;
import org.jooq.generated.mjga.tables.pojos.AiLlmConfig;
import org.springframework.beans.BeanUtils;
@@ -28,9 +29,11 @@ public class LlmService {
return llmRepository.fetchOneByCode(llmCodeEnum);
}
public Optional<AiLlmConfig> getPrecedenceLlmBy(Boolean enable) {
public Optional<AiLlmConfig> getPrecedenceChatLlmBy(Boolean enable) {
List<AiLlmConfig> aiLlmConfigs = llmRepository.fetchByEnable(enable);
return aiLlmConfigs.stream().max((o1, o2) -> o2.getPriority().compareTo(o1.getPriority()));
return aiLlmConfigs.stream()
.filter(aiLlmConfig -> LlmTypeEnum.CHAT.equals(aiLlmConfig.getType()))
.max((o1, o2) -> o2.getPriority().compareTo(o1.getPriority()));
}
public PageResponseDto<List<LlmVm>> pageQueryLlm(