From 21b60a0216843eef51ba434e0eb732ef665cb9aa Mon Sep 17 00:00:00 2001
From: liyongde <1419499670@qq.com>
Date: Sat, 7 Jun 2025 22:32:41 +0800
Subject: [PATCH] =?UTF-8?q?feat:=20ollama=E6=B5=81=E5=BC=8F=E5=BA=94?=
=?UTF-8?q?=E7=AD=94=E6=8E=A5=E5=8F=A3=E5=AE=9E=E7=8E=B0?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
---
.idea/uiDesigner.xml | 124 ++++++++++++++++++
.../java/com/storm/dev/api/IAiService.java | 26 ++++
.../{ => com/storm/dev/api}/package-info.java | 3 +-
ai-rag-app/pom.xml | 28 ++--
.../main/java/com/storm/dev/Application.java | 18 +++
.../com/storm/dev/config/OllamaConfig.java | 27 ++++
.../storm/dev/config/RedisClientConfig.java | 42 ++++++
.../config/RedisClientConfigProperties.java | 37 ++++++
.../main/java/com/storm/dev/package-info.java | 6 +
.../src/main/resources/application-dev.yml | 27 ++++
.../src/main/resources/application-prod.yml | 7 +
.../src/main/resources/application-test.yml | 7 +
ai-rag-app/src/main/resources/application.yml | 5 +
.../src/main/resources/logback-spring.xml | 113 ++++++++++++++++
ai-rag-trigger/pom.xml | 24 ++--
.../dev/trigger/http/OllamaController.java | 41 ++++++
.../com/storm/dev/trigger/package-info.java | 6 +
17 files changed, 515 insertions(+), 26 deletions(-)
create mode 100644 .idea/uiDesigner.xml
create mode 100644 ai-rag-api/src/main/java/com/storm/dev/api/IAiService.java
rename ai-rag-api/src/main/java/{ => com/storm/dev/api}/package-info.java (60%)
create mode 100644 ai-rag-app/src/main/java/com/storm/dev/Application.java
create mode 100644 ai-rag-app/src/main/java/com/storm/dev/config/OllamaConfig.java
create mode 100644 ai-rag-app/src/main/java/com/storm/dev/config/RedisClientConfig.java
create mode 100644 ai-rag-app/src/main/java/com/storm/dev/config/RedisClientConfigProperties.java
create mode 100644 ai-rag-app/src/main/java/com/storm/dev/package-info.java
create mode 100644 ai-rag-app/src/main/resources/application-dev.yml
create mode 100644 ai-rag-app/src/main/resources/application-prod.yml
create mode 100644 ai-rag-app/src/main/resources/application-test.yml
create mode 100644 ai-rag-app/src/main/resources/application.yml
create mode 100644 ai-rag-app/src/main/resources/logback-spring.xml
create mode 100644 ai-rag-trigger/src/main/java/com/storm/dev/trigger/http/OllamaController.java
create mode 100644 ai-rag-trigger/src/main/java/com/storm/dev/trigger/package-info.java
diff --git a/.idea/uiDesigner.xml b/.idea/uiDesigner.xml
new file mode 100644
index 0000000..2b63946
--- /dev/null
+++ b/.idea/uiDesigner.xml
@@ -0,0 +1,124 @@
+
+
+
+
+ -
+
+
+ -
+
+
+ -
+
+
+ -
+
+
+ -
+
+
+
+
+
+ -
+
+
+
+
+
+ -
+
+
+
+
+
+ -
+
+
+
+
+
+ -
+
+
+
+
+ -
+
+
+
+
+ -
+
+
+
+
+ -
+
+
+
+
+ -
+
+
+
+
+ -
+
+
+
+
+ -
+
+
+ -
+
+
+
+
+ -
+
+
+
+
+ -
+
+
+
+
+ -
+
+
+
+
+ -
+
+
+
+
+ -
+
+
+ -
+
+
+ -
+
+
+ -
+
+
+ -
+
+
+
+
+ -
+
+
+ -
+
+
+
+
+
\ No newline at end of file
diff --git a/ai-rag-api/src/main/java/com/storm/dev/api/IAiService.java b/ai-rag-api/src/main/java/com/storm/dev/api/IAiService.java
new file mode 100644
index 0000000..021606b
--- /dev/null
+++ b/ai-rag-api/src/main/java/com/storm/dev/api/IAiService.java
@@ -0,0 +1,26 @@
+package com.storm.dev.api;
+
+import org.springframework.ai.chat.ChatResponse;
+import reactor.core.publisher.Flux;
+
+/**
+ * @author: lyd
+ * @date: 2025/6/7 22:12
+ */
+public interface IAiService {
+ /**
+ * 非流式生成
+ * @param model 模型
+ * @param message 信息
+ * @return
+ */
+ ChatResponse generate(String model, String message);
+
+ /**
+ * 流式生成
+ * @param model 模型
+ * @param message 信息
+ * @return
+ */
+ Flux generateStream(String model, String message);
+}
diff --git a/ai-rag-api/src/main/java/package-info.java b/ai-rag-api/src/main/java/com/storm/dev/api/package-info.java
similarity index 60%
rename from ai-rag-api/src/main/java/package-info.java
rename to ai-rag-api/src/main/java/com/storm/dev/api/package-info.java
index dd64099..942087a 100644
--- a/ai-rag-api/src/main/java/package-info.java
+++ b/ai-rag-api/src/main/java/com/storm/dev/api/package-info.java
@@ -1,4 +1,5 @@
/**
* @author: lyd
* @date: 2025/6/7 19:12
- */
\ No newline at end of file
+ */
+package com.storm.dev.api;
\ No newline at end of file
diff --git a/ai-rag-app/pom.xml b/ai-rag-app/pom.xml
index 5f10ecf..62aa8b5 100644
--- a/ai-rag-app/pom.xml
+++ b/ai-rag-app/pom.xml
@@ -24,21 +24,23 @@
test
-
- org.springframework.ai
- spring-ai-openai-spring-boot-starter
-
+
+
+
+
-
- org.springframework.ai
- spring-ai-tika-document-reader
-
+
+
+
+
-
- org.springframework.ai
- spring-ai-pgvector-store-spring-boot-starter
-
+
+
+
+
+
+
org.springframework.ai
spring-ai-ollama
@@ -122,7 +124,7 @@
org.springframework.boot
spring-boot-maven-plugin
-
+ com.storm.dev.Application
JAR
diff --git a/ai-rag-app/src/main/java/com/storm/dev/Application.java b/ai-rag-app/src/main/java/com/storm/dev/Application.java
new file mode 100644
index 0000000..55c3069
--- /dev/null
+++ b/ai-rag-app/src/main/java/com/storm/dev/Application.java
@@ -0,0 +1,18 @@
+package com.storm.dev;
+
+import org.springframework.beans.factory.annotation.Configurable;
+import org.springframework.boot.SpringApplication;
+import org.springframework.boot.autoconfigure.SpringBootApplication;
+
+/**
+ * 会扫描com.storm.dev的包
+ */
+@SpringBootApplication
+@Configurable
+public class Application {
+
+ public static void main(String[] args) {
+ SpringApplication.run(Application.class);
+ }
+
+}
diff --git a/ai-rag-app/src/main/java/com/storm/dev/config/OllamaConfig.java b/ai-rag-app/src/main/java/com/storm/dev/config/OllamaConfig.java
new file mode 100644
index 0000000..53299a2
--- /dev/null
+++ b/ai-rag-app/src/main/java/com/storm/dev/config/OllamaConfig.java
@@ -0,0 +1,27 @@
+package com.storm.dev.config;
+
+import org.springframework.ai.ollama.OllamaChatClient;
+import org.springframework.ai.ollama.api.OllamaApi;
+import org.springframework.beans.factory.annotation.Value;
+import org.springframework.context.annotation.Bean;
+import org.springframework.context.annotation.Configuration;
+
+/**
+ * 注入OllamaApi、OllamaChatClient对象
+ * @author: lyd
+ * @date: 2025/6/7 22:28
+ */
+@Configuration
+public class OllamaConfig {
+
+ @Bean
+ public OllamaApi ollamaApi(@Value("${spring.ai.ollama.base-url}") String baseUrl) {
+ return new OllamaApi(baseUrl);
+ }
+
+ @Bean
+ public OllamaChatClient ollamaChatClient(OllamaApi ollamaApi) {
+ return new OllamaChatClient(ollamaApi);
+ }
+
+}
\ No newline at end of file
diff --git a/ai-rag-app/src/main/java/com/storm/dev/config/RedisClientConfig.java b/ai-rag-app/src/main/java/com/storm/dev/config/RedisClientConfig.java
new file mode 100644
index 0000000..0d57fef
--- /dev/null
+++ b/ai-rag-app/src/main/java/com/storm/dev/config/RedisClientConfig.java
@@ -0,0 +1,42 @@
+package com.storm.dev.config;
+
+import org.redisson.Redisson;
+import org.redisson.api.RedissonClient;
+import org.redisson.codec.JsonJacksonCodec;
+import org.redisson.config.Config;
+import org.springframework.boot.context.properties.EnableConfigurationProperties;
+import org.springframework.context.ConfigurableApplicationContext;
+import org.springframework.context.annotation.Bean;
+import org.springframework.context.annotation.Configuration;
+
+/**
+ * Redis 客户端,使用 Redisson Redisson
+ *
+ */
+@Configuration
+@EnableConfigurationProperties(RedisClientConfigProperties.class)
+public class RedisClientConfig {
+
+ @Bean("redissonClient")
+ public RedissonClient redissonClient(ConfigurableApplicationContext applicationContext, RedisClientConfigProperties properties) {
+ Config config = new Config();
+ // 根据需要可以设定编解码器;https://github.com/redisson/redisson/wiki/4.-%E6%95%B0%E6%8D%AE%E5%BA%8F%E5%88%97%E5%8C%96
+ config.setCodec(JsonJacksonCodec.INSTANCE);
+
+ config.useSingleServer()
+ .setAddress("redis://" + properties.getHost() + ":" + properties.getPort())
+// .setPassword(properties.getPassword())
+ .setConnectionPoolSize(properties.getPoolSize())
+ .setConnectionMinimumIdleSize(properties.getMinIdleSize())
+ .setIdleConnectionTimeout(properties.getIdleTimeout())
+ .setConnectTimeout(properties.getConnectTimeout())
+ .setRetryAttempts(properties.getRetryAttempts())
+ .setRetryInterval(properties.getRetryInterval())
+ .setPingConnectionInterval(properties.getPingInterval())
+ .setKeepAlive(properties.isKeepAlive())
+ ;
+
+ return Redisson.create(config);
+ }
+
+}
diff --git a/ai-rag-app/src/main/java/com/storm/dev/config/RedisClientConfigProperties.java b/ai-rag-app/src/main/java/com/storm/dev/config/RedisClientConfigProperties.java
new file mode 100644
index 0000000..0dde870
--- /dev/null
+++ b/ai-rag-app/src/main/java/com/storm/dev/config/RedisClientConfigProperties.java
@@ -0,0 +1,37 @@
+package com.storm.dev.config;
+
+import lombok.Data;
+import org.springframework.boot.context.properties.ConfigurationProperties;
+
+/**
+ * @author Fuzhengwei bugstack.cn @小傅哥
+ * Redis 连接配置 redisson-spring-boot-starter
+ */
+@Data
+@ConfigurationProperties(prefix = "redis.sdk.config", ignoreInvalidFields = true)
+public class RedisClientConfigProperties {
+
+ /** host:ip */
+ private String host;
+ /** 端口 */
+ private int port;
+ /** 账密 */
+ private String password;
+ /** 设置连接池的大小,默认为64 */
+ private int poolSize = 64;
+ /** 设置连接池的最小空闲连接数,默认为10 */
+ private int minIdleSize = 10;
+ /** 设置连接的最大空闲时间(单位:毫秒),超过该时间的空闲连接将被关闭,默认为10000 */
+ private int idleTimeout = 10000;
+ /** 设置连接超时时间(单位:毫秒),默认为10000 */
+ private int connectTimeout = 10000;
+ /** 设置连接重试次数,默认为3 */
+ private int retryAttempts = 3;
+ /** 设置连接重试的间隔时间(单位:毫秒),默认为1000 */
+ private int retryInterval = 1000;
+ /** 设置定期检查连接是否可用的时间间隔(单位:毫秒),默认为0,表示不进行定期检查 */
+ private int pingInterval = 0;
+ /** 设置是否保持长连接,默认为true */
+ private boolean keepAlive = true;
+
+}
diff --git a/ai-rag-app/src/main/java/com/storm/dev/package-info.java b/ai-rag-app/src/main/java/com/storm/dev/package-info.java
new file mode 100644
index 0000000..ed0404c
--- /dev/null
+++ b/ai-rag-app/src/main/java/com/storm/dev/package-info.java
@@ -0,0 +1,6 @@
+/**
+ * 启动模块
+ * @author: lyd
+ * @date: 2025/6/7 22:04
+ */
+package com.storm.dev;
\ No newline at end of file
diff --git a/ai-rag-app/src/main/resources/application-dev.yml b/ai-rag-app/src/main/resources/application-dev.yml
new file mode 100644
index 0000000..cc8f7f5
--- /dev/null
+++ b/ai-rag-app/src/main/resources/application-dev.yml
@@ -0,0 +1,27 @@
+server:
+ port: 8090
+
+spring:
+ ai:
+ ollama:
+ base-url: http://117.72.202.142:11434
+
+# Redis
+redis:
+ sdk:
+ config:
+ host: 117.72.202.142
+ port: 16379
+ pool-size: 10
+ min-idle-size: 5
+ idle-timeout: 30000
+ connect-timeout: 5000
+ retry-attempts: 3
+ retry-interval: 1000
+ ping-interval: 60000
+ keep-alive: true
+
+logging:
+ level:
+ root: info
+ config: classpath:logback-spring.xml
diff --git a/ai-rag-app/src/main/resources/application-prod.yml b/ai-rag-app/src/main/resources/application-prod.yml
new file mode 100644
index 0000000..7d19cad
--- /dev/null
+++ b/ai-rag-app/src/main/resources/application-prod.yml
@@ -0,0 +1,7 @@
+server:
+ port: 8090
+
+logging:
+ level:
+ root: info
+ config: classpath:logback-spring.xml
diff --git a/ai-rag-app/src/main/resources/application-test.yml b/ai-rag-app/src/main/resources/application-test.yml
new file mode 100644
index 0000000..7d19cad
--- /dev/null
+++ b/ai-rag-app/src/main/resources/application-test.yml
@@ -0,0 +1,7 @@
+server:
+ port: 8090
+
+logging:
+ level:
+ root: info
+ config: classpath:logback-spring.xml
diff --git a/ai-rag-app/src/main/resources/application.yml b/ai-rag-app/src/main/resources/application.yml
new file mode 100644
index 0000000..f5dfac6
--- /dev/null
+++ b/ai-rag-app/src/main/resources/application.yml
@@ -0,0 +1,5 @@
+spring:
+ application:
+ name: ai-rag-knowledge
+ profiles:
+ active: dev
diff --git a/ai-rag-app/src/main/resources/logback-spring.xml b/ai-rag-app/src/main/resources/logback-spring.xml
new file mode 100644
index 0000000..f71e2ea
--- /dev/null
+++ b/ai-rag-app/src/main/resources/logback-spring.xml
@@ -0,0 +1,113 @@
+
+
+
+
+ logback
+
+
+
+
+
+
+
+
+
+
+
+ info
+
+
+ %d{yy-MM-dd.HH:mm:ss.SSS} [%-16t] %-5p %-22c{0}%X{ServiceId} -%X{trace-id} %m%n
+ UTF-8
+
+
+
+
+
+
+
+ ./data/log/log_info.log
+
+
+ %d{yy-MM-dd.HH:mm:ss.SSS} [%-16t] %-5p %-22c{0}%X{ServiceId} -%X{trace-id} %m%n
+ UTF-8
+
+
+
+
+ ./data/log/log-info-%d{yyyy-MM-dd}.%i.log
+
+ 100MB
+
+
+ 15
+ 10GB
+
+
+
+
+
+
+ ./data/log/log_error.log
+
+
+ %d{yy-MM-dd.HH:mm:ss.SSS} [%-16t] %-5p %-22c{0}%X{ServiceId} -%X{trace-id} %m%n
+ UTF-8
+
+
+
+ ./data/log/log-error-%d{yyyy-MM-dd}.%i.log
+
+ 100MB
+
+
+ 7
+ 5GB
+
+
+
+ WARN
+
+
+
+
+
+
+ 0
+
+ 8192
+
+ true
+
+ false
+
+
+
+
+
+ 0
+
+ 1024
+
+ true
+
+ false
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/ai-rag-trigger/pom.xml b/ai-rag-trigger/pom.xml
index 3abc8f7..2dc9d7f 100644
--- a/ai-rag-trigger/pom.xml
+++ b/ai-rag-trigger/pom.xml
@@ -23,18 +23,18 @@
spring-boot-starter-web
-
- org.springframework.ai
- spring-ai-openai-spring-boot-starter
-
-
- org.springframework.ai
- spring-ai-tika-document-reader
-
-
- org.springframework.ai
- spring-ai-pgvector-store
-
+
+
+
+
+
+
+
+
+
+
+
+
org.springframework.ai
spring-ai-ollama
diff --git a/ai-rag-trigger/src/main/java/com/storm/dev/trigger/http/OllamaController.java b/ai-rag-trigger/src/main/java/com/storm/dev/trigger/http/OllamaController.java
new file mode 100644
index 0000000..b6a34c2
--- /dev/null
+++ b/ai-rag-trigger/src/main/java/com/storm/dev/trigger/http/OllamaController.java
@@ -0,0 +1,41 @@
+package com.storm.dev.trigger.http;
+
+import com.storm.dev.api.IAiService;
+import jakarta.annotation.Resource;
+import org.springframework.ai.chat.ChatResponse;
+import org.springframework.ai.chat.prompt.Prompt;
+import org.springframework.ai.ollama.OllamaChatClient;
+import org.springframework.ai.ollama.api.OllamaOptions;
+import org.springframework.web.bind.annotation.*;
+import reactor.core.publisher.Flux;
+
+/**
+ * @author: lyd
+ * @date: 2025/6/7 22:18
+ */
+@RestController()
+@CrossOrigin("*")
+@RequestMapping("/api/v1/ollama/")
+public class OllamaController implements IAiService {
+
+ @Resource
+ private OllamaChatClient chatClient;
+
+ /**
+ * http://localhost:8090/api/v1/ollama/generate?model=deepseek-r1:1.5b&message=1+1
+ */
+ @GetMapping("generate")
+ @Override
+ public ChatResponse generate(@RequestParam String model, @RequestParam String message) {
+ return chatClient.call(new Prompt(message, OllamaOptions.create().withModel(model)));
+ }
+
+ /**
+ * http://localhost:8090/api/v1/ollama/generate_stream?model=deepseek-r1:1.5b&message=hi
+ */
+ @GetMapping("generate_stream")
+ @Override
+ public Flux generateStream(@RequestParam String model, @RequestParam String message) {
+ return chatClient.stream(new Prompt(message, OllamaOptions.create().withModel(model)));
+ }
+}
diff --git a/ai-rag-trigger/src/main/java/com/storm/dev/trigger/package-info.java b/ai-rag-trigger/src/main/java/com/storm/dev/trigger/package-info.java
new file mode 100644
index 0000000..d89b4a9
--- /dev/null
+++ b/ai-rag-trigger/src/main/java/com/storm/dev/trigger/package-info.java
@@ -0,0 +1,6 @@
+/**
+ * 触发器
+ * @author: lyd
+ * @date: 2025/6/7 22:17
+ */
+package com.storm.dev.trigger;
\ No newline at end of file