liveBook · Manning

Messagewindowchatmemory

As explained in Spring AI in Action

MessageWindowChatMemory is a Spring AI chat-memory implementation that maintains a bounded window of conversational messages through a ChatMemoryRepository.

MessageWindowChatMemory is a Spring AI ChatMemory implementation that keeps a bounded window of conversational messages through a ChatMemoryRepository. Its default repository stores history in an in-memory Map, making conversational context easy to add but unavailable after application restart. section 5.2.1 section 5.3

Listing 5.1 Adding message-oriented chat memory as a default advisor
@Bean
ChatClient chatClient(
        ChatClient.Builder chatClientBuilder, 
        VectorStore vectorStore,
        ChatMemory chatMemory) {
  return chatClientBuilder
      .defaultAdvisors(
          MessageChatMemoryAdvisor.builder(chatMemory).build(),   #1
          QuestionAnswerAdvisor.builder(vectorStore)
              .searchRequest(SearchRequest.builder().build()).build())
        .build();
}

Register MessageChatMemoryAdvisor with the ChatMemory bean when building a ChatClient; the advisor supplies stored messages to subsequent prompts. section 5.2.1

Configure the memory window and conversation identity as application requirements grow:

  • Use the default configuration for a simple in-memory conversation, with the most recent 20 messages sent in prompts. section 5.2.1 section 5.2.3
  • Override the ChatMemory bean and call maxMessages() to change the limit; older entries drop off as new messages arrive. section 5.2.3
  • Pass a conversation ID through the advisor parameters so separate conversations do not share context. section 5.3
@Bean
ChatMemory chatMemory(ChatMemoryRepository chatMemoryRepository) {
  return MessageWindowChatMemory.builder()
      .chatMemoryRepository(chatMemoryRepository)
      .maxMessages(50)
      .build();
}

Define a ChatMemory bean with MessageWindowChatMemory.builder(), inject ChatMemoryRepository, and set maxMessages(50) for a larger window. section 5.2.3

Maintaining context across follow-up questions

A request asks about the Burger Force Field card in Burger Battle, then asks whether it protects against Burgerpocalypse. Reusing the same conversation ID lets the second request refer to the earlier card without repeating its name; a different ID starts without that context. section 5.2.1 section 5.3

Listing 5.3 Providing the conversation ID to the advisor
import static org.springframework.ai.chat.memory
    .ChatMemory.CONVERSATION_ID;

  // ...

  @Override
  public Answer askQuestion(Question question, String conversationId) {
    var gameNameMatch = String.format(
            "gameTitle == '%s'",
            normalizeGameTitle(question.gameTitle()));

    return chatClient.prompt()
        .system(systemSpec -> systemSpec
            .text(promptTemplate)
            .param("gameTitle", question.gameTitle()))
        .user(question.question())
        .advisors(advisorSpec -> advisorSpec
            .param(FILTER_EXPRESSION, gameNameMatch)
            .param(CONVERSATION_ID, conversationId))  #1
        .call()
        .entity(Answer.class);
  }

Supply ChatMemory.CONVERSATION_ID through the advisor specification alongside the application’s retrieval parameters. section 5.3

The default in-memory behavior suits introductory or temporary use, but it is not recommended for production when history must survive restarts, be shared across instances, or avoid indefinite application-memory growth. Replace the repository with CassandraChatMemoryRepository, JdbcChatMemoryRepository, or Neo4jChatMemoryRepository for durable storage. section 5.3 section 5.4.1

@Bean
ChatMemory chatMemory(ChatMemoryRepository chatMemoryRepository) {
  return MessageWindowChatMemory.builder()
      .chatMemoryRepository(chatMemoryRepository)
      .build();
}

Build MessageWindowChatMemory with an injected repository so the windowing behavior remains while storage moves to a configured persistent implementation. section 5.4.1

How Spring AI in Action covers it

How deep it goes
Explains advisor integration, repository storage, message limits, conversation IDs, and persistent repository choices.
Examples
Uses Burger Battle follow-up questions, builder-based window sizing, request-header conversation IDs, and database repository configuration.
What it assumes
Assumes a Spring AI ChatClient and advisor-based application while demonstrating memory setup and conversation identity explicitly.
What you can do after
Configure bounded chat history, isolate conversations, and replace volatile storage with a persistent repository.
How it connects
Connects ChatMemory, ChatMemoryRepository, MessageChatMemoryAdvisor, PromptChatMemoryAdvisor, ChatClient, and database-backed repositories.

Related concepts

This explainer was generated by Manning's knowledge graph from the text of Spring AI in Action. The section links point to the parts of the book it draws on.