commit 500465e421d47ef2307475a0859205e512f2c42b Author: xiang Date: Sun Oct 26 22:00:40 2025 +0800 feat:init diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..5ff6309 --- /dev/null +++ b/.gitignore @@ -0,0 +1,38 @@ +target/ +!.mvn/wrapper/maven-wrapper.jar +!**/src/main/**/target/ +!**/src/test/**/target/ + +### IntelliJ IDEA ### +.idea/modules.xml +.idea/jarRepositories.xml +.idea/compiler.xml +.idea/libraries/ +*.iws +*.iml +*.ipr + +### Eclipse ### +.apt_generated +.classpath +.factorypath +.project +.settings +.springBeans +.sts4-cache + +### NetBeans ### +/nbproject/private/ +/nbbuild/ +/dist/ +/nbdist/ +/.nb-gradle/ +build/ +!**/src/main/**/build/ +!**/src/test/**/build/ + +### VS Code ### +.vscode/ + +### Mac OS ### +.DS_Store \ No newline at end of file diff --git a/pom.xml b/pom.xml new file mode 100644 index 0000000..27f9b3f --- /dev/null +++ b/pom.xml @@ -0,0 +1,141 @@ + + + + org.springframework.boot + spring-boot-starter-parent + 3.5.5 + + + pom + + xservice-service + xservice-server + + 4.0.0 + + com.xiang + xservice-ai-center + 1.0-SNAPSHOT + + + 17 + 17 + UTF-8 + 1.0.0.3 + 1.0.0 + + + + + spring-snapshots + Spring Snapshots + https://repo.spring.io/snapshot + + true + + + false + + + + Central Portal Snapshots + central-portal-snapshots + https://central.sonatype.com/repository/maven-snapshots/ + + false + + + true + + + + + + + + com.alibaba.cloud.ai + spring-ai-alibaba-bom + pom + import + ${springai.alibaba.version} + + + org.springframework.ai + spring-ai-bom + ${springai.version} + + + org.springframework.boot + spring-boot-dependencies + 3.5.5 + + + + + + + com.alibaba.cloud.ai + spring-ai-alibaba-starter-dashscope + ${springai.alibaba.version} + + + com.alibaba.cloud.ai + spring-ai-alibaba-graph-core + ${springai.alibaba.version} + + + com.alibaba.cloud.ai + spring-ai-alibaba-starter-memory-jdbc + ${springai.alibaba.version} + + + + mysql + mysql-connector-java + 8.0.33 + + + + org.springframework.ai + spring-ai-pdf-document-reader + ${springai.version} + + + org.springframework.ai + spring-ai-pgvector-store + ${springai.version} + + + org.springframework.ai + spring-ai-autoconfigure-vector-store-pgvector + ${springai.version} + + + org.springframework.ai + spring-ai-tika-document-reader + ${springai.version} + + + + + org.springframework.boot + spring-boot-starter + + + org.springframework.boot + spring-boot-starter-web + + + org.projectlombok + lombok + 1.18.32 + + + org.springframework.boot + spring-boot-starter-jdbc + + + + \ No newline at end of file diff --git a/xservice-server/pom.xml b/xservice-server/pom.xml new file mode 100644 index 0000000..abe4f48 --- /dev/null +++ b/xservice-server/pom.xml @@ -0,0 +1,28 @@ + + + 4.0.0 + + com.xiang + xservice-ai-center + 1.0-SNAPSHOT + + + xservice-server + + + 17 + 17 + UTF-8 + + + + + com.xiang + xservice-service + 1.0-SNAPSHOT + + + + \ No newline at end of file diff --git a/xservice-server/src/main/java/com/xiang/XserviceAIApplication.java b/xservice-server/src/main/java/com/xiang/XserviceAIApplication.java new file mode 100644 index 0000000..7138613 --- /dev/null +++ b/xservice-server/src/main/java/com/xiang/XserviceAIApplication.java @@ -0,0 +1,22 @@ +package com.xiang; + +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.springframework.boot.SpringApplication; +import org.springframework.boot.autoconfigure.SpringBootApplication; +import org.springframework.context.ConfigurableApplicationContext; +import org.springframework.core.env.Environment; + +@SpringBootApplication +public class XserviceAIApplication { + + private static final Logger log = LoggerFactory.getLogger(XserviceAIApplication.class); + + public static void main(String[] args) { + log.info("======> xservice stock center application 启动准备 <======"); + ConfigurableApplicationContext context = SpringApplication.run(XserviceAIApplication.class, args); + Environment environment = context.getBean(Environment.class); + log.info("启动环境配置:{}, 启动端口配置:{}", environment.getProperty("spring.profiles.active"), environment.getProperty("server.port")); + log.info("======> xservice ai center application 启动完成 <======"); + } +} diff --git a/xservice-server/src/main/java/com/xiang/xsa/xservice/ai/server/ChatController.java b/xservice-server/src/main/java/com/xiang/xsa/xservice/ai/server/ChatController.java new file mode 100644 index 0000000..97fe05f --- /dev/null +++ b/xservice-server/src/main/java/com/xiang/xsa/xservice/ai/server/ChatController.java @@ -0,0 +1,40 @@ +package com.xiang.xsa.xservice.ai.server; + +import lombok.RequiredArgsConstructor; +import org.springframework.ai.chat.client.ChatClient; +import org.springframework.ai.chat.client.advisor.MessageChatMemoryAdvisor; +import org.springframework.ai.chat.client.advisor.SimpleLoggerAdvisor; +import org.springframework.ai.chat.memory.ChatMemory; +import org.springframework.web.bind.annotation.PostMapping; +import org.springframework.web.bind.annotation.RequestParam; +import org.springframework.web.bind.annotation.RestController; +import reactor.core.publisher.Flux; + +@RestController +@RequiredArgsConstructor +public class ChatController { + + private final ChatClient chatClient; + private final ChatMemory chatMemory; + + @PostMapping("/chat") + public String chatDemo(@RequestParam("question") String question) { + return chatClient.prompt(question).call().content(); + } + + @PostMapping(value = "/chatWithFlux") + public Flux chatWithFlux(@RequestParam("question") String question) { + return chatClient.prompt(question).stream().content(); + } + + @PostMapping("/chatWithConversionId") + public String chatWithConversionId(@RequestParam("sessionId") String sessionId, @RequestParam("question") String question) { + + return chatClient.prompt() + .user(question) + .advisors( + MessageChatMemoryAdvisor.builder(chatMemory).conversationId(sessionId).build(), new SimpleLoggerAdvisor() + ) + .call().content(); + } +} diff --git a/xservice-server/src/main/resources/application.yml b/xservice-server/src/main/resources/application.yml new file mode 100644 index 0000000..fd5223a --- /dev/null +++ b/xservice-server/src/main/resources/application.yml @@ -0,0 +1,22 @@ +spring: + ai: + dashscope: + api-key: sk-07353fd191074c9c930b134230ba88ea + application: + name: xservice-ai-center + profiles: + active: local + datasource: + url: jdbc:mysql://rm-bp15t34gqx62jm069ro.mysql.rds.aliyuncs.com:3306/xservice-ai-center?useUnicode=true&characterEncoding=utf-8&serverTimezone=Asia/Shanghai&allowMultiQueries=true + username: root + password: xb#UWqnhH24&XpX + driver-class-name: com.mysql.cj.jdbc.Driver +server: + port: 38020 + # 返回结果UTF-8格式编码 + servlet: + encoding: + charset: UTF-8 + enabled: true + force: true + diff --git a/xservice-service/pom.xml b/xservice-service/pom.xml new file mode 100644 index 0000000..aeaefaf --- /dev/null +++ b/xservice-service/pom.xml @@ -0,0 +1,19 @@ + + + 4.0.0 + + com.xiang + xservice-ai-center + 1.0-SNAPSHOT + + + xservice-service + + + 17 + 17 + UTF-8 + + \ No newline at end of file diff --git a/xservice-service/src/main/java/com/xiang/xservice/ai/config/LlmClientConfig.java b/xservice-service/src/main/java/com/xiang/xservice/ai/config/LlmClientConfig.java new file mode 100644 index 0000000..fc4dcfd --- /dev/null +++ b/xservice-service/src/main/java/com/xiang/xservice/ai/config/LlmClientConfig.java @@ -0,0 +1,46 @@ +package com.xiang.xservice.ai.config; +import com.alibaba.cloud.ai.dashscope.chat.DashScopeChatOptions; +import com.alibaba.cloud.ai.memory.jdbc.MysqlChatMemoryRepository; +import org.springframework.ai.chat.client.ChatClient; +import org.springframework.ai.chat.client.advisor.MessageChatMemoryAdvisor; +import org.springframework.ai.chat.client.advisor.SimpleLoggerAdvisor; +import org.springframework.ai.chat.memory.ChatMemory; +import org.springframework.ai.chat.memory.MessageWindowChatMemory; +import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.Configuration; +import org.springframework.jdbc.core.JdbcTemplate; + + +/** + * 初始化llm客户端 + */ + +@Configuration +public class LlmClientConfig { + + private static final String DEFAULT_PROMPT = "你是一个友好的AI助手,可以根据用户提出的问题进行解答"; + + @Bean + public ChatClient initChatCLient(ChatClient.Builder charClientBuilder, ChatMemory chatMemory) { + return charClientBuilder + .defaultSystem(DEFAULT_PROMPT) + .defaultAdvisors( + new SimpleLoggerAdvisor(), + MessageChatMemoryAdvisor.builder(chatMemory).build() + ) + .defaultOptions( + DashScopeChatOptions.builder().withTemperature(1.2).build() + ).build(); + } + + @Bean + public ChatMemory initChatMemory(JdbcTemplate jdbcTemplate) { + return MessageWindowChatMemory.builder() + .chatMemoryRepository(MysqlChatMemoryRepository.mysqlBuilder() + .jdbcTemplate(jdbcTemplate) + .build()) + .maxMessages(100) + .build(); + } + +}