VectorStoreChatMemoryAdvisor 向量存储聊天历史

VectorStoreChatMemoryAdvisor 类是一个基于向量存储(VectorStore)的聊天记忆管理组件,通过将历史对话消息转换为向量并存储,实现在对话系统中上下文感知的对话记忆功能。

当用户发起请求时,VectorStoreChatMemoryAdvisor 会基于会话 ID(Conversation ID)直接关联并返回历史消息,而没有进行向量语义检索(即没有通过嵌入向量相似性搜索来获取相关上下文)。

VectorStoreChatMemoryAdvisor 类的主要功能如下:

  • 上下文记忆:存储用户与AI的对话历史,并且将消息向量化,存储到向量数据库。

  • 动态上下文注入:自动将检索到的历史对话添加到新请求的上下文中,作为系统提示词进行添加。

注意:再次强调,VectorStoreChatMemoryAdvisor 没有提供向量语义检索,看源码:

VectorStoreChatMemoryAdvisor 向量存储聊天历史

上图中,直接通过 conversationId 进行过滤,未有语义相关代码。

VectorStoreChatMemoryAdvisor 向量存储聊天历史

  

构造方法

和其他 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

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,它是一个轻量级内存向量存储实现,适合开发测试和小规模生产环境使用。主要特点:

  • 基于内存的快速存取,无需额外基础设施

  • 开箱即用,无需复杂配置

  • 非常适合快速原型开发和测试场景

  • 支持添加、删除和相似性搜索

  • 支持将存储内容序列化到磁盘

创建 YML 配置文件

在 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

创建 AI 配置类

继续创建一个名为 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(); // 默认配置
    }

}

创建 Controller

创建一个名为 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 地址,提问“我是张三,毕业于四川大学”,效果如下图:

VectorStoreChatMemoryAdvisor 向量存储聊天历史

此时后端日志信息如下:

VectorStoreChatMemoryAdvisor 向量存储聊天历史

上图中,“LONG_TERM_MEMORY”部分内容为空。

接着,继续提问“张三”,效果如下图:

VectorStoreChatMemoryAdvisor 向量存储聊天历史

继续查看后端输出日志:

VectorStoreChatMemoryAdvisor 向量存储聊天历史

此时,“LONG_TERM_MEMORY”部分有数据了,是前面我们提问/回复的数据。

如果继续问一个与“张三”完全没有关系的话题,看看 AI 的回复,如下图:

VectorStoreChatMemoryAdvisor 向量存储聊天历史

看看日志呢:

VectorStoreChatMemoryAdvisor 向量存储聊天历史

通过日志可以看出,“LONG_TERM_MEMORY”部分的内容是本次会话的历史数据,并不是语义相关的数据。

  

说说我的看法
全部评论(
没有评论
关于
本网站专注于 Java、数据库(MySQL、Oracle)、Linux、软件架构及大数据等多领域技术知识分享。涵盖丰富的原创与精选技术文章,助力技术传播与交流。无论是技术新手渴望入门,还是资深开发者寻求进阶,这里都能为您提供深度见解与实用经验,让复杂编码变得轻松易懂,携手共赴技术提升新高度。如有侵权,请来信告知:hxstrive@outlook.com
其他应用
公众号