序
本文主要研究一下langchain4j的ChatMemory
ChatMemory
langchain4j-core/src/main/java/dev/langchain4j/memory/ChatMemory.java
public interface ChatMemory {
/**
* The ID of the {@link ChatMemory}.
* @return The ID of the {@link ChatMemory}.
*/
Object id();
/**
* Adds a message to the chat memory.
*
* @param message The {@link ChatMessage} to add.
*/
void add(ChatMessage message);
/**
* Retrieves messages from the chat memory.
* Depending on the implementation, it may not return all previously added messages,
* but rather a subset, a summary, or a combination thereof.
*
* @return A list of {@link ChatMessage} objects that represent the current state of the chat memory.
*/
List<ChatMessage> messages();
/**
* Clears the chat memory.
*/
void clear();
}
ChatMemory定义了id、add、messages、clear方法,它有MessageWindowChatMemory、TokenWindowChatMemory两个实现
public class MessageWindowChatMemory implements ChatMemory {
private static final Logger log = LoggerFactory.getLogger(MessageWindowChatMemory.class);
private final Object id;
private final Integer maxMessages;
private final ChatMemoryStore store;
private MessageWindowChatMemory(Builder builder) {
this.id = ensureNotNull(builder.id, "id");
this.maxMessages = ensureGreaterThanZero(builder.maxMessages, "maxMessages");
this.store = ensureNotNull(builder.store, "store");
}
@Override
public Object id() {
return id;
}
@Override
public void add(ChatMessage message) {
List<ChatMessage> messages = messages();
if (message instanceof SystemMessage) {
Optional<SystemMessage> systemMessage = findSystemMessage(messages);
if (systemMessage.isPresent()) {
if (systemMessage.get().equals(message)) {
return; // do not add the same system message
} else {
messages.remove(systemMessage.get()); // need to replace existing system message
}
}
}
messages.add(message);
ensureCapacity(messages, maxMessages);
store.updateMessages(id, messages);
}
private static Optional<SystemMessage> findSystemMessage(List<ChatMessage> messages) {
return messages.stream()
.filter(message -> message instanceof SystemMessage)
.map(message -> (SystemMessage) message)
.findAny();
}
@Override
public List<ChatMessage> messages() {
List<ChatMessage> messages = new LinkedList<>(store.getMessages(id));
ensureCapacity(messages, maxMessages);
return messages;
}
private static void ensureCapacity(List<ChatMessage> messages, int maxMessages) {
while (messages.size() > maxMessages) {
int messageToEvictIndex = 0;
if (messages.get(0) instanceof SystemMessage) {
messageToEvictIndex = 1;
}
ChatMessage evictedMessage = messages.remove(messageToEvictIndex);
log.trace("Evicting the following message to comply with the capacity requirement: {}", evictedMessage);
if (evictedMessage instanceof AiMessage && ((AiMessage) evictedMessage).hasToolExecutionRequests()) {
while (messages.size() > messageToEvictIndex
&& messages.get(messageToEvictIndex) instanceof ToolExecutionResultMessage) {
// Some LLMs (e.g. OpenAI) prohibit ToolExecutionResultMessage(s) without corresponding AiMessage,
// so we have to automatically evict orphan ToolExecutionResultMessage(s) if AiMessage was evicted
ChatMessage orphanToolExecutionResultMessage = messages.remove(messageToEvictIndex);
log.trace("Evicting orphan {}", orphanToolExecutionResultMessage);
}
}
}
}
@Override
public void clear() {
store.deleteMessages(id);
}
//......
}
MessageWindowChatMemory默认使用的是InMemoryChatMemoryStore;ensureCapacity方法用来确保message不超过maxMessages,超过则从list的头部开始移除;SystemMessage一旦添加了就会一直保留,每次只能保留一个SystemMessage,添加相同的SystemMessage会被忽略,不同的SystemMessage会保留最新的

最低0.47元/天 解锁文章

5186

被折叠的 条评论
为什么被折叠?



