Skip to content

Commit

Permalink
Update chat memory example and separate ChatMemoryStore from ChatMemo…
Browse files Browse the repository at this point in the history
…ry usage
  • Loading branch information
andreas-eberle committed Dec 7, 2023
1 parent 685203f commit 6be3de2
Show file tree
Hide file tree
Showing 5 changed files with 61 additions and 51 deletions.

This file was deleted.

Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
package io.quarkiverse.langchain4j.samples;

import jakarta.enterprise.context.ApplicationScoped;
import jakarta.inject.Inject;

import dev.langchain4j.memory.ChatMemory;
import dev.langchain4j.memory.chat.ChatMemoryProvider;
import dev.langchain4j.memory.chat.MessageWindowChatMemory;
import dev.langchain4j.store.memory.chat.ChatMemoryStore;

@ApplicationScoped
public class ChatMemoryProviderBean implements ChatMemoryProvider {

@Inject
ChatMemoryStore store;

@Override
public ChatMemory get(Object memoryId) {
return MessageWindowChatMemory.builder()
.id(memoryId)
.maxMessages(20)
.chatMemoryStore(store)
.build();
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
package io.quarkiverse.langchain4j.samples;

import jakarta.enterprise.context.ApplicationScoped;

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

public class ChatMemoryStoreProducer {

@ApplicationScoped
ChatMemoryStore produceChatMemoryStore() {
return new InMemoryChatMemoryStore();
}
}
Original file line number Diff line number Diff line change
@@ -1,32 +1,24 @@
package io.quarkiverse.langchain4j.samples;

import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;
import java.util.function.Supplier;

import dev.langchain4j.memory.ChatMemory;
import jakarta.inject.Inject;

import dev.langchain4j.memory.chat.ChatMemoryProvider;
import dev.langchain4j.memory.chat.MessageWindowChatMemory;
import io.quarkiverse.langchain4j.RemovableChatMemoryProvider;
import dev.langchain4j.store.memory.chat.ChatMemoryStore;

public class MySmallMemoryProvider implements Supplier<ChatMemoryProvider> {
@Override
public ChatMemoryProvider get() {
return new RemovableChatMemoryProvider() {
private final Map<Object, ChatMemory> memories = new ConcurrentHashMap<>();

@Override
public ChatMemory get(Object memoryId) {
return memories.computeIfAbsent(memoryId, id -> MessageWindowChatMemory.builder()
.maxMessages(20)
.id(memoryId)
.build());
}
@Inject
ChatMemoryStore store;

@Override
public void remove(Object id) {
memories.remove(id);
}
};
@Override
public ChatMemoryProvider get() {
return memoryId -> MessageWindowChatMemory.builder()
.id(memoryId)
.maxMessages(20)
.chatMemoryStore(store)
.build();
}
}
12 changes: 10 additions & 2 deletions docs/modules/ROOT/pages/ai-services.adoc
Original file line number Diff line number Diff line change
Expand Up @@ -181,10 +181,18 @@ An example of such a bean is:

[source,java]
----
include::{examples-dir}/io/quarkiverse/langchain4j/samples/ChatMemoryBean.java[]
include::{examples-dir}/io/quarkiverse/langchain4j/samples/ChatMemoryProviderBean.java[]
----

Notice that the messages are deleted when the scope terminates (as it will call the `close` method).
Additionally, it is important to configure a `ChatMemoryStore` which is responsible for actually storing the chat memory.
The following example shows how an application wide `InMemoryChatMemoryStore` can be used for this.

[source,java]
----
include::{examples-dir}/io/quarkiverse/langchain4j/samples/ChatMemoryStoreProducer.java[]
----

Notice that with this example, conversations are not deleted and thus accumulate over time.

NOTE: It is recommended to have your chat memory beans implement `RemovableChatMemoryProvider` because the objects used as memory IDs are removed from the memory when the service goes out of scope.

Expand Down

0 comments on commit 6be3de2

Please sign in to comment.