首页
学习
活动
专区
圈层
工具
发布
社区首页 >专栏 >Langchain4j-03

Langchain4j-03

原创
作者头像
叶佳骏
发布2025-10-16 09:00:44
发布2025-10-16 09:00:44
1380
举报

ChatMemory

主要作用是用来管理和维护ChatMessage。负责对话消息的记忆与淘汰

额外功能:

  • Eviction policy  驱逐策略
  • Persistence  持久化
  • SystemMessage 特殊处理
  • Special treatment of tool messages 殊处理工具消息

注意:LangChain4j 目前只提供“记忆”,而不是“历史记录”。如果需要保留整个历史记录,需要开发者自行处理。

使用示例:

代码语言:java
复制
  
@AiService  
interface Assistant {  
    @SystemMessage("You are a polite assistant")  
    String chat(String userMessage);  
}  
public void chatMeme() {  
    ChatMemory chatMemory = MessageWindowChatMemory.withMaxMessages(10);  
  
    Assistant assistant = AiServices.builder(Assistant.class)  
            .chatModel(qwenChatModel)  
            .chatMemory(chatMemory)  
            .build();  
  
    String answer = assistant.chat("Hello! My name is Klaus.");  
    System.out.println(answer); // Hello Klaus! How can I assist you today?  
  
    String answerWithName = assistant.chat("What is my name?");  
    System.out.println(answerWithName); // Your name is Klaus.  
}

通过memoryId隔离会话:

代码语言:java
复制
import dev.langchain4j.memory.chat.MessageWindowChatMemory;
import dev.langchain4j.model.chat.ChatModel;
import dev.langchain4j.model.openai.OpenAiChatModel;
import dev.langchain4j.service.AiServices;
import dev.langchain4j.service.MemoryId;
import dev.langchain4j.service.UserMessage;

import static dev.langchain4j.model.openai.OpenAiChatModelName.GPT_4_O_MINI;

public class ServiceWithMemoryForEachUserExample {

    /**
     * See also {@link ServiceWithPersistentMemoryForEachUserExample}.
     */

    interface Assistant {

        String chat(@MemoryId int memoryId, @UserMessage String userMessage);
    }

    public static void main(String[] args) {

        ChatModel model = OpenAiChatModel.builder()
                .apiKey(ApiKeys.OPENAI_API_KEY)
                .modelName(GPT_4_O_MINI)
                .build();

        Assistant assistant = AiServices.builder(Assistant.class)
                .chatModel(model)
                .chatMemoryProvider(memoryId -> MessageWindowChatMemory.withMaxMessages(10))
                .build();

        System.out.println(assistant.chat(1, "Hello, my name is Klaus"));
        // Hi Klaus! How can I assist you today?

        System.out.println(assistant.chat(2, "Hello, my name is Francine"));
        // Hello Francine! How can I assist you today?

        System.out.println(assistant.chat(1, "What is my name?"));
        // Your name is Klaus.

        System.out.println(assistant.chat(2, "What is my name?"));
        // Your name is Francine.
    }
}

Eviction policy  驱逐策略

为了适应 LLM 的上下文窗口。LLM 一次可以处理的token数量是有限的。在某个时刻,对话可能会超过这个限制。在这种情况下,应该驱逐一些消息。通常,最旧的消息会被驱逐,但如果需要,可以实施更复杂的算法。

同时,驱逐旧的消息,可以节约token成本,提供响应效率。

目前,LangChain4j 提供了 2 种开箱即用的实现:

  • MessageWindowChatMemory:作为一个滑动窗口,保留最近的 N 条消息,并淘汰不再适合的旧消息
  • TokenWindowChatMemory:它也作为一个滑动窗口,但专注于保留最近的 N个token,并在需要时淘汰旧消息。注意按token来淘汰可能会导致语义不完整,消息是不可分割的。如果消息不合适,它将被完全淘汰。 所以TokenWindowChatMemory 需要一个 TokenCountEstimator 来计算每个 ChatMessage 中的token数量。Persistence  持久化默认情况下, ChatMemory 实现将 ChatMessage 存储在内存中(服务重启数据丢失)。 如果需要持久化,可以实现一个自定义的 ChatMemoryStore 来将 ChatMessage 存储在任何持久存储中:

使用示例:

代码语言:java
复制
class PersistentChatMemoryStore implements ChatMemoryStore {

        @Override
        public List<ChatMessage> getMessages(Object memoryId) {
          // TODO: Implement getting all messages from the persistent store by memory ID.
          // ChatMessageDeserializer.messageFromJson(String) and 
          // ChatMessageDeserializer.messagesFromJson(String) helper methods can be used to
          // easily deserialize chat messages from JSON.
        }

        @Override
        public void updateMessages(Object memoryId, List<ChatMessage> messages) {
            // TODO: Implement updating all messages in the persistent store by memory ID.
            // ChatMessageSerializer.messageToJson(ChatMessage) and 
            // ChatMessageSerializer.messagesToJson(List<ChatMessage>) helper methods can be used to
            // easily serialize chat messages into JSON.
        }

        @Override
        public void deleteMessages(Object memoryId) {
          // TODO: Implement deleting all messages in the persistent store by memory ID.
        }
    }

ChatMemory chatMemory = MessageWindowChatMemory.builder()
        .id("12345")
        .maxMessages(10)
        .chatMemoryStore(new PersistentChatMemoryStore())
        .build();

updateMessages() 方法在每次向 ChatMemory 添加新的 ChatMessage 时都会被调用。这通常在每次与 LLM 的交互中发生两次:一次是在添加新的 UserMessage 时,另一次是在添加新的 AiMessage 时。预期 updateMessages() 方法会更新与给定内存 ID 相关的所有消息。 ChatMessage 可以分别存储(例如,每条消息一个记录/行/对象)或一起存储(例如,整个 ChatMemory 一个记录/行/对象)。

原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。

如有侵权,请联系 cloudcommunity@tencent.com 删除。

原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。

如有侵权,请联系 cloudcommunity@tencent.com 删除。

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • ChatMemory
    • Eviction policy  驱逐策略
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档