Skip to main content

Sessions & State in AWS Strands

In this lesson, you’ll learn how to give your agent a memory. By default, an agent is stateless—it forgets everything after providing a response. Session management allows an agent to remember past interactions, maintain context, and have more natural, ongoing conversations. We’ll use a FileSessionManager to automatically save and load the conversation history to your local computer.

Why Session Management Matters

Conversational Context

Remember previous messages in a conversation

User Preferences

Recall user information and preferences

Task Continuity

Resume multi-step tasks across interactions

Natural Interactions

Enable more human-like, context-aware responses

Key Concepts

1. FileSessionManager

This component handles the agent’s memory. We create an instance with two key parameters:
  • session_id: A unique string that identifies a specific conversation. You can have many different sessions, each with its own memory.
  • storage_dir: The folder on your computer where the conversation history will be saved as JSON files.

2. Agent with Memory

We simply pass the session_manager instance to the Agent constructor. The agent automatically:
  • Saves every message (both user and assistant)
  • Loads the history every time it’s called with the same session_id

3. Conversational Context

Because the agent loads the previous messages, it has the full context of the conversation. When the user asks “Do you remember my name?”, the agent can look back at the history and provide the correct answer.

4. How It Works Under the Hood

The FileSessionManager creates a folder for each session_id. Inside that folder, it saves each message in the conversation as a separate JSON file. When you create an agent with an existing session_id, the manager loads all those JSON files to reconstruct the conversation history.

Implementation

Step 1: Import Dependencies

import os
from pathlib import Path
from dotenv import load_dotenv
from strands import Agent
from strands.models.litellm import LiteLLMModel
from strands.session.file_session_manager import FileSessionManager

# Load environment variables from a .env file
load_dotenv()

Step 2: Create a Persistent Agent

def create_persistent_agent(session_id: str) -> Agent:
    """
    Creates an agent with persistent memory using a FileSessionManager.
    
    Args:
        session_id: A unique identifier for the conversation session.
    
    Returns:
        An Agent instance that can remember past interactions.
    """
    # Configure the language model
    model = LiteLLMModel(
        client_args={"api_key": os.getenv("NEBIUS_API_KEY")},
        model_id="nebius/deepseek-ai/DeepSeek-V3-0324",
    )
    
    # Set up the directory to store session files
    base_dir = Path(__file__).parent.resolve()
    storage_dir = base_dir / "tmp" / "sessions"
    print(f"Session files will be stored in: {storage_dir}")
    
    # Create a FileSessionManager to handle saving and loading the conversation
    session_manager = FileSessionManager(
        session_id=session_id,
        storage_dir=str(storage_dir),
    )
    
    # Create an agent and attach the session manager
    # This agent will now have memory!
    persistent_agent = Agent(
        model=model,
        session_manager=session_manager,
        system_prompt="You are a friendly assistant. Keep your responses concise."
    )
    return persistent_agent
The session_id is crucial—it’s how the agent knows which conversation history to load. Use descriptive IDs like user_123_chat or project_brainstorm_session.

Step 3: Use the Agent in a Conversation

def main():
    """
    Main function to demonstrate a conversational agent with memory.
    """
    # Each session ID represents a unique conversation history
    session_id = "user_arindam_convo_123"
    agent = create_persistent_agent(session_id)
    
    print("--- Conversation Start ---")
    
    # First interaction: The user introduces themselves
    print("\nUser: Hey, my name is Arindam.")
    response1 = agent("Hey, my name is Arindam.")
    print(f"Agent: {response1}")
    
    # Second interaction: Ask the agent if it remembers the name
    print("\nUser: Do you remember my name?")
    response2 = agent("Do you remember my name?")
    print(f"Agent: {response2}")
    
    print("\n--- Conversation End ---")
    print(f"\nThe agent was able to remember the name because its memory is persisted in the session '{session_id}'.")

if __name__ == "__main__":
    main()

Running the Example

1

Set up environment

Create a .env file with your API key:
NEBIUS_API_KEY=your_api_key_here
2

Install dependencies

pip install strands python-dotenv
3

Run the script

python main.py

Expected Output

Session files will be stored in: /path/to/tmp/sessions
--- Conversation Start ---

User: Hey, my name is Arindam.
Agent: Hello Arindam! Nice to meet you. How can I help you today?

User: Do you remember my name?
Agent: Yes, of course! Your name is Arindam.

--- Conversation End ---

The agent was able to remember the name because its memory is persisted 
in the session 'user_arindam_convo_123'.
The agent successfully recalls the user’s name from the previous message because the session manager loaded the conversation history!

Session Storage Structure

When you run the example, the FileSessionManager creates a directory structure like this:
tmp/
└── sessions/
    └── user_arindam_convo_123/
        ├── message_001.json
        ├── message_002.json
        ├── message_003.json
        └── message_004.json
Each JSON file contains a message in the conversation, including:
  • Role (user or assistant)
  • Content (the actual message text)
  • Timestamp
  • Metadata

Try It Yourself

Create multiple sessions with different session IDs:
# Session 1: Planning a trip
agent1 = create_persistent_agent("trip_planning_session")
agent1("I want to visit Japan in the spring")

# Session 2: Learning Python
agent2 = create_persistent_agent("python_learning_session")
agent2("I'm learning Python. Can you help me?")

# Later, resume session 1
agent1_resumed = create_persistent_agent("trip_planning_session")
agent1_resumed("What did we discuss about Japan?")
# Agent remembers the trip planning conversation!
Test the agent’s memory over many interactions:
agent = create_persistent_agent("long_conversation")

# Message 1: Share information
agent("My favorite color is blue.")

# Message 2: More information
agent("I work as a software engineer.")

# Message 3: Even more
agent("I have a dog named Max.")

# Message 4: Test memory
response = agent("What do you know about me?")
print(response)  # Should recall color, job, and dog!
Delete the session directory to start fresh:
import shutil
from pathlib import Path

# Delete all sessions
storage_dir = Path("./tmp/sessions")
if storage_dir.exists():
    shutil.rmtree(storage_dir)
    print("All sessions cleared!")

# Start fresh
agent = create_persistent_agent("new_session")
Store sessions in a different directory:
session_manager = FileSessionManager(
    session_id="custom_session",
    storage_dir="/path/to/my/sessions",  # Custom path
)

Other Session Managers

While this lesson uses FileSessionManager, AWS Strands supports other session managers:

FileSessionManager

Store sessions as JSON files on disk (used in this lesson)

InMemorySessionManager

Store sessions in RAM (lost when program exits)

Custom Managers

Implement your own (e.g., database-backed)

Production Considerations

For production applications, consider:
  • Using a database-backed session manager instead of file storage
  • Implementing session expiration and cleanup
  • Adding user authentication to secure sessions
  • Limiting session history length to control token usage

What You Learned

  • How to use FileSessionManager to give agents memory
  • How to create unique session IDs for different conversations
  • How session storage works under the hood
  • How to maintain conversational context across multiple interactions
  • How to manage multiple independent sessions

Next Steps

Your agent now has memory! But what if you need to extract structured data from unstructured text? In the next lesson, you’ll learn how to use Pydantic models to get structured output from your agent.

Lesson 03: Structured Output

Learn how to extract structured JSON data from natural language using Pydantic

Resources

Video Tutorial

Watch Lesson 02 on YouTube

Strands Documentation

Read the official docs

Build docs developers (and LLMs) love