feat: RAG
This commit is contained in:
parent
f5b0e16c94
commit
bf47df6ac6
19
pom.xml
19
pom.xml
|
|
@ -77,12 +77,25 @@
|
|||
</dependency>
|
||||
|
||||
|
||||
<!--mysql驱动-->
|
||||
<!-- PostgreSQL:聊天记忆 JDBC + pgvector 共用同一数据源 -->
|
||||
<dependency>
|
||||
<groupId>com.mysql</groupId>
|
||||
<artifactId>mysql-connector-j</artifactId>
|
||||
<groupId>org.postgresql</groupId>
|
||||
<artifactId>postgresql</artifactId>
|
||||
<scope>runtime</scope>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>org.springframework.ai</groupId>
|
||||
<artifactId>spring-ai-starter-vector-store-pgvector</artifactId>
|
||||
<version>1.1.2</version>
|
||||
</dependency>
|
||||
|
||||
<!-- 向量数据库 -->
|
||||
<dependency>
|
||||
<groupId>org.springframework.ai</groupId>
|
||||
<artifactId>spring-ai-advisors-vector-store</artifactId>
|
||||
<version>1.1.2</version>
|
||||
</dependency>
|
||||
</dependencies>
|
||||
|
||||
</project>
|
||||
|
|
@ -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;
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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,
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
Loading…
Reference in New Issue