LangChain4j AiServices 实现聊天记忆

邢文凯 2024-08-04 12:01:02 阅读 96

ChatMemory

上次说到ChatMessage手动的维护和管理是比较麻烦的,因此LangChain4j提出了ChatMemory的概念。它的本质是ChatMessage的容器。

可以看下ChatMemory这个接口的方法,它内部封装了一个List的ChatMessage。

要注意的是:

LLM的上下文窗口都是有一定限制的,针对不同的LLM可能限制的令牌数量有所不同,这意味着他们在任何给定时间可以处理的令牌数量都有上限,这可能会导致整个窗口对话超出限制。每个令牌都有成本,所以每次调用LLM的成本会逐渐增加。

通过ChatMemory可以结合ApiServices组件可以实现聊天记忆功能。

以下是官方提供的几个示例:

简单的聊天记忆

<code>package com.chatglm.demo;

import dev.langchain4j.memory.ChatMemory;

import dev.langchain4j.memory.chat.MessageWindowChatMemory;

import dev.langchain4j.model.openai.OpenAiChatModel;

import dev.langchain4j.service.AiServices;

/**

* 聊天记忆

*/

public class ServiceWithMemoryExample {

/**

* 定义一个带有单个方法的接口

*/

interface Assistant {

String chat(String message);

}

public static void main(String[] args) {

// 创建ChatLanguageModel组件作为AiServices的基础组件

OpenAiChatModel openAiChatModel = OpenAiChatModel.withApiKey("demo");

// 创建MessageWindowChatMemory充当滑动窗口

ChatMemory chatMemory = MessageWindowChatMemory.withMaxMessages(10);

// 利用Apiservices组件实现Assistant接口并接入chatMemory

Assistant assistant = AiServices.builder(Assistant.class)

.chatLanguageModel(openAiChatModel)

.chatMemory(chatMemory)

.build();

String answer = assistant.chat("你好,我叫小A.");

System.out.println(answer);

String answerWithName = assistant.chat("我叫什么名字?");

System.out.println(answerWithName);

}

}

AI回答:

多用户聊天记忆

<code>package com.chatglm.demo;

import dev.langchain4j.memory.chat.MessageWindowChatMemory;

import dev.langchain4j.model.openai.OpenAiChatModel;

import dev.langchain4j.service.AiServices;

import dev.langchain4j.service.MemoryId;

import dev.langchain4j.service.UserMessage;

/**

* 每个用户单独的聊天内存

*/

public class ServiceWithMemoryForEachUserExample {

interface Assistant {

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

}

public static void main(String[] args) {

Assistant assistant = AiServices.builder(Assistant.class)

.chatLanguageModel(OpenAiChatModel.withApiKey(""))

.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.

}

}

聊天记忆持久化

依赖:

<dependency>

<groupId>org.mapdb</groupId>

<artifactId>mapdb</artifactId>

<version>3.0.9</version>

<exclusions>

<exclusion>

<groupId>org.jetbrains.kotlin</groupId>

<artifactId>kotlin-stdlib</artifactId>

</exclusion>

</exclusions>

</dependency>

package com.chatglm.demo;

import dev.langchain4j.data.message.ChatMessage;

import dev.langchain4j.memory.ChatMemory;

import dev.langchain4j.memory.chat.MessageWindowChatMemory;

import dev.langchain4j.model.openai.OpenAiChatModel;

import dev.langchain4j.service.AiServices;

import dev.langchain4j.store.memory.chat.ChatMemoryStore;

import org.mapdb.DB;

import org.mapdb.DBMaker;

import java.util.List;

import java.util.Map;

import static dev.langchain4j.data.message.ChatMessageDeserializer.messagesFromJson;

import static dev.langchain4j.data.message.ChatMessageSerializer.messagesToJson;

import static org.mapdb.Serializer.STRING;

/**

* 持久的聊天记忆

*/

public class ServiceWithPersistentMemoryExample {

interface Assistant {

String chat(String message);

}

public static void main(String[] args) {

ChatMemory chatMemory = MessageWindowChatMemory.builder()

.maxMessages(10)

.chatMemoryStore(new PersistentChatMemoryStore())

.build();

Assistant assistant = AiServices.builder(Assistant.class)

.chatLanguageModel(OpenAiChatModel.withApiKey("demo"))

.chatMemory(chatMemory)

.build();

String answer = assistant.chat("你是什么智能");

System.out.println(answer); // Hello Klaus! How can I assist you today?

// Now, comment out the two lines above, uncomment the two lines below, and run again.

// String answerWithName = assistant.chat("What is my name?");

// System.out.println(answerWithName); // Your name is Klaus.

}

// You can create your own implementation of ChatMemoryStore and store chat memory whenever you'd like

static class PersistentChatMemoryStore implements ChatMemoryStore {

private final DB db = DBMaker.fileDB("chat-memory.db").transactionEnable().make();

private final Map<String, String> map = db.hashMap("messages", STRING, STRING).createOrOpen();

@Override

public List<ChatMessage> getMessages(Object memoryId) {

String json = map.get((String) memoryId);

return messagesFromJson(json);

}

@Override

public void updateMessages(Object memoryId, List<ChatMessage> messages) {

String json = messagesToJson(messages);

map.put((String) memoryId, json);

db.commit();

}

@Override

public void deleteMessages(Object memoryId) {

map.remove((String) memoryId);

db.commit();

}

}

}

多用户聊天记忆持久化

package com.chatglm.demo;

import dev.langchain4j.data.message.ChatMessage;

import dev.langchain4j.memory.chat.ChatMemoryProvider;

import dev.langchain4j.memory.chat.MessageWindowChatMemory;

import dev.langchain4j.model.openai.OpenAiChatModel;

import dev.langchain4j.service.AiServices;

import dev.langchain4j.service.MemoryId;

import dev.langchain4j.service.UserMessage;

import dev.langchain4j.store.memory.chat.ChatMemoryStore;

import org.mapdb.DB;

import org.mapdb.DBMaker;

import java.util.List;

import java.util.Map;

import static dev.langchain4j.data.message.ChatMessageDeserializer.messagesFromJson;

import static dev.langchain4j.data.message.ChatMessageSerializer.messagesToJson;

import static org.mapdb.Serializer.INTEGER;

import static org.mapdb.Serializer.STRING;

/**

* 每个用户持久的聊天记忆

*/

public class ServiceWithPersistentMemoryForEachUserExample {

interface Assistant {

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

}

public static void main(String[] args) {

PersistentChatMemoryStore store = new PersistentChatMemoryStore();

ChatMemoryProvider chatMemoryProvider = memoryId -> MessageWindowChatMemory.builder()

.id(memoryId)

.maxMessages(10)

.chatMemoryStore(store)

.build();

Assistant assistant = AiServices.builder(Assistant.class)

.chatLanguageModel(OpenAiChatModel.withApiKey("demo"))

.chatMemoryProvider(chatMemoryProvider)

.build();

System.out.println(assistant.chat(1, "Hello, my name is Klaus"));

System.out.println(assistant.chat(2, "Hi, my name is Francine"));

// Now, comment out the two lines above, uncomment the two lines below, and run again.

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

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

}

// You can create your own implementation of ChatMemoryStore and store chat memory whenever you'd like

static class PersistentChatMemoryStore implements ChatMemoryStore {

private final DB db = DBMaker.fileDB("multi-user-chat-memory.db").transactionEnable().make();

private final Map<Integer, String> map = db.hashMap("messages", INTEGER, STRING).createOrOpen();

@Override

public List<ChatMessage> getMessages(Object memoryId) {

String json = map.get((int) memoryId);

return messagesFromJson(json);

}

@Override

public void updateMessages(Object memoryId, List<ChatMessage> messages) {

String json = messagesToJson(messages);

map.put((int) memoryId, json);

db.commit();

}

@Override

public void deleteMessages(Object memoryId) {

map.remove((int) memoryId);

db.commit();

}

}

}



声明

本文内容仅代表作者观点,或转载于其他网站,本站不以此文作为商业用途
如有涉及侵权,请联系本站进行删除
转载本站原创文章,请注明来源及作者。