package com.xly.config; import com.fasterxml.jackson.databind.ObjectMapper; import com.fasterxml.jackson.databind.SerializationFeature; import com.fasterxml.jackson.datatype.jsr310.JavaTimeModule; import com.xly.agent.DynamicTableNl2SqlAiAgent; import com.xly.agent.SceneSelectorAiAgent; import dev.langchain4j.memory.chat.MessageWindowChatMemory; import dev.langchain4j.model.chat.ChatLanguageModel; import dev.langchain4j.model.chat.StreamingChatLanguageModel; import dev.langchain4j.model.ollama.OllamaChatModel; import dev.langchain4j.model.ollama.OllamaStreamingChatModel; import dev.langchain4j.service.AiServices; import org.springframework.beans.factory.annotation.Qualifier; import org.springframework.beans.factory.annotation.Value; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; import org.springframework.context.annotation.Primary; import java.time.Duration; /** * 大模型初始化配置(单例复用,避免重复创建) */ @Configuration public class ModelConfig { @Value("${langchain4j.ollama.base-url}") private String chatModelUrl; @Value("${langchain4j.ollama.base-url}") private String sqlModelUrl; @Value("${langchain4j.ollama.chat-model-name}") private String chatModelName; @Value("${langchain4j.ollama.sql-model-name}") private String sqlModelName; // 中文对话模型 qwen2.5:7b-instruct @Bean @Primary public OllamaChatModel chatLanguageModel() { return OllamaChatModel.builder() .baseUrl(chatModelUrl) .modelName(chatModelName) // 使用聊天模型名称 .temperature(0.0) // 建议调整为0.0太确定 .topP(0.9) // .numPredict(2048) // 添加生成长度限制 .timeout(Duration.ofSeconds(60)) // 缩短超时时间 .maxRetries(2) .build(); } /*** * @Author 钱豹 * @Date 13:25 2026/2/6 * @Param [] * @return dev.langchain4j.model.ollama.OllamaChatModel * @Description 聊天 **/ @Bean("chatiModel") public ChatLanguageModel chatiModel() { return OllamaChatModel.builder() .baseUrl(chatModelUrl) .modelName(chatModelName) // 使用聊天模型名称 .temperature(0.8) // 建议调整为0.8太确定 .topP(0.9) // .numPredict(2048) // 添加生成长度限制 .timeout(Duration.ofSeconds(60)) // 缩短超时时间 .maxRetries(2) .build(); } // SQL/代码专用模型 qwen2.5-coder:14b @Bean("sqlChatModel") // 明确指定bean名称 public ChatLanguageModel sqlChatModel() { return OllamaChatModel.builder() .baseUrl(sqlModelUrl) .modelName(sqlModelName) // 使用SQL模型名称 .temperature(0.0) .topP(0.95) .numPredict(4096) // 代码生成需要更长 .timeout(Duration.ofSeconds(120)) .maxRetries(3) // .repeatPenalty(1.1) // 减少重复 .build(); } /*** * @Author 钱豹 * @Date 22:53 2026/2/3 * @Param [] * @return dev.langchain4j.model.chat.StreamingChatLanguageModel * @Description 流式聊天模型 - 使用 @Primary **/ @Bean("streamingChatModel") @Primary public StreamingChatLanguageModel streamingChatModel() { return OllamaStreamingChatModel.builder() .baseUrl(chatModelUrl) .modelName(chatModelName) .temperature(0.7) .topP(0.9) .numPredict(1024) .timeout(Duration.ofSeconds(60)) .build(); } // 流式SQL/代码模型 - 指定名称 @Bean("streamingSqlModel") public StreamingChatLanguageModel streamingSqlModel() { return OllamaStreamingChatModel.builder() .baseUrl(sqlModelUrl) .modelName(sqlModelName) .temperature(0.3) .topP(0.95) .numPredict(2048) .timeout(Duration.ofSeconds(120)) .build(); } /** * 全局ObjectMapper:支持LocalDate序列化 */ @Bean @Primary public ObjectMapper objectMapper() { ObjectMapper mapper = new ObjectMapper(); mapper.registerModule(new JavaTimeModule()); mapper.disable(SerializationFeature.WRITE_DATES_AS_TIMESTAMPS); mapper.configure(com.fasterxml.jackson.databind.DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false); return mapper; } //动态SQL生成模型 @Bean public DynamicTableNl2SqlAiAgent dynamicTableNl2SqlAiAgent(@Qualifier("sqlChatModel") ChatLanguageModel sqlModel) { return AiServices.builder(DynamicTableNl2SqlAiAgent.class) .chatLanguageModel(sqlModel) // 会话记忆:每个用户最多保留10轮对话,避免记忆溢出 .chatMemoryProvider(memoryId -> MessageWindowChatMemory.withMaxMessages(10)) .build(); } //场景意图解析AI服务 @Bean public SceneSelectorAiAgent sceneSelectorAiAgent(OllamaChatModel sqlModel) { return AiServices.builder(SceneSelectorAiAgent.class) .chatLanguageModel(sqlModel) // 会话记忆:每个用户最多保留10轮对话,避免记忆溢出 .chatMemoryProvider(memoryId -> MessageWindowChatMemory.withMaxMessages(10)) .build(); } }