VectorStoreChatMemoryAdvisor 类是一个基于向量存储(VectorStore)的聊天记忆管理组件,通过将历史对话消息转换为向量并存储,实现在对话系统中上下文感知的对话记忆功能。
当用户发起请求时,VectorStoreChatMemoryAdvisor 会基于会话 ID(Conversation ID)直接关联并返回历史消息,而没有进行向量语义检索(即没有通过嵌入向量相似性搜索来获取相关上下文)。
VectorStoreChatMemoryAdvisor 类的主要功能如下:
上下文记忆:存储用户与AI的对话历史,并且将消息向量化,存储到向量数据库。
动态上下文注入:自动将检索到的历史对话添加到新请求的上下文中,作为系统提示词进行添加。
注意:再次强调,VectorStoreChatMemoryAdvisor 没有提供向量语义检索,看源码:
上图中,直接通过 conversationId 进行过滤,未有语义相关代码。
和其他 Advisor 一样,VectorStoreChatMemoryAdvisor 的构造方法是私有的,如下:
private VectorStoreChatMemoryAdvisor(PromptTemplate systemPromptTemplate, int defaultTopK, String defaultConversationId, int order, Scheduler scheduler, VectorStore vectorStore) { Assert.notNull(systemPromptTemplate, "systemPromptTemplate cannot be null"); Assert.isTrue(defaultTopK > 0, "topK must be greater than 0"); Assert.hasText(defaultConversationId, "defaultConversationId cannot be null or empty"); Assert.notNull(scheduler, "scheduler cannot be null"); Assert.notNull(vectorStore, "vectorStore cannot be null"); this.systemPromptTemplate = systemPromptTemplate; this.defaultTopK = defaultTopK; this.defaultConversationId = defaultConversationId; this.order = order; this.scheduler = scheduler; this.vectorStore = vectorStore; }
必须通过静态方法 builder(VectorStore chatMemory) 进行构建,该方法接收一个 VectorStore,VectorStore(向量存储)是 Spring AI 中用于高效存储和检索向量嵌入数据的核心组件,专为 AI 应用中的语义搜索和相似性匹配场景设计。
builder(VectorStore chatMemory) 方法返回类型是静态内部类 Builder,Builder 用来通过链式调用方式构建 VectorStoreChatMemoryAdvisor 实例,构建方法如下:
VectorStoreChatMemoryAdvisor vector= VectorStoreChatMemoryAdvisor.builder(vectorStore(embeddingModel)) .systemPromptTemplate(new PromptTemplate("请使用中文回复")) // 系统提示词 .conversationId("sessionId-20250706065015") // 消息ID .order(0) // 排序 .defaultTopK(10) // TopK .build();
VectorStoreChatMemoryAdvisor.Builder 是 Spring AI 1.0.0 中用于构建基于向量存储的对话记忆顾问(VectorStoreChatMemoryAdvisor)的核心构建器,提供链式调用方式。
以下是该构建器提供的属性:
public static class Builder { private PromptTemplate systemPromptTemplate; private Integer defaultTopK; private String conversationId; private Scheduler scheduler; private int order; private VectorStore vectorStore; protected Builder(VectorStore vectorStore) { this.systemPromptTemplate = VectorStoreChatMemoryAdvisor.DEFAULT_SYSTEM_PROMPT_TEMPLATE; this.defaultTopK = 20; this.conversationId = "default"; this.scheduler = BaseAdvisor.DEFAULT_SCHEDULER; this.order = -2147482648; this.vectorStore = vectorStore; } //... }
属性说明:
systemPromptTemplate 系统提示词模板,用于控制系统提示词的生成,可嵌入对话历史和当前上下文。默认提示词如下:
private static final PromptTemplate DEFAULT_SYSTEM_PROMPT_TEMPLATE = new PromptTemplate("{instructions}\n\nUse the long term conversation memory from the LONG_TERM_MEMORY section to provide accurate answers.\n\n---------------------\nLONG_TERM_MEMORY:\n{long_term_memory}\n---------------------\n");
将提示词中的 \n 转换为换行,如下:
{instructions} Use the long term conversation memory from the LONG_TERM_MEMORY section to provide accurate answers. --------------------- LONG_TERM_MEMORY: {long_term_memory} ---------------------
defaultTopK 控制默认返回的最相关记忆片段数量,向量相似度搜索的结果规模。即从向量数据库召回语义相似的片段数量。默认为 20 个片段。
conversationId 会话唯一 ID
scheduler 控制记忆操作的执行线程和调度策略,异步记忆操作、后台记忆清理、高并发场景优化。常用调度器:
Schedulers.immediate() 立即在当前线程执行(默认)
Schedulers.boundedElastic() 弹性线程池,适合阻塞操作
Schedulers.parallel() 固定大小线程池,适合计算密集型
Schedulers.single() 单线程执行
order 决定 Advisor 在调用链中的执行顺序,值越小优先级越高,越先执行。
vectorStore 提供向量存储和检索能力,Spring AI 提供了很多模块实现向量存储,如下:
spring-ai-starter-vector-store-aws-opensearch:快速集成 AWS OpenSearch 向量搜索。
spring-ai-starter-vector-store-azure:快速集成 Azure 向量存储服务。
spring-ai-starter-vector-store-azure-cosmos-db:快速集成 Azure Cosmos DB 向量存储。
spring-ai-starter-vector-store-cassandra:快速集成 Apache Cassandra 向量存储。
spring-ai-starter-vector-store-chroma:快速集成 ChromaDB 向量存储。
spring-ai-starter-vector-store-couchbase:快速集成 Couchbase 向量存储。
spring-ai-starter-vector-store-elasticsearch:快速集成 Elasticsearch 向量搜索。
spring-ai-starter-vector-store-gemfire:快速集成 GemFire 向量存储。
spring-ai-starter-vector-store-mariadb:快速集成 MariaDB 向量扩展。
spring-ai-starter-vector-store-milvus:快速集成 Milvus 向量数据库。
spring-ai-starter-vector-store-mongodb-atlas:快速集成 MongoDB Atlas 向量搜索。
spring-ai-starter-vector-store-neo4j:快速集成 Neo4j 向量能力。
spring-ai-starter-vector-store-opensearch:快速集成 OpenSearch 向量搜索。
spring-ai-starter-vector-store-oracle:快速集成 Oracle 向量存储。
spring-ai-starter-vector-store-pgvector:快速集成 PostgreSQL 的 pgvector 扩展。
spring-ai-starter-vector-store-pinecone:快速集成 Pinecone 云向量服务。
spring-ai-starter-vector-store-qdrant:快速集成 Qdrant 向量搜索引擎。
spring-ai-starter-vector-store-redis:快速集成 Redis 向量存储。
spring-ai-starter-vector-store-typesense:快速集成 Typesense 向量搜索。
spring-ai-starter-vector-store-weaviate:快速集成 Weaviate 向量搜索引擎。
后续示例我们将基于 Redis 进行演示。
下面为了演示,将采用 Spring AI 提供的 SimpleVectorStore,它是一个轻量级内存向量存储实现,适合开发测试和小规模生产环境使用。主要特点:
基于内存的快速存取,无需额外基础设施
开箱即用,无需复杂配置
非常适合快速原型开发和测试场景
支持添加、删除和相似性搜索
支持将存储内容序列化到磁盘
在 resources 下面创建 application.yml 配置文件,添加大模型相关配置信息,如下:
spring: application: name: springai_demo1 # AI配置 ai: # openai相关配置 openai: # 基础地址 base-url: https://api.xty.app # AI KEY api-key: sk-vHTHX8D3wNZBfRya831a**********e42BeB8A23e48AbB600 # 聊天模型配置 chat: options: model: gpt-3.5-turbo # 图片模型配置 image: options: # 需要高级接口 model: dall-e-3 chat: memory: # 会话历史持久化 repository: jdbc: # 启动时不自动执行初始化SQL脚本,手动创建数据表 initialize-schema: never client: # true 开启,自动注入 ChatClient,false 关闭,需要手动创建 ChatClient enabled: true # 日志配置 logging: charset: console: UTF-8 level: root: info org.springframework.ai: debug
继续创建一个名为 AiConfig 的配置类,创建 VectorStoreChatMemoryAdvisor 和 VectorStore,如下:
package com.hxstrive.springai.springai_openai.advisor_VectorStoreChatMemoryAdvisor.config; import org.springframework.ai.chat.client.advisor.SimpleLoggerAdvisor; import org.springframework.ai.chat.client.advisor.vectorstore.VectorStoreChatMemoryAdvisor; import org.springframework.ai.embedding.EmbeddingModel; import org.springframework.ai.vectorstore.SimpleVectorStore; import org.springframework.ai.vectorstore.VectorStore; import org.springframework.ai.vectorstore.redis.RedisVectorStore; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; import redis.clients.jedis.JedisPooled; /** * AI配置 * @author Administrator */ @Configuration public class AiConfig { @Bean public VectorStore vectorStore(JedisPooled jedis, EmbeddingModel embeddingModel) { return SimpleVectorStore.builder(embeddingModel).build(); } @Bean public VectorStoreChatMemoryAdvisor vectorStoreChatMemoryAdvisor(VectorStore vectorStore) { return VectorStoreChatMemoryAdvisor.builder(vectorStore) .defaultTopK(10) // TopK .build(); } @Bean public SimpleLoggerAdvisor simpleLoggerAdvisor() { return new SimpleLoggerAdvisor(); // 默认配置 } }
创建一个名为 AIController 的控制器,通过 @Autowired 注入 VectorStoreChatMemoryAdvisor,然后使用 ChatClient 的 defaultAdvisors() 添加 VectorStoreChatMemoryAdvisor。如下:
package com.hxstrive.springai.springai_openai.advisor_VectorStoreChatMemoryAdvisor.controller; import org.springframework.ai.chat.client.ChatClient; import org.springframework.ai.chat.client.advisor.SimpleLoggerAdvisor; import org.springframework.ai.chat.client.advisor.vectorstore.VectorStoreChatMemoryAdvisor; import org.springframework.ai.chat.memory.ChatMemory; import org.springframework.ai.chat.model.ChatModel; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.web.bind.annotation.GetMapping; import org.springframework.web.bind.annotation.RequestParam; import org.springframework.web.bind.annotation.RestController; @RestController public class AIController { @Autowired private ChatModel chatModel; @Autowired private VectorStoreChatMemoryAdvisor vectorStoreChatMemoryAdvisor; @Autowired private SimpleLoggerAdvisor simpleLoggerAdvisor; @GetMapping("/ai/simple") public String completion(@RequestParam("userText") String userText) { ChatClient chatClient = ChatClient.builder(chatModel) .defaultSystem("使用中文进行回复") .defaultAdvisors( simpleLoggerAdvisor, vectorStoreChatMemoryAdvisor // 使用 VectorStoreChatMemoryAdvisor ) .build(); // conversationId 区分不同对话,定位对应的历史记录 String conversationId = "sessionId-20250706153029"; return chatClient.prompt() // 运行时设置会话ID参数 .advisors(advisor -> { advisor.param(ChatMemory.CONVERSATION_ID, conversationId); }) .user(userText) .call() .content(); } }
启动应用程序,浏览器访问 http://localhost:8080/ai/simple 地址,提问“我是张三,毕业于四川大学”,效果如下图:
此时后端日志信息如下:
上图中,“LONG_TERM_MEMORY”部分内容为空。
接着,继续提问“张三”,效果如下图:
继续查看后端输出日志:
此时,“LONG_TERM_MEMORY”部分有数据了,是前面我们提问/回复的数据。
如果继续问一个与“张三”完全没有关系的话题,看看 AI 的回复,如下图:
看看日志呢:
通过日志可以看出,“LONG_TERM_MEMORY”部分的内容是本次会话的历史数据,并不是语义相关的数据。