Handling Multiple Sessions

Handling Multiple Sessions

Welcome to the next step in your journey of creating a personal tutor with Spring AI! In the previous lessons, you worked with a ChatService class to send queries to Spring AI's language model, explore model parameters, maintain tutoring session history, and personalize AI behavior with system prompts.

In this lesson, we will generalize and refactor ChatService to a TutoringService to better reflect its educational purpose and to support managing multiple tutoring sessions. This is crucial for applications where you need to handle several educational interactions simultaneously, such as a tutoring platform serving multiple students. By the end of this lesson, you will be able to create and manage multiple tutoring sessions using Spring AI framework, setting the stage for more complex educational interactions.

Creating Unique Tutoring Sessions

In a tutoring application, each educational interaction should be treated as a separate session. To achieve this, we use unique identifiers for each tutoring session. This ensures that queries and explanations are correctly associated with their respective sessions.

We'll generate a unique session identifier using UUID.randomUUID().toString(). Each session's conversation history is managed by associating the session ID with its own context, allowing the AI to maintain continuity for each student.

Below is an example of how to create this method:

import java.util.UUID;

public class TutoringService {

    // Create a new tutoring session and return its unique ID.
    public String createSession() {
        return UUID.randomUUID().toString();
    }

    // ... (other methods)
}

We'll use this session ID to keep track of the conversation history and context for each student.

By managing sessions in this way, you ensure that each educational interaction remains distinct and coherent.

Sending Queries and Receiving Explanations

Once a tutoring session is created, you can send queries and receive explanations while keeping the conversation context intact. To maintain this context across messages, each question must be associated with its corresponding session ID.

In Spring AI, this can be done by passing the session ID to the chat advisor, which ensures the right memory history is retrieved and updated for that specific session. Advisors are a chain of interceptors that can process and modify chat requests and responses, allowing you to add functionalities such as managing conversation history, enforcing usage limits, logging interactions, and more. When you use the .advisors() method, you specify which advisors should be applied to a particular chat prompt, enabling features like session management and context preservation for each conversation.

Below is the updated askQuestion method in TutoringService, which takes a sessionId and uses it to manage memory isolation:

public class TutoringService {
    // ... (other fields and methods)

    // Sends a question under the given session and returns the assistant's response
    public String askQuestion(String sessionId, String question) {
        return chatClient.prompt()
                .advisors(advisor -> advisor.param(
                        ChatMemory.CONVERSATION_ID, sessionId))
                .user(question)
                .call()
                .content();
    }
}

Here’s what’s happening in the advisors configuration:

  • ChatMemory.CONVERSATION_ID is a special key that tells Spring AI which session’s message history to use.
  • The sessionId you provide acts as the unique identifier for that tutoring session.
  • Spring AI automatically retrieves past messages for that session and appends the latest user and assistant messages after each call.

By using a unique sessionId per session, each conversation stays separate and maintains its own memory, ensuring accurate and personalized interactions.

Multiple Sessions in Action

The code below demonstrates how to create and interact with separate tutoring sessions using the TutoringService. Each session maintains its own memory, ensuring that conversations remain isolated and context-specific. This prevents any overlap or interference between different users or topics.

Inside the below example, we simulate two independent sessions by generating unique session IDs and asking different sets of questions in each one:

// Create two independent tutoring sessions
String session1 = tutoringService.createSession();
String session2 = tutoringService.createSession();

// Session 1: Ask two general knowledge questions
System.out.println("Session 1 → General tutoring questions");
System.out.println(
        tutoringService.askQuestion(session1,
                "Can you explain the water cycle?"));
System.out.println(
        tutoringService.askQuestion(session1,
                "What is the Pythagorean theorem?"));

// Session 2: Ask two different general knowledge questions
System.out.println("Session 2 → General tutoring questions");
System.out.println(
        tutoringService.askQuestion(session2,
                "How does photosynthesis work?"));
System.out.println(
        tutoringService.askQuestion(session2,
                "What are Newton's three laws of motion?"));

// Exit the application after demonstration
SpringApplication.exit(ctx, () -> 0);

Sample Output:

Session 1 → General tutoring questions
The water cycle describes how water moves through the environment, including processes like evaporation, condensation, precipitation, and collection.
The Pythagorean theorem states that in a right triangle, the square of the hypotenuse equals the sum of the squares of the other two sides: a² + b² = c².
Session 2 → General tutoring questions
Photosynthesis is the process by which plants convert sunlight, carbon dioxide, and water into glucose and oxygen, providing energy for growth.
Newton's three laws of motion describe the relationship between a body and the forces acting on it, explaining how objects move and interact.

This setup ensures that each session's memory is kept separate, allowing multiple conversations to run in parallel without sharing context. It’s a reliable way to provide accurate, personalized answers to different users or topics independently.

Summary and Preparation for Practice

In this lesson, you learned how to manage multiple tutoring sessions using the Spring AI framework. We refactored ChatService into a more flexible TutoringService, introduced session-specific memory using unique identifiers, and demonstrated how to handle multiple conversations independently. These capabilities are essential when building intelligent educational tools that need to keep track of multiple learners at once.

As you move on to the practice exercises, try creating and managing separate tutoring sessions on your own. This hands-on experience will help solidify your understanding and prepare you to build more advanced and responsive educational assistants. Keep going—you’re on your way to building a fully personalized tutor with Spring AI!

Sign up

Join the 1M+ learners on CodeSignal

Be a part of our community of 1M+ users who develop and demonstrate their skills on CodeSignal