diff --git a/pom.xml b/pom.xml
index 680bc9f..2ae0931 100644
--- a/pom.xml
+++ b/pom.xml
@@ -77,12 +77,25 @@
-
+
- com.mysql
- mysql-connector-j
+ org.postgresql
+ postgresql
runtime
+
+
+ org.springframework.ai
+ spring-ai-starter-vector-store-pgvector
+ 1.1.2
+
+
+
+
+ org.springframework.ai
+ spring-ai-advisors-vector-store
+ 1.1.2
+
\ No newline at end of file
diff --git a/src/main/java/com/baoshi/conf/AiConfig.java b/src/main/java/com/baoshi/conf/AiConfig.java
index 3238b91..ca21dab 100644
--- a/src/main/java/com/baoshi/conf/AiConfig.java
+++ b/src/main/java/com/baoshi/conf/AiConfig.java
@@ -1,14 +1,19 @@
package com.baoshi.conf;
import com.alibaba.cloud.ai.dashscope.chat.DashScopeChatModel;
+import com.alibaba.cloud.ai.dashscope.spec.DashScopeModel;
import org.springframework.ai.chat.client.ChatClient;
import org.springframework.ai.chat.client.advisor.PromptChatMemoryAdvisor;
import org.springframework.ai.chat.memory.ChatMemory;
import org.springframework.ai.chat.memory.MessageWindowChatMemory;
import org.springframework.ai.chat.memory.repository.jdbc.JdbcChatMemoryRepository;
+import org.springframework.ai.embedding.EmbeddingModel;
import org.springframework.ai.model.ollama.autoconfigure.OllamaChatProperties;
import org.springframework.ai.ollama.OllamaChatModel;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
+import org.springframework.context.annotation.Primary;
@Configuration
public class AiConfig {
@@ -16,7 +21,7 @@ public class AiConfig {
@Bean
public ChatMemory chatMemory(JdbcChatMemoryRepository chatMemoryRepository) {
return MessageWindowChatMemory.builder()
- .maxMessages(1)
+ .maxMessages(3)
.chatMemoryRepository(chatMemoryRepository)
.build();
}
@@ -37,4 +42,10 @@ public class AiConfig {
.defaultAdvisors(PromptChatMemoryAdvisor.builder(chatMemory).build())
.build();
}
+
+ @Primary
+ @Bean
+ public EmbeddingModel embeddingModel(@Autowired @Qualifier("ollamaEmbeddingModel") EmbeddingModel embeddingModel) {
+ return embeddingModel;
+ }
}
diff --git a/src/main/resources/application.yml b/src/main/resources/application.yml
index e4814f5..0fca9e6 100644
--- a/src/main/resources/application.yml
+++ b/src/main/resources/application.yml
@@ -5,6 +5,8 @@ spring:
base-url: http://100.121.13.117:11434
chat:
model: qwen2.5:7b
+ embedding:
+ model: bge-m3
dashscope:
api-key: sk-36a57382b9ae4db696ecd07eb7150a88
chat:
@@ -14,11 +16,18 @@ spring:
repository:
jdbc:
initialize-schema: always
+ vectorstore:
+ pgvector:
+ initialize-schema: true
+ index-type: HNSW
+ distance-type: COSINE_DISTANCE
datasource:
- username: root
- password: 123456
- url: jdbc:mysql://localhost:3306/springai?characterEncoding=utf8&useSSL=false&serverTimezone=UTC&
- driver-class-name: com.mysql.cj.jdbc.Driver
+ username: postgres
+ password: postgres
+ url: jdbc:postgresql://localhost:5432/springai
+ driver-class-name: org.postgresql.Driver
+
+
server:
port: 8080
diff --git a/src/test/java/com/baoshi/JDBCMemoryTest.java b/src/test/java/com/baoshi/JDBCMemoryTest.java
index c7f05fb..62e5c68 100644
--- a/src/test/java/com/baoshi/JDBCMemoryTest.java
+++ b/src/test/java/com/baoshi/JDBCMemoryTest.java
@@ -6,6 +6,7 @@ import org.springframework.ai.chat.client.ChatClient;
import org.springframework.ai.chat.memory.ChatMemory;
import org.springframework.ai.chat.memory.repository.jdbc.JdbcChatMemoryRepository;
import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.jdbc.core.JdbcTemplate;
@@ -23,14 +24,12 @@ class JDBCMemoryTest {
private static final String CONVERSATION_ID = "1";
@Autowired
- private ChatClient ollama;
+ @Qualifier("ollama")
+ private ChatClient chatClient;
@Autowired
private ChatMemory chatMemory;
- @Autowired
- private JdbcChatMemoryRepository chatMemoryRepository;
-
@Autowired
private JdbcTemplate jdbcTemplate;
@@ -41,20 +40,23 @@ class JDBCMemoryTest {
@Test
void shouldPersistMessagesIntoJdbcRepositoryByChatModelConversation() {
- ollama.prompt()
+ chatClient.prompt()
.advisors(advisor -> advisor.param(ChatMemory.CONVERSATION_ID, CONVERSATION_ID))
.user("我叫邹志文")
.call()
.content();
-
- String secondResponse = ollama.prompt()
+ chatClient.prompt()
+ .advisors(advisor -> advisor.param(ChatMemory.CONVERSATION_ID, CONVERSATION_ID))
+ .user("她叫冬马和纱")
+ .call()
+ .content();
+ String secondResponse = chatClient.prompt()
.advisors(advisor -> advisor.param(ChatMemory.CONVERSATION_ID, CONVERSATION_ID))
.user("我叫什么")
.call()
.content();
- assertThat(secondResponse).isNotBlank();
- assertThat(chatMemoryRepository.findByConversationId(CONVERSATION_ID)).isNotEmpty();
+ System.out.println(secondResponse);
Integer rowCount = jdbcTemplate.queryForObject(
"SELECT COUNT(*) FROM SPRING_AI_CHAT_MEMORY WHERE conversation_id = ?",
Integer.class,
diff --git a/src/test/java/com/baoshi/SimpleVectorStoreTest.java b/src/test/java/com/baoshi/SimpleVectorStoreTest.java
new file mode 100644
index 0000000..05c3ebf
--- /dev/null
+++ b/src/test/java/com/baoshi/SimpleVectorStoreTest.java
@@ -0,0 +1,76 @@
+package com.baoshi;
+
+import com.alibaba.cloud.ai.dashscope.chat.DashScopeChatModel;
+import org.junit.jupiter.api.BeforeEach;
+import org.junit.jupiter.api.Test;
+import org.springframework.ai.chat.client.ChatClient;
+import org.springframework.ai.chat.client.advisor.SimpleLoggerAdvisor;
+import org.springframework.ai.chat.client.advisor.vectorstore.QuestionAnswerAdvisor;
+import org.springframework.ai.document.Document;
+import org.springframework.ai.vectorstore.SearchRequest;
+import org.springframework.ai.vectorstore.VectorStore;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.beans.factory.annotation.Qualifier;
+import org.springframework.boot.test.context.SpringBootTest;
+
+import java.util.Arrays;
+
+@SpringBootTest
+public class SimpleVectorStoreTest {
+
+ @BeforeEach
+ public void init( @Autowired
+ VectorStore vectorStore) {
+ // 1. 声明内容文档
+ Document doc = Document.builder()
+ .text("""
+ 预订航班:
+ - 通过我们的网站或移动应用程序预订。
+ - 预订时需要全额付款。
+ - 确保个人信息(姓名、ID 等)的准确性,因为更正可能会产生 25 的费用。
+ """)
+ .build();
+ Document doc2 = Document.builder()
+ .text("""
+ 取消预订:
+ - 最晚在航班起飞前 48 小时取消。
+ - 取消费用:经济舱 75 美元,豪华经济舱 50 美元,商务舱 25 美元。
+ - 退款将在 7 个工作日内处理。
+ """)
+ .build();
+
+
+ // 2. 将文本进行向量化,并且存入向量数据库(无需再手动向量化)
+ vectorStore.add(Arrays.asList(doc,doc2));
+ }
+
+
+ @Test
+ void chatRagTest(
+ @Autowired
+ VectorStore vectorStore,
+ @Autowired
+ @Qualifier("ollama")
+ ChatClient chatClient
+ ) {
+
+
+ String message="退费需要多少费用?";
+ String content = chatClient.prompt().user(message)
+ .advisors(
+ new SimpleLoggerAdvisor(),
+ QuestionAnswerAdvisor.builder(vectorStore)
+ .searchRequest(
+ SearchRequest
+ .builder().query(message)
+ .topK(5)
+ .similarityThreshold(0.3)
+ .build())
+ .build()
+ ).call().content();
+
+ System.out.println(content);
+
+ }
+
+}
\ No newline at end of file