diff --git a/service-ai/pom.xml b/service-ai/pom.xml index aa083d7..b9366c1 100644 --- a/service-ai/pom.xml +++ b/service-ai/pom.xml @@ -11,7 +11,6 @@ Hudi AI服务集合 service-ai-core - service-ai-chat service-ai-knowledge service-ai-cli diff --git a/service-ai/service-ai-chat/pom.xml b/service-ai/service-ai-chat/pom.xml deleted file mode 100644 index e85b63f..0000000 --- a/service-ai/service-ai-chat/pom.xml +++ /dev/null @@ -1,56 +0,0 @@ - - - 4.0.0 - - com.lanyuanxiaoyao - service-ai - 1.0.0-SNAPSHOT - - - service-ai-chat - - - - com.lanyuanxiaoyao - service-ai-core - - - org.springframework.ai - spring-ai-starter-model-deepseek - - - org.springframework.ai - spring-ai-starter-model-openai - test - - - org.noear - solon-ai - test - - - org.noear - solon-ai-dialect-openai - test - - - - - - - org.springframework.boot - spring-boot-maven-plugin - - - package - - repackage - - - - - - - \ No newline at end of file diff --git a/service-ai/service-ai-chat/src/main/java/com/lanyuanxiaoyao/service/ai/chat/AiChatApplication.java b/service-ai/service-ai-chat/src/main/java/com/lanyuanxiaoyao/service/ai/chat/AiChatApplication.java deleted file mode 100644 index 1d9b9f5..0000000 --- a/service-ai/service-ai-chat/src/main/java/com/lanyuanxiaoyao/service/ai/chat/AiChatApplication.java +++ /dev/null @@ -1,37 +0,0 @@ -package com.lanyuanxiaoyao.service.ai.chat; - -import com.ulisesbocchio.jasyptspringboot.annotation.EnableEncryptableProperties; -import org.springframework.beans.BeansException; -import org.springframework.boot.SpringApplication; -import org.springframework.boot.autoconfigure.SpringBootApplication; -import org.springframework.boot.context.properties.EnableConfigurationProperties; -import org.springframework.cloud.client.discovery.EnableDiscoveryClient; -import org.springframework.context.ApplicationContext; -import org.springframework.context.ApplicationContextAware; -import org.springframework.retry.annotation.EnableRetry; - -/** - * @author lanyuanxiaoyao - * @version 20250514 - */ -@SpringBootApplication(scanBasePackages = "com.lanyuanxiaoyao.service") -@EnableDiscoveryClient -@EnableConfigurationProperties -@EnableEncryptableProperties -@EnableRetry -public class AiChatApplication implements ApplicationContextAware { - private static ApplicationContext context; - - public static void main(String[] args) { - SpringApplication.run(AiChatApplication.class, args); - } - - public static T getBean(Class clazz) { - return context.getBean(clazz); - } - - @Override - public void setApplicationContext(ApplicationContext context) throws BeansException { - AiChatApplication.context = context; - } -} diff --git a/service-ai/service-ai-chat/src/main/java/com/lanyuanxiaoyao/service/ai/chat/entity/MessageVO.java b/service-ai/service-ai-chat/src/main/java/com/lanyuanxiaoyao/service/ai/chat/entity/MessageVO.java deleted file mode 100644 index 90603e6..0000000 --- a/service-ai/service-ai-chat/src/main/java/com/lanyuanxiaoyao/service/ai/chat/entity/MessageVO.java +++ /dev/null @@ -1,44 +0,0 @@ -package com.lanyuanxiaoyao.service.ai.chat.entity; - -/** - * @author lanyuanxiaoyao - * @version 20250516 - */ -public class MessageVO { - private String role; - private String content; - private String reason; - - public String getRole() { - return role; - } - - public void setRole(String role) { - this.role = role; - } - - public String getContent() { - return content; - } - - public void setContent(String content) { - this.content = content; - } - - public String getReason() { - return reason; - } - - public void setReason(String reason) { - this.reason = reason; - } - - @Override - public String toString() { - return "MessageVO{" + - "role='" + role + '\'' + - ", content='" + content + '\'' + - ", reason='" + reason + '\'' + - '}'; - } -} diff --git a/service-ai/service-ai-chat/src/main/resources/application.yml b/service-ai/service-ai-chat/src/main/resources/application.yml deleted file mode 100644 index 5a98dbc..0000000 --- a/service-ai/service-ai-chat/src/main/resources/application.yml +++ /dev/null @@ -1,15 +0,0 @@ -spring: - application: - name: service-ai-chat - profiles: - include: random-port,common,discovery,metrics,forest - ai: - deepseek: - base-url: http://132.121.206.65:10086/v1 - api-key: ENC(K+Hff9QGC+fcyi510VIDd9CaeK/IN5WBJ9rlkUsHEdDgIidW+stHHJlsK0lLPUXXREha+ToQZqqDXJrqSE+GUKCXklFhelD8bRHFXBIeP/ZzT2cxhzgKUXgjw3S0Qw2R) - chat: - options: - model: 'Qwen3/qwen3-1.7b' - mvc: - async: - request-timeout: 3600000 diff --git a/service-ai/service-ai-chat/src/main/resources/logback-spring.xml b/service-ai/service-ai-chat/src/main/resources/logback-spring.xml deleted file mode 100644 index d686c9c..0000000 --- a/service-ai/service-ai-chat/src/main/resources/logback-spring.xml +++ /dev/null @@ -1,34 +0,0 @@ - - - - - - - - - - - - %d{yyyy-MM-dd HH:mm:ss.SSS} %clr(%5p) %clr([${HOSTNAME}]){yellow} %clr([%t]){magenta} %clr(%logger{40}){cyan} #@# %m%n%wEx - - - - - ${LOGGING_PARENT:-.}/${APP_NAME:-run}.log - - ${LOGGING_PARENT:-.}/archive/${APP_NAME:-run}-%d{yyyy-MM-dd}.gz - 7 - - - %d{yyyy-MM-dd HH:mm:ss.SSS} %p [${HOSTNAME}] [%t] %logger #@# %m%n%wEx - - - - - - - - - - - \ No newline at end of file diff --git a/service-ai/service-ai-chat/src/test/java/com/lanyuanxiaoyao/service/ai/chat/TestDatetimeFormat.java b/service-ai/service-ai-chat/src/test/java/com/lanyuanxiaoyao/service/ai/chat/TestDatetimeFormat.java deleted file mode 100644 index c8b5dbd..0000000 --- a/service-ai/service-ai-chat/src/test/java/com/lanyuanxiaoyao/service/ai/chat/TestDatetimeFormat.java +++ /dev/null @@ -1,16 +0,0 @@ -package com.lanyuanxiaoyao.service.ai.chat; - -import java.time.LocalDate; -import java.time.format.DateTimeFormatter; - -/** - * @author lanyuanxiaoyao - * @version 20250606 - */ -public class TestDatetimeFormat { - private static final DateTimeFormatter FORMATTER = DateTimeFormatter.ofPattern("yyyyMMdd"); - - public static void main(String[] args) { - System.out.println(LocalDate.parse("20250606", FORMATTER).format(FORMATTER)); - } -} diff --git a/service-ai/service-ai-chat/src/test/java/com/lanyuanxiaoyao/service/ai/chat/TestLlmPlan.java b/service-ai/service-ai-chat/src/test/java/com/lanyuanxiaoyao/service/ai/chat/TestLlmPlan.java deleted file mode 100644 index 3da1c94..0000000 --- a/service-ai/service-ai-chat/src/test/java/com/lanyuanxiaoyao/service/ai/chat/TestLlmPlan.java +++ /dev/null @@ -1,76 +0,0 @@ -package com.lanyuanxiaoyao.service.ai.chat; - -import cn.hutool.core.util.StrUtil; -import com.lanyuanxiaoyao.service.ai.chat.tools.TableTool; -import com.lanyuanxiaoyao.service.ai.chat.tools.YarnTool; -import java.net.http.HttpClient; -import org.springframework.ai.chat.client.ChatClient; -import org.springframework.ai.deepseek.DeepSeekChatModel; -import org.springframework.ai.deepseek.DeepSeekChatOptions; -import org.springframework.ai.deepseek.api.DeepSeekApi; -import org.springframework.http.client.JdkClientHttpRequestFactory; -import org.springframework.http.client.reactive.JdkClientHttpConnector; -import org.springframework.web.client.RestClient; -import org.springframework.web.reactive.function.client.WebClient; - -public class TestLlmPlan { - public static void main(String[] args) { - ChatClient client = ChatClient.builder( - DeepSeekChatModel.builder() - .deepSeekApi( - DeepSeekApi.builder() - .baseUrl("http://127.0.0.1:1234/v1") - .apiKey("nopassword") - .restClientBuilder(restClientBuilder()) - .webClientBuilder(webClientBuilder()) - .build() - ) - .defaultOptions( - DeepSeekChatOptions.builder() - .model("qwen/qwen3-1.7b") - .build() - ) - .build() - ) - .defaultSystem(StrUtil.format( - """ - 你是一名专业的AI运维助手,专职负责“Hudi数据同步服务”的平台运维工作。你的核心职责是: - 1.友好解答:积极、专业地解答用户(通常是平台管理员或用户)关于该平台运维工作的疑问。 - 2.知识驱动:在解答时,应尽可能通过各种方式(知识库、上下文、外部工具等)全面获取准确知识和数据来支持回答。 - 3.诚实守界: - 对于无法通过已有知识或数据确认的问题,必须明确告知用户你无法解答,切勿捏造信息或提供不确定的答案。 - 对于与该Hudi数据同步服务平台运维工作无关的问题,需委婉拒绝用户,并明确说明超出你的职责和能力范围。 - - 对话语言:中文 - - {} - """, - Prompts.hudi - )) - .defaultTools( - new TableTool(), - new YarnTool() - ) - .build(); - System.out.println(client.prompt(""" - 我需要大模型帮我检查系统整体运行状态,帮我设计详细的指导大模型具体操作的操作步骤 - 避免使用上下文中没有提到的外部工具 - """).call().content()); - } - - private static HttpClient httpClient() { - return HttpClient.newBuilder() - .version(HttpClient.Version.HTTP_1_1) - .build(); - } - - private static RestClient.Builder restClientBuilder() { - return RestClient.builder() - .requestFactory(new JdkClientHttpRequestFactory(httpClient())); - } - - private static WebClient.Builder webClientBuilder() { - return WebClient.builder() - .clientConnector(new JdkClientHttpConnector(httpClient())); - } -} diff --git a/service-ai/service-ai-chat/src/test/java/com/lanyuanxiaoyao/service/ai/chat/TestModel.java b/service-ai/service-ai-chat/src/test/java/com/lanyuanxiaoyao/service/ai/chat/TestModel.java deleted file mode 100644 index 94d15c6..0000000 --- a/service-ai/service-ai-chat/src/test/java/com/lanyuanxiaoyao/service/ai/chat/TestModel.java +++ /dev/null @@ -1,169 +0,0 @@ -package com.lanyuanxiaoyao.service.ai.chat; - -import cn.hutool.core.util.StrUtil; -import java.io.IOException; -import java.net.http.HttpClient; -import java.time.Duration; -import java.util.Arrays; -import java.util.List; -import org.noear.solon.ai.rag.Document; -import org.noear.solon.ai.reranking.RerankingModel; -import org.springframework.ai.chat.client.ChatClient; -import org.springframework.ai.document.MetadataMode; -import org.springframework.ai.embedding.EmbeddingModel; -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.openai.api.OpenAiApi; -import org.springframework.core.io.FileSystemResource; -import org.springframework.http.client.JdkClientHttpRequestFactory; -import org.springframework.http.client.reactive.JdkClientHttpConnector; -import org.springframework.util.MimeTypeUtils; -import org.springframework.web.client.RestClient; -import org.springframework.web.reactive.function.client.WebClient; - -/** - * @author lanyuanxiaoyao - * @version 20250514 - */ -public class TestModel { - public static void main(String[] args) throws IOException { - // testChatModel(); - testVisualModel(); - testEmbeddingModel(); - testRerankingModel(); - } - - private static void testChatModel() { - for (String model : List.of( - "Qwen3/qwen3-0.6b", - "Qwen3/qwen3-1.7b", - "Qwen3/qwen3-4b", - "Qwen3/qwen3-4b-q4km", - "Qwen3/qwen3-8b-q4km" - )) { - System.out.println(model); - long start = System.currentTimeMillis(); - ChatClient client = chatClient(model); - String content = client.prompt() - .user("你好,详细介绍一下是谁,能帮我做什么?") - .call() - .content(); - System.out.println(content.length() * 1000.0 / (System.currentTimeMillis() - start)); - } - } - - private static void testVisualModel() { - for (String model : List.of( - "Qwen2.5/qwen2.5-vl-7b", - "Qwen2.5/qwen2.5-vl-7b-q4km", - "Qwen2.5/qwen2.5-vl-3b-instruct", - "Qwen2.5/qwen2.5-vl-7b-instruct", - "MiniCPM/minicpm-o-2.6-7.6b", - "MiniCPM/minicpm-o-2.6-7.6b-q4km" - - )) { - ChatClient client = chatClient(model); - String content = client.prompt() - .user(spec -> spec.text("根据图片中的内容编一个童话小故事").media(MimeTypeUtils.IMAGE_PNG, new FileSystemResource("/Users/lanyuanxiaoyao/Pictures/deepseek.png"))) - .call() - .content(); - System.out.println(StrUtil.trim(content)); - } - } - - private static void testEmbeddingModel() { - for (String model : List.of( - "Qwen3/qwen3-embedding-0.6b", - "Qwen3/qwen3-embedding-4b", - "Qwen3/qwen3-embedding-4b-q4km", - "Qwen3/qwen3-embedding-8b-q4km", - "BGE/bge-m3", - "BGE/bge-m3-q4km" - )) { - EmbeddingModel embeddingModel = embeddingModel(model); - float[] worlds = embeddingModel.embed("Hello world"); - System.out.println(Arrays.toString(worlds)); - } - } - - private static void testRerankingModel() throws IOException { - for (String model : List.of( - "BGE/beg-reranker-v2", - "BGE/beg-reranker-v2-q4km" - )) { - System.out.println(model); - RerankingModel rerankingModel = rerankingModel(model); - List list = rerankingModel.rerank( - "你好", - List.of( - new Document("go go go,滚犊子"), - new Document("我是tom,你最近过得好吗?"), - new Document("666,你就是大聪明") - ) - ); - list.forEach(System.out::println); - } - } - - private static ChatClient chatClient(String model) { - return ChatClient.builder( - OpenAiChatModel.builder() - .openAiApi( - OpenAiApi.builder() - .baseUrl("http://132.121.206.65:10086") - .apiKey("*XMySqV%>hR&v>>g*NwCs3tpQ5FVMFEF2VHVTjhR&v>>g*NwCs3tpQ5FVMFEF2VHVTjhR&v>>g*NwCs3tpQ5FVMFEF2VHVTjhR&v>>g*NwCs3tpQ5FVMFEF2VHVTj registry.anyRequest().authenticated()) + return http.authorizeHttpRequests( + registry -> registry + .requestMatchers(HttpMethod.OPTIONS, "/**") + .permitAll() + .anyRequest() + .authenticated() + ) .httpBasic(Customizer.withDefaults()) .cors(AbstractHttpConfigurer::disable) .csrf(AbstractHttpConfigurer::disable) diff --git a/service-ai/service-ai-knowledge/src/main/java/com/lanyuanxiaoyao/service/ai/knowledge/KnowledgeApplication.java b/service-ai/service-ai-knowledge/src/main/java/com/lanyuanxiaoyao/service/ai/knowledge/KnowledgeApplication.java index cee0e37..3e492d7 100644 --- a/service-ai/service-ai-knowledge/src/main/java/com/lanyuanxiaoyao/service/ai/knowledge/KnowledgeApplication.java +++ b/service-ai/service-ai-knowledge/src/main/java/com/lanyuanxiaoyao/service/ai/knowledge/KnowledgeApplication.java @@ -1,12 +1,15 @@ package com.lanyuanxiaoyao.service.ai.knowledge; import com.ulisesbocchio.jasyptspringboot.annotation.EnableEncryptableProperties; +import org.springframework.beans.BeansException; import org.springframework.boot.ApplicationArguments; import org.springframework.boot.ApplicationRunner; import org.springframework.boot.SpringApplication; import org.springframework.boot.autoconfigure.SpringBootApplication; import org.springframework.boot.context.properties.EnableConfigurationProperties; import org.springframework.cloud.client.discovery.EnableDiscoveryClient; +import org.springframework.context.ApplicationContext; +import org.springframework.context.ApplicationContextAware; import org.springframework.retry.annotation.EnableRetry; import org.springframework.scheduling.annotation.EnableScheduling; @@ -20,12 +23,23 @@ import org.springframework.scheduling.annotation.EnableScheduling; @EnableEncryptableProperties @EnableRetry @EnableScheduling -public class KnowledgeApplication implements ApplicationRunner { +public class KnowledgeApplication implements ApplicationRunner, ApplicationContextAware { + private static ApplicationContext context; + public static void main(String[] args) { SpringApplication.run(KnowledgeApplication.class, args); } + public static T getBean(Class clazz) { + return context.getBean(clazz); + } + @Override public void run(ApplicationArguments args) { } + + @Override + public void setApplicationContext(ApplicationContext context) throws BeansException { + KnowledgeApplication.context = context; + } } diff --git a/service-ai/service-ai-chat/src/main/java/com/lanyuanxiaoyao/service/ai/chat/Prompts.java b/service-ai/service-ai-knowledge/src/main/java/com/lanyuanxiaoyao/service/ai/knowledge/configuration/Prompts.java similarity index 99% rename from service-ai/service-ai-chat/src/main/java/com/lanyuanxiaoyao/service/ai/chat/Prompts.java rename to service-ai/service-ai-knowledge/src/main/java/com/lanyuanxiaoyao/service/ai/knowledge/configuration/Prompts.java index f331903..355e3d5 100644 --- a/service-ai/service-ai-chat/src/main/java/com/lanyuanxiaoyao/service/ai/chat/Prompts.java +++ b/service-ai/service-ai-knowledge/src/main/java/com/lanyuanxiaoyao/service/ai/knowledge/configuration/Prompts.java @@ -1,4 +1,4 @@ -package com.lanyuanxiaoyao.service.ai.chat; +package com.lanyuanxiaoyao.service.ai.knowledge.configuration; import cn.hutool.core.util.StrUtil; diff --git a/service-ai/service-ai-chat/src/main/java/com/lanyuanxiaoyao/service/ai/chat/controller/ChatController.java b/service-ai/service-ai-knowledge/src/main/java/com/lanyuanxiaoyao/service/ai/knowledge/controller/caht/ChatController.java similarity index 83% rename from service-ai/service-ai-chat/src/main/java/com/lanyuanxiaoyao/service/ai/chat/controller/ChatController.java rename to service-ai/service-ai-knowledge/src/main/java/com/lanyuanxiaoyao/service/ai/knowledge/controller/caht/ChatController.java index 6b3a3f6..fc6173b 100644 --- a/service-ai/service-ai-chat/src/main/java/com/lanyuanxiaoyao/service/ai/chat/controller/ChatController.java +++ b/service-ai/service-ai-knowledge/src/main/java/com/lanyuanxiaoyao/service/ai/knowledge/controller/caht/ChatController.java @@ -1,13 +1,13 @@ -package com.lanyuanxiaoyao.service.ai.chat.controller; +package com.lanyuanxiaoyao.service.ai.knowledge.controller.caht; import cn.hutool.core.util.ObjectUtil; import cn.hutool.core.util.StrUtil; -import com.lanyuanxiaoyao.service.ai.chat.Prompts; -import com.lanyuanxiaoyao.service.ai.chat.entity.MessageVO; -import com.lanyuanxiaoyao.service.ai.chat.tools.ChartTool; -import com.lanyuanxiaoyao.service.ai.chat.tools.KnowledgeTool; -import com.lanyuanxiaoyao.service.ai.chat.tools.TableTool; -import com.lanyuanxiaoyao.service.ai.chat.tools.YarnTool; +import com.lanyuanxiaoyao.service.ai.knowledge.configuration.Prompts; +import com.lanyuanxiaoyao.service.ai.knowledge.entity.vo.MessageVO; +import com.lanyuanxiaoyao.service.ai.knowledge.tools.ChartTool; +import com.lanyuanxiaoyao.service.ai.knowledge.tools.KnowledgeTool; +import com.lanyuanxiaoyao.service.ai.knowledge.tools.TableTool; +import com.lanyuanxiaoyao.service.ai.knowledge.tools.YarnTool; import java.io.IOException; import java.time.LocalDateTime; import java.time.format.DateTimeFormatter; @@ -22,6 +22,7 @@ import org.springframework.ai.chat.messages.UserMessage; import org.springframework.ai.chat.model.ChatResponse; import org.springframework.ai.chat.model.Generation; import org.springframework.ai.deepseek.DeepSeekAssistantMessage; +import org.springframework.beans.factory.annotation.Qualifier; import org.springframework.stereotype.Controller; import org.springframework.web.bind.annotation.PostMapping; import org.springframework.web.bind.annotation.RequestBody; @@ -46,11 +47,11 @@ public class ChatController { private final ChatClient chatClient; - public ChatController(ChatClient.Builder builder) { + public ChatController(@Qualifier("chat") ChatClient.Builder builder) { this.chatClient = builder.build(); } - private ChatClient.ChatClientRequestSpec buildRequest(Long knowledgeId, ImmutableList messages) { + private ChatClient.ChatClientRequestSpec buildRequest(ImmutableList messages) { ChatClient.ChatClientRequestSpec spec = chatClient.prompt() .system( StrUtil.format(""" @@ -79,9 +80,6 @@ public class ChatController { .collect(message -> (Message) message) .toList() ); - if (ObjectUtil.isNotNull(knowledgeId)) { - spec.tools(new KnowledgeTool(knowledgeId)); - } spec.tools( new TableTool(), new YarnTool(), @@ -93,10 +91,9 @@ public class ChatController { @PostMapping("sync") @ResponseBody public MessageVO chatSync( - @RequestParam(value = "knowledge_id", required = false) Long knowledgeId, @RequestBody ImmutableList messages ) { - ChatResponse response = buildRequest(knowledgeId, messages) + ChatResponse response = buildRequest(messages) .call() .chatResponse(); return toMessage(response); @@ -104,11 +101,10 @@ public class ChatController { @PostMapping("async") public SseEmitter chatAsync( - @RequestParam(value = "knowledge_id", required = false) Long knowledgeId, @RequestBody ImmutableList messages ) { SseEmitter emitter = new SseEmitter(); - buildRequest(knowledgeId, messages) + buildRequest(messages) .stream() .chatResponse() .subscribe( diff --git a/service-ai/service-ai-knowledge/src/main/java/com/lanyuanxiaoyao/service/ai/knowledge/entity/vo/MessageVO.java b/service-ai/service-ai-knowledge/src/main/java/com/lanyuanxiaoyao/service/ai/knowledge/entity/vo/MessageVO.java new file mode 100644 index 0000000..a5d6288 --- /dev/null +++ b/service-ai/service-ai-knowledge/src/main/java/com/lanyuanxiaoyao/service/ai/knowledge/entity/vo/MessageVO.java @@ -0,0 +1,14 @@ +package com.lanyuanxiaoyao.service.ai.knowledge.entity.vo; + +import lombok.Data; + +/** + * @author lanyuanxiaoyao + * @version 20250516 + */ +@Data +public class MessageVO { + private String role; + private String content; + private String reason; +} diff --git a/service-ai/service-ai-chat/src/main/java/com/lanyuanxiaoyao/service/ai/chat/tools/ChartTool.java b/service-ai/service-ai-knowledge/src/main/java/com/lanyuanxiaoyao/service/ai/knowledge/tools/ChartTool.java similarity index 90% rename from service-ai/service-ai-chat/src/main/java/com/lanyuanxiaoyao/service/ai/chat/tools/ChartTool.java rename to service-ai/service-ai-knowledge/src/main/java/com/lanyuanxiaoyao/service/ai/knowledge/tools/ChartTool.java index 66b4caa..fd1d5bc 100644 --- a/service-ai/service-ai-chat/src/main/java/com/lanyuanxiaoyao/service/ai/chat/tools/ChartTool.java +++ b/service-ai/service-ai-knowledge/src/main/java/com/lanyuanxiaoyao/service/ai/knowledge/tools/ChartTool.java @@ -1,8 +1,7 @@ -package com.lanyuanxiaoyao.service.ai.chat.tools; +package com.lanyuanxiaoyao.service.ai.knowledge.tools; -import com.lanyuanxiaoyao.service.ai.chat.AiChatApplication; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; +import com.lanyuanxiaoyao.service.ai.knowledge.KnowledgeApplication; +import lombok.extern.slf4j.Slf4j; import org.springframework.ai.chat.client.ChatClient; import org.springframework.ai.tool.annotation.Tool; import org.springframework.ai.tool.annotation.ToolParam; @@ -13,9 +12,8 @@ import org.springframework.ai.tool.annotation.ToolParam; * @author lanyuanxiaoyao * @version 20250611 */ +@Slf4j public class ChartTool { - private static final Logger logger = LoggerFactory.getLogger(ChartTool.class); - @Tool(description = """ 根据需求生成mermaid图表代码 """) @@ -45,8 +43,8 @@ public class ChartTool { 其他:箭头类型(实线/虚线)、注释文本等 """) String request ) { - logger.info("Enter method: mermaid[request]. request:{}", request); - ChatClient.Builder builder = AiChatApplication.getBean(ChatClient.Builder.class); + log.info("Enter method: mermaid[request]. request:{}", request); + ChatClient.Builder builder = KnowledgeApplication.getBean(ChatClient.Builder.class); ChatClient client = builder.build(); return client.prompt() // language=TEXT diff --git a/service-ai/service-ai-chat/src/main/java/com/lanyuanxiaoyao/service/ai/chat/tools/KnowledgeTool.java b/service-ai/service-ai-knowledge/src/main/java/com/lanyuanxiaoyao/service/ai/knowledge/tools/KnowledgeTool.java similarity index 83% rename from service-ai/service-ai-chat/src/main/java/com/lanyuanxiaoyao/service/ai/chat/tools/KnowledgeTool.java rename to service-ai/service-ai-knowledge/src/main/java/com/lanyuanxiaoyao/service/ai/knowledge/tools/KnowledgeTool.java index 5c42b30..063900a 100644 --- a/service-ai/service-ai-chat/src/main/java/com/lanyuanxiaoyao/service/ai/chat/tools/KnowledgeTool.java +++ b/service-ai/service-ai-knowledge/src/main/java/com/lanyuanxiaoyao/service/ai/knowledge/tools/KnowledgeTool.java @@ -1,8 +1,8 @@ -package com.lanyuanxiaoyao.service.ai.chat.tools; +package com.lanyuanxiaoyao.service.ai.knowledge.tools; import cn.hutool.core.util.ObjectUtil; import cn.hutool.core.util.StrUtil; -import com.lanyuanxiaoyao.service.ai.chat.AiChatApplication; +import com.lanyuanxiaoyao.service.ai.knowledge.KnowledgeApplication; import com.lanyuanxiaoyao.service.forest.service.KnowledgeService; import org.springframework.ai.tool.annotation.Tool; import org.springframework.ai.tool.annotation.ToolParam; @@ -27,7 +27,7 @@ public class KnowledgeTool { """) String query ) { - KnowledgeService knowledgeService = AiChatApplication.getBean(KnowledgeService.class); + KnowledgeService knowledgeService = KnowledgeApplication.getBean(KnowledgeService.class); var documents = knowledgeService.query(knowledgeId, query, 10, 0.5); if (ObjectUtil.isNotEmpty(documents)) { return StrUtil.format(""" diff --git a/service-ai/service-ai-chat/src/main/java/com/lanyuanxiaoyao/service/ai/chat/tools/TableTool.java b/service-ai/service-ai-knowledge/src/main/java/com/lanyuanxiaoyao/service/ai/knowledge/tools/TableTool.java similarity index 84% rename from service-ai/service-ai-chat/src/main/java/com/lanyuanxiaoyao/service/ai/chat/tools/TableTool.java rename to service-ai/service-ai-knowledge/src/main/java/com/lanyuanxiaoyao/service/ai/knowledge/tools/TableTool.java index d244a61..10122d7 100644 --- a/service-ai/service-ai-chat/src/main/java/com/lanyuanxiaoyao/service/ai/chat/tools/TableTool.java +++ b/service-ai/service-ai-knowledge/src/main/java/com/lanyuanxiaoyao/service/ai/knowledge/tools/TableTool.java @@ -1,11 +1,12 @@ -package com.lanyuanxiaoyao.service.ai.chat.tools; +package com.lanyuanxiaoyao.service.ai.knowledge.tools; import cn.hutool.core.util.StrUtil; -import com.lanyuanxiaoyao.service.ai.chat.AiChatApplication; +import com.lanyuanxiaoyao.service.ai.knowledge.KnowledgeApplication; import com.lanyuanxiaoyao.service.forest.service.InfoService; import java.time.LocalDate; import java.time.LocalDateTime; import java.time.format.DateTimeFormatter; +import lombok.extern.slf4j.Slf4j; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.springframework.ai.tool.annotation.Tool; @@ -15,8 +16,8 @@ import org.springframework.ai.tool.annotation.ToolParam; * @author lanyuanxiaoyao * @version 20250605 */ +@Slf4j public class TableTool { - private static final Logger logger = LoggerFactory.getLogger(TableTool.class); private static final DateTimeFormatter FORMATTER = DateTimeFormatter.ofPattern("yyyyMMdd"); @Tool(description = """ @@ -27,12 +28,12 @@ public class TableTool { 完整的MySQL查询语句,禁止使用除select外的任何语句。 """) String sql ) { - logger.info("Enter method: executeJdbc[sql]. sql:{}", sql); - InfoService infoService = AiChatApplication.getBean(InfoService.class); + log.info("Enter method: executeJdbc[sql]. sql:{}", sql); + InfoService infoService = KnowledgeApplication.getBean(InfoService.class); String result = infoService.jdbc(sql) .collect(map -> map.valuesView().makeString(",")) .makeString("\n"); - logger.info("SQL result: \n{}", result); + log.info("SQL result: \n{}", result); return result; } @@ -48,8 +49,8 @@ public class TableTool { 一次调用只能传一个类型,不支持多个类型同时查询 """) String type ) { - logger.info("Enter method: tableCount[type]. type:{}", type); - var infoService = AiChatApplication.getBean(InfoService.class); + log.info("Enter method: tableCount[type]. type:{}", type); + var infoService = KnowledgeApplication.getBean(InfoService.class); return switch (type) { case "logic" -> StrUtil.format(""" 逻辑表共{}张,其中重点表{}张 @@ -83,8 +84,8 @@ public class TableTool { """) String type ) { - logger.info("Enter method: version[date, type]. date:{},type:{}", date, type); - InfoService infoService = AiChatApplication.getBean(InfoService.class); + log.info("Enter method: version[date, type]. date:{},type:{}", date, type); + InfoService infoService = KnowledgeApplication.getBean(InfoService.class); String version = date; if (StrUtil.isBlank(version)) { version = LocalDateTime.now().minusDays(1).format(FORMATTER); diff --git a/service-ai/service-ai-chat/src/main/java/com/lanyuanxiaoyao/service/ai/chat/tools/YarnTool.java b/service-ai/service-ai-knowledge/src/main/java/com/lanyuanxiaoyao/service/ai/knowledge/tools/YarnTool.java similarity index 79% rename from service-ai/service-ai-chat/src/main/java/com/lanyuanxiaoyao/service/ai/chat/tools/YarnTool.java rename to service-ai/service-ai-knowledge/src/main/java/com/lanyuanxiaoyao/service/ai/knowledge/tools/YarnTool.java index 6c6a24c..72d1f62 100644 --- a/service-ai/service-ai-chat/src/main/java/com/lanyuanxiaoyao/service/ai/chat/tools/YarnTool.java +++ b/service-ai/service-ai-knowledge/src/main/java/com/lanyuanxiaoyao/service/ai/knowledge/tools/YarnTool.java @@ -1,11 +1,12 @@ -package com.lanyuanxiaoyao.service.ai.chat.tools; +package com.lanyuanxiaoyao.service.ai.knowledge.tools; import cn.hutool.core.util.StrUtil; -import com.lanyuanxiaoyao.service.ai.chat.AiChatApplication; +import com.lanyuanxiaoyao.service.ai.knowledge.KnowledgeApplication; import com.lanyuanxiaoyao.service.configuration.entity.yarn.YarnApplication; import com.lanyuanxiaoyao.service.configuration.entity.yarn.YarnQueue; import com.lanyuanxiaoyao.service.configuration.entity.yarn.YarnRootQueue; import com.lanyuanxiaoyao.service.forest.service.YarnService; +import lombok.extern.slf4j.Slf4j; import org.eclipse.collections.api.list.ImmutableList; import org.slf4j.Logger; import org.slf4j.LoggerFactory; @@ -16,9 +17,8 @@ import org.springframework.ai.tool.annotation.ToolParam; * @author lanyuanxiaoyao * @version 20250606 */ +@Slf4j public class YarnTool { - private static final Logger logger = LoggerFactory.getLogger(YarnTool.class); - @Tool(description = """ 查询yarn集群整体资源情况,返回值为资源占用率(%) """) @@ -28,8 +28,8 @@ public class YarnTool { 一次调用只能查询一个集群,不支持多个集群同时查询 """) String cluster ) { - logger.info("Enter method: yarnStatus[cluster]. cluster:{}", cluster); - YarnService yarnService = AiChatApplication.getBean(YarnService.class); + log.info("Enter method: yarnStatus[cluster]. cluster:{}", cluster); + YarnService yarnService = KnowledgeApplication.getBean(YarnService.class); YarnRootQueue status = yarnService.cluster(cluster); return (status.getUsedCapacity() * 100.0) / status.getCapacity(); } @@ -46,8 +46,8 @@ public class YarnTool { yarn队列名称 """) String queue ) { - logger.info("Enter method: yarnQueueStatus[cluster, queue]. cluster:{},queue:{}", cluster, queue); - YarnService yarnService = AiChatApplication.getBean(YarnService.class); + log.info("Enter method: yarnQueueStatus[cluster, queue]. cluster:{},queue:{}", cluster, queue); + YarnService yarnService = KnowledgeApplication.getBean(YarnService.class); YarnQueue status = yarnService.queueDetail(cluster, queue); return (status.getAbsoluteCapacity() * 100.0) / status.getAbsoluteMaxCapacity(); } @@ -67,8 +67,8 @@ public class YarnTool { 一次调用只能传一个类型,不支持多个类型同时查询 """) String type ) { - logger.info("Enter method: yarnTaskStatus[cluster, type]. cluster:{},type:{}", cluster, type); - YarnService yarnService = AiChatApplication.getBean(YarnService.class); + log.info("Enter method: yarnTaskStatus[cluster, type]. cluster:{},type:{}", cluster, type); + YarnService yarnService = KnowledgeApplication.getBean(YarnService.class); ImmutableList applications = yarnService.jobList(cluster).select(app -> StrUtil.isNotBlank(type) && StrUtil.contains(app.getName(), type)); return StrUtil.format( """ diff --git a/service-web/client/src/pages/ai/Conversation.tsx b/service-web/client/src/pages/ai/Conversation.tsx index ad1a229..a7a6e59 100644 --- a/service-web/client/src/pages/ai/Conversation.tsx +++ b/service-web/client/src/pages/ai/Conversation.tsx @@ -1,9 +1,8 @@ -import {ClearOutlined, FileOutlined, UserOutlined} from '@ant-design/icons' +import {ClearOutlined, UserOutlined} from '@ant-design/icons' import {Bubble, Sender, useXAgent, useXChat, Welcome} from '@ant-design/x' import {fetchEventSource} from '@echofly/fetch-event-source' -import {useMount} from 'ahooks' -import {Button, Collapse, Flex, Popover, Radio, Typography} from 'antd' -import {isEqual, isStrBlank, trim} from 'licia' +import {Button, Collapse, Flex, Typography} from 'antd' +import {isStrBlank, trim} from 'licia' import {useRef, useState} from 'react' import styled from 'styled-components' import {commonInfo} from '../../util/amis.tsx' @@ -40,24 +39,10 @@ type ChatMessage = { role: string, content?: string, reason?: string } function Conversation() { const abortController = useRef(null) const [input, setInput] = useState('') - const [knowledge, setKnowledge] = useState('0') - const [knowledgeList, setKnowledgeList] = useState<{ id: string, name: string }[]>([]) - - useMount(async () => { - let response = await fetch(`${commonInfo.baseAiKnowledgeUrl}/knowledge/list`, { - headers: commonInfo.authorizationHeaders, - }) - let items = (await response.json()).data.items - setKnowledgeList(items.map((item: { id: string, name: string }) => ({id: item.id, name: item.name}))) - }) const [agent] = useXAgent({ request: async (info, callbacks) => { - let requestUrl = `${commonInfo.baseAiChatUrl}/chat/async` - if (!isEqual('0', info.knowledge)) { - requestUrl = `${requestUrl}?knowledge_id=${info.knowledge}` - } - await fetchEventSource(requestUrl, { + await fetchEventSource(`${commonInfo.baseAiChatUrl}/chat/async`, { method: 'POST', headers: commonInfo.authorizationHeaders, body: JSON.stringify(info.messages), @@ -180,7 +165,6 @@ function Conversation() { content: message, }, stream: true, - knowledge: knowledge, }) setInput('') }} @@ -190,32 +174,6 @@ function Conversation() { return ( - setKnowledge(event.target.value)} - options={[ - {value: '0', label: '无'}, - ...knowledgeList.map(k => ({label: k.name, value: k.id})), - ]} - />} - > - -