而在defaultAdvisors(new PromptChatMemoryAdvisor(chatMemory))这个中传入了一个chatMemory对象,这个就是我们今天要介绍的。 Spring AI当然也是考虑到这点了,因此有了ChatMemory的实现。 ChatMemory是个抽象接口,我们看一下org.springframework.ai.chat.memory.ChatMemory的源码:/** * The ChatMemory interface 其实很简单,Spring AI会自动装配一个ChatMemory的bean,我们只需要使用:@AutowiredChatMemory chatMemory;即可直接使用。 4.1、实现ChatMemory接口public class FileCacheChatMemory implements ChatMemory { @Override public void
interface ChatMemory { /** * The ID of the {@link ChatMemory} if (context.hasChatMemory()) { ChatMemory chatMemory = context.chatMemory( 添加到chatMemory简而言之就有点类似ChatLanguageModel model = OpenAiChatModel.withApiKey(openAiKey);ChatMemory chatMemory ; // Pulp Fiction, Kill Bill, etc.chatMemory.add(answer);chatMemory.add(UserMessage.userMessage("How AiServices集成了ChatMemory可以自动将message添加到chatMemory,省去手工操作。
一、Spring AI 聊天记忆核心概念 1.1 ChatMemory 接口 ChatMemory 是 Spring AI 中定义聊天记忆行为的核心接口: public interface ChatMemory 二、MessageWindowChatMemory 详解 2.1 核心特性 MessageWindowChatMemory 是 ChatMemory 的主要实现类,具有以下特点: 维护一个固定大小的消息窗口 构造函数是私有的 ChatMemory memory = new MessageWindowChatMemory(repository, 20); 正确方式 - 使用 Builder 模式: @Bean public ChatMemory chatMemory(ChatMemoryRepository chatMemoryRepository) { return MessageWindowChatMemory.builder ChatClient chatClient(OllamaChatModel chatModel, ChatMemory chatMemory) { return ChatClient.builder
* * @param chatMemory An instance of chat memory to be used by the AI Service. * @return builder */ public AiServices<T> chatMemory(ChatMemory chatMemory) { } for all users/conversations, configure a {@link #chatMemory} instead chatMemory = context.chatMemory(memoryId); systemMessage.ifPresent(chatMemory high level的组件,用于协同多个组件(提示模版、ChatMemory、LLM、输出解析、RAG组件:嵌入模型和评分)一起。
* @param chatMemory the chat memory store */ protected AbstractChatMemoryAdvisor(T chatMemory > { public MessageChatMemoryAdvisor(ChatMemory chatMemory) { super(chatMemory); } public ; } public static Builder builder(ChatMemory chatMemory) { return new Builder(chatMemory); > { protected Builder(ChatMemory chatMemory) { super(chatMemory); } public MessageChatMemoryAdvisor (ChatMemory chatMemory, String systemTextAdvise) { super(chatMemory); this.systemTextAdvise =
* @param chatMemory the chat memory store */ protected AbstractChatMemoryAdvisor(T chatMemory) > { public MessageChatMemoryAdvisor(ChatMemory chatMemory) { super(chatMemory); } public MessageChatMemoryAdvisor (ChatMemory chatMemory, String defaultConversationId, int chatHistoryWindowSize) { this(chatMemory > { protected Builder(ChatMemory chatMemory) { super(chatMemory); } public MessageChatMemoryAdvisor chatMemory) { this(chatMemory, DEFAULT_SYSTEM_TEXT_ADVISE); } public PromptChatMemoryAdvisor(ChatMemory
一、Spring AI 1.1.x 对话记忆核心概念Spring AI 1.1.x 将 对话记忆系统拆分为两层:ChatMemory ↓ ChatMemoryRepository组件作用ChatMemory 管理对话上下文ChatMemoryRepository负责持久化存储核心设计思想:逻辑层(ChatMemory)存储层(ChatMemoryRepository)实现 存储解耦。 二、ChatMemory1 概念ChatMemory 是 对话上下文管理器,负责:保存对话消息获取历史消息控制记忆窗口维护会话上下文对话记忆是 按 conversationId 维度管理。 .maxMessages(10) .build(); public LoveApp(ChatClient.Builder builder, ChatMemory chatMemory) 创建(这利用Spring的自动装配机制)同样的在LoveApp中,不再让ChatMemory作为字段而是作为构造方法的参数,利用自动装配机制,让其找到容器中基于关系数据库的ChatMemory,完成ChatClient
, aiServiceAnnotation, aiServiceAnnotation.chatMemory (), chatMemories, "chatMemory", "chatMemory", propertyValues ); addBeanReference chatMemory) { this.chatMemory = chatMemory; } public void setChatMemoryProvider(ChatMemoryProvider = null) { builder.chatMemory(chatMemory); } if (chatMemoryProvider !
ChatMemory主要作用是用来管理和维护ChatMessage。 chatMemory = MessageWindowChatMemory.withMaxMessages(10); Assistant assistant = AiServices.builder (Assistant.class) .chatModel(qwenChatModel) .chatMemory(chatMemory) Persistence 持久化默认情况下, ChatMemory 实现将 ChatMessage 存储在内存中(服务重启数据丢失)。 ChatMessage 可以分别存储(例如,每条消息一个记录/行/对象)或一起存储(例如,整个 ChatMemory 一个记录/行/对象)。
* * @param chatMemory An instance of chat memory to be used by the AI Service. * @return builder */ public AiServices<T> chatMemory(ChatMemory chatMemory) { context.chatMemories } for all users/conversations, configure a {@link #chatMemory} instead chatMemory = context.chatMemory(memoryId); systemMessage.ifPresent(chatMemory high level的组件,用于协同多个组件(提示模版、ChatMemory、LLM、输出解析、RAG组件:嵌入模型和评分)一起。
context.chatMemory(memoryId).messages() : null; Metadata metadata = Metadata.from(userMessage, memoryId, chatMemory); userMessage chatMemory = context.chatMemory(memoryId); systemMessage.ifPresent(chatMemory if (context.hasChatMemory()) { context.chatMemory chatMemory = context.chatMemory(memoryId); for (ToolExecutionRequest
, aiServiceAnnotation, aiServiceAnnotation.chatMemory() , chatMemories, "chatMemory", "chatMemory chatMemory; private ChatMemoryProvider chatMemoryProvider; private ContentRetriever contentRetriever chatMemory) { this.chatMemory = chatMemory; } public void setChatMemoryProvider(ChatMemoryProvider = null) { builder.chatMemory(chatMemory); } if (chatMemoryProvider !
因此,LangChain4j 提供了ChatMemory抽象以及多个开箱即用的实现:ChatMemory可以作为一个独立的底层组件使用也可作为类似AI服务等高级组件的一部分使用ChatMemory作为ChatMessage 3 持久化默认情况下,ChatMemory的实现将ChatMessage存储在内存中。 } }ChatMemory chatMemory = MessageWindowChatMemory.builder() .id("12345") .maxMessages 每当ChatMemory的用户请求所有消息时,都会调用getMessages()方法。 通常在每次与 LLM 交互时调用一次。 每当调用ChatMemory.clear()时,都会调用deleteMessages()方法。 如果不使用此功能,可以将此方法留空。
chatMemory; public MyMessageChatMemoryAdvisor(ChatMemory chatMemory) { super(chatMemory ); this.chatMemory = chatMemory; } public MyMessageChatMemoryAdvisor(ChatMemory chatMemory (ChatMemory chatMemory, String defaultConversationId, int chatHistoryWindowSize, int order) { super(chatMemory, defaultConversationId, chatHistoryWindowSize, order); this.chatMemory = chatMemory chatMemory = (ChatMemory)toolContext.getContext().get("userMemory"); String conversation_id
最新的ChatMemory接口,在1.1.0中,有1个方法定义: 而spring-ai-starter-model-chat-memory-repository-jdbc 1.0.0版本中的ChatMemory new MyMessageWindowChatMemory(this.chatMemoryRepository, this.maxMessages); } } } 二、注入ChatMemory chatMemory(ChatMemoryRepository chatMemoryRepository) { return MyMessageWindowChatMemory.builder 当前新问题,扔到聊天上下文中 chatMemory.add(conversationId, new UserMessage(prompt)); // 2. 把历史消息全都取出来 List<Message> history = chatMemory.get(conversationId, MAX_HISTORY_SESSION);
com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper; import org.springframework.ai.chat.memory.ChatMemory java.util.List; import java.util.stream.Collectors; @Component public class MySQLChatMemory implements ChatMemory MultiChatController { @Autowired private ChatClient chatClient; @Autowired private MySQLChatMemory chatMemory MessageChatMemoryAdvisor,自动管理上下文 MessageChatMemoryAdvisor advisor = new MessageChatMemoryAdvisor(chatMemory .call().content(); } } 小结 通过以上代码大家也可以看出来,使用 Spring AI 实现连续对话是比较复杂的,需要自己实现数据库增删改查的代码,并且重写 ChatMemory
封装了ChatModel 、 ChatMessage 、 ChatMemory 等低级组件。提供更加方便简单的使用方式。 String chat(String userMessage); } @Autowired Assistant assistant; public void chatMeme() { ChatMemory chatMemory = MessageWindowChatMemory.withMaxMessages(10); Assistant assistant = AiServices.builder (Assistant.class) .chatModel(qwenChatModel) .chatMemory(chatMemory)
chatMemory; private final ConversationService conversationService; public IntelligentCustomerService = chatModel; this.vectorStore = vectorStore; this.chatMemory = chatMemory; this.conversationService 获取对话历史 List<Message> conversationHistory = chatMemory.get(userId, 10); (userId, new UserMessage(question)); chatMemory.add(userId, new AssistantMessage(answer)); chatMemory; @Mock private ConversationService conversationService; @InjectMocks
retrievalAugmentationAdvisor;public ModuleRAGCompressionController(ChatClient.Builder chatClientBuilder,ChatMemory chatMemory,VectorStore vectorStore) {this.chatClient = chatClientBuilder.build();this.chatMemoryAdvisor = MessageChatMemoryAdvisor.builder(chatMemory).build();var documentRetriever = VectorStoreDocumentRetriever.builder retrievalAugmentationAdvisor;public ModuleRAGMemoryController(ChatClient.Builder chatClientBuilder,ChatMemory chatMemory,VectorStore vectorStore) {this.chatClient = chatClientBuilder.build();this.chatMemoryAdvisor
Describethefollowingimage"),ImageContent.from("https://example.com/cat.jpg"));ChatResponseresponse=model.chat(userMessage);ChatMemory MessageWindowChatMemory.withMaxMessages(10);//创建记录10条记录的记忆量(提问和回答都算)publicStringchatMemory(Stringmessage){chatMemory.add 此处表示扔入记忆对象中ChatResponsechat1=chatLanguageModel.chat(chatMemory.messages());//此处使用ChatResponse接收,它里面包含了 chatMemory.add(chat1.aiMessage());//记录此次对话返回的数据returnchat1.aiMessage().text();//返回给页面做渲染}ENDING此次记录到这