Spring AI 对话记忆

对话记忆功能是一种技术,使得应用程序或智能助手能够在一段时间内“记住”用户提供的信息,以便在后续对话中参考和使用。这种记忆可以让对话更加连贯,并使助手能够理解用户的背景和偏好,从而提供更加个性化和精准的回复。

对话记忆功能的用途

  1. 用户信息的持久化:记录用户提供的背景信息或个人偏好。
  2. 上下文跟踪:在多轮对话中保持上下文一致性。
  3. 更好地回答追问:在复杂的多轮对话中,当用户询问更详细的问题或追问之前提到的内容时,记忆功能使助手能更好地理解用户的意图。

Spring AI 记忆功能

  1. ChatMemory
    ChatMemory作为一个内存管理容器,存储和管理多轮对话中的ChatMessage。它不仅允许开发者保存消息,还提供了消息驱逐策略(Eviction Policy)、持久化存储(Persistence)以及特殊消息处理(如SystemMessage和ToolExecutionMessage)等功能。此外,ChatMemory还与high-level组件(如AI服务)集成,便于开发者更方便地管理对话历史。
    在Spring AI中,ChatMemory接口定义了用于存储和检索聊天对话历史记录的方法。以下是ChatMemory接口的主要方法:

    1. add(String conversationId, Message message):将单个消息添加到指定会话的对话中。
    2. add(String conversationId, List<Message> messages):将消息列表添加到指定会话的对话中。
    3. get(String conversationId, int lastN):从指定会话的对话中检索最新的N条消息。
    4. clear(String conversationId):清除指定会话的对话历史记录。
public interface ChatMemory {
	// TODO: consider a non-blocking interface for streaming usages
	default void add(String conversationId, Message message) {
		this.add(conversationId, List.of(message));
	}
	void add(String conversationId, List<Message> messages);
	List<Message> get(String conversationId, int lastN);
	void clear(String conversationId);
}

2、内存记忆InMemoryChatMemory
InMemoryChatMemory是Spring AI框架提供的一种ChatMemory实现,它将对话历史记录存储在内存中。这种实现方式具有快速访问和检索消息的优点,适用于快速原型开发和测试场景。由于内存是易失性存储介质,因此InMemoryChatMemory不适用于需要长期保存聊天记录的应用场景。

代码:

public class InMemoryChatMemory implements ChatMemory {
	Map<String, List<Message>> conversationHistory = new ConcurrentHashMap<>();
	@Override
	public void add(String conversationId, List<Message> messages) {
		this.conversationHistory.putIfAbsent(conversationId, new ArrayList<>());
		this.conversationHistory.get(conversationId).addAll(messages);
	}
	@Override
	public List<Message> get(String conversationId, int lastN) {
		List<Message> all = this.conversationHistory.get(conversationId);
		return all != null ? all.stream().skip(Math.max(0, all.size() - lastN)).toList() : List.of();
	}
	@Override
	public void clear(String conversationId) {
		this.conversationHistory.remove(conversationId);
	}
}

样例:

import org.springframework.ai.chat.memory.ChatMemory;
import org.springframework.ai.chat.memory.InMemoryChatMemory;
import org.springframework.ai.chat.messages.Message;
import org.springframework.ai.chat.messages.UserMessage;
import java.util.List;

public class ChatMemoryExample {
    public static void main(String[] args) {
        // 创建InMemoryChatMemory实例
        ChatMemory chatMemory = new InMemoryChatMemory();

        // 创建用户消息
        Message userMessage1 = new UserMessage("Hello, how are you?");
        Message userMessage2 = new UserMessage("I'm fine, thank you. How about you?");

        // 将会话ID和消息添加到ChatMemory中
        String conversationId = "12345";
        chatMemory.add(conversationId, List.of(userMessage1));
        chatMemory.add(conversationId, List.of(userMessage2));

        // 检索最新的N条消息
        List<Message> messages = chatMemory.get(conversationId, 2);

        // 输出消息内容
        for (Message message : messages) {
            System.out.println(message.getContent());
        }
    }
}

Advisor应用

  1. PromptChatMemoryAdvisor
    PromptChatMemoryAdvisor是Spring AI框架中的一个组件,它实现了Advisor接口,并提供了特定的逻辑来处理聊天记忆中的消息。当使用Spring AI与LLM进行交互时,PromptChatMemoryAdvisor可以自动地将与当前会话相关的历史消息添加到提示中,从而增强LLM对上下文的理解。
    原理:
  2. 检索历史消息:PromptChatMemoryAdvisor会从配置的ChatMemory(如InMemoryChatMemory)中检索与当前会话相关的历史消息。
  3. 构建提示:检索到的历史消息会被添加到提示的系统文本中。系统文本通常用于指定LLM的角色或提供额外的上下文信息。
  4. 发送提示:增强后的提示会被发送到LLM,LLM基于这个提示生成回复。

应用:
在Spring AI应用中,开发者可以通过以下步骤使用PromptChatMemoryAdvisor:

1. **配置ChatMemory**:首先,需要配置一个ChatMemory实现来存储和管理对话历史记录。
2. **创建PromptChatMemoryAdvisor实例**:然后,创建一个PromptChatMemoryAdvisor实例,并将其与配置的ChatMemory关联起来。
3. **注册Advisor**:将PromptChatMemoryAdvisor实例注册到Spring AI的Advisor链中。这通常是在构建ChatClient时通过调用defaultAdvisors或advisors方法完成的。
4. **发送提示并接收回复**:在发送提示到LLM之前,PromptChatMemoryAdvisor会自动地将历史消息添加到提示中。然后,可以像平常一样发送提示并接收LLM的回复。

示例:

// 假设已经有一个配置好的ChatMemory实例chatMemory
PromptChatMemoryAdvisor promptChatMemoryAdvisor = new PromptChatMemoryAdvisor(chatMemory);
// 创建ChatClient并注册PromptChatMemoryAdvisor
ChatClient chatClient = ChatClient.builder(chatModel)
    .defaultAdvisors(promptChatMemoryAdvisor)
    .build();
// 发送提示并接收回复
String userText = "What did we talk about last time?";
String response = chatClient.prompt()
    .user(userText)
    .call()
    .content();
// 输出回复内容
System.out.println(response);
  1. VectorStoreChatMemoryAdvisor

VectorStoreChatMemoryAdvisor 是 Spring AI 框架中的一个组件,它结合了向量存储(VectorStore)技术来增强聊天机器人的记忆能力。这个 Advisor 利用向量数据库存储用户与聊天机器人的交互历史,包括用户提出的问题和模型的回答。在生成新的回复时,VectorStoreChatMemoryAdvisor 会检索与当前问题相关的历史记录,并将其作为上下文信息添加到提示中,从而帮助大型语言模型(LLM)生成更连贯和准确的回复。

原理:

  1. 存储交互历史:当用户与聊天机器人进行交互时,VectorStoreChatMemoryAdvisor 会将每次交互的信息(包括用户问题和模型回答)存储到向量数据库中。这些信息会被转换为向量表示,以便进行高效的检索和匹配。
  2. 检索相关历史:当用户提出新的问题时,VectorStoreChatMemoryAdvisor 会在向量数据库中检索与当前问题相关的历史记录。这通常是通过计算当前问题与历史记录之间的向量相似度来实现的。
  3. 增强提示信息:检索到的相关历史记录会被添加到提示的系统文本中,从而增强大型语言模型对上下文的理解。这有助于模型生成更连贯和准确的回复。
  4. 发送提示并接收回复:增强后的提示会被发送到大型语言模型,模型基于这个提示生成回复。回复随后会通过 VectorStoreChatMemoryAdvisor 和其他可能的 Advisor 链传递,最终返回给用户。

配置和使用
在 Spring AI 应用中,配置和使用 VectorStoreChatMemoryAdvisor 通常涉及以下步骤:
5. 设置向量数据库:首先需要配置一个向量数据库来存储交互历史。Spring AI 框架支持多种向量数据库实现,如 AzureVectorStore、ChromaVectorStore、PgVectorStore 等。
6. 创建 VectorStoreChatMemoryAdvisor 实例:使用配置好的向量数据库创建一个 VectorStoreChatMemoryAdvisor 实例。
7. 注册 Advisor:将 VectorStoreChatMemoryAdvisor 实例注册到 Spring AI 的 Advisor 链中。这通常是在构建 ChatClient 时通过调用 defaultAdvisors 或 advisors 方法完成的。
8. 发送提示并接收回复:在发送提示到大型语言模型之前,VectorStoreChatMemoryAdvisor 会自动检索并增强提示信息。然后,可以像平常一样发送提示并接收回复。

示例:

// 假设已经有一个配置好的 VectorStore 实例 vectorStore
VectorStoreChatMemoryAdvisor vectorStoreChatMemoryAdvisor = new VectorStoreChatMemoryAdvisor(vectorStore);

// 将 VectorStoreChatMemoryAdvisor 注册到 ChatClient 中
chatClient.registerAdvisor(vectorStoreChatMemoryAdvisor);

// 发送提示并接收回复(示例代码,具体实现可能因框架版本和配置而异)
String userText = "What did we discuss last time about this topic?";
String response = chatClient.prompt(userText).call().getContent();
System.out.println(response);
### 使用 Spring 和 Alibaba 技术实现带有上下文记忆的聊天机器人 #### 设计思路 为了创建一个具备上下文记忆功能的聊天应用,可以采用微服务架构并利用Spring Cloud Alibaba组件来管理分布式系统的复杂性。通过引入Nacos作为注册中心和服务发现工具,Sentinel用于流量防护和熔断降级机制,Seata处理跨服务事务一致性问题。 #### 关键技术选型 - **后端框架**: 基于Spring Boot快速搭建基础环境,并集成Spring AI Alibaba模块以增强自然语言理解和生成的能力[^1]。 - **会话状态存储**: Redis被广泛应用于缓存用户交互历史记录,确保每次请求都能获取到完整的对话背景信息。 - **消息队列**: Kafka可用于异步通信模式下传递事件通知给各个子系统之间同步数据更新操作。 #### 实现步骤概述 定义实体类表示用户的输入输出对象;编写控制器接收HTTP POST请求并将参数转发至业务逻辑层进行解析处理;调用第三方API接口查询外部资源或执行具体动作指令前先判断当前话题是否已经存在关联的历史记录;最后返回响应结果给客户端展示界面。 ```java @RestController @RequestMapping("/chatbot") public class ChatBotController { @Autowired private ChatService chatService; @PostMapping(value = "/talk", consumes = MediaType.APPLICATION_JSON_VALUE, produces = MediaType.APPLICATION_JSON_VALUE) public ResponseEntity<ChatResponse> talk(@RequestBody ChatRequest request){ String userId = request.getUserId(); String messageText = request.getMessage(); // Check and load conversation history from redis cache by user id. List<String> contextHistory = redisTemplate.opsForList().range(userId, 0 ,-1); // Pass the loaded context to service layer for processing along with new incoming messages. ChatResponse response = this.chatService.processMessage(messageText,contextHistory); // Save current interaction back into redis as part of ongoing session data. redisTemplate.opsForList().rightPush(userId,messageText); return ResponseEntity.ok(response); } } ``` 上述代码片段展示了如何在一个RESTful API中处理来自前端的消息,并且考虑到了保持连续性的需求——即保存之前的交流内容以便后续参考。每当收到新消息时都会尝试从Redis数据库读取该用户的过往对话列表,之后再把这些资料一并发往负责实际应答的服务单元做进一步分析计算得出最终答复后再追加进对应的链表里头去形成新的条目等待下次访问时候能够再次提取出来使用[^2]。
评论 4
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

王小工

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值