Give Your AI Agents Long-Term Memory: Amazon Bedrock AgentCore Memory in Action
Part 2 of the AgentCore Series
π»πͺπ¨π± Dev.to LinkedIn GitHub Twitter Instagram YouTube
π§ The Cross-Session Memory Problem
You deployed your first production AI agent with AgentCore Runtime. It works perfectly within conversations.
AgentCore Runtime already provides short-term memory - your agent remembers context within the same session (up to 8 hours or 15 minutes of inactivity).
But here's what happens when users return:
- New session starts β Agent forgets everything π€
- User preferences lost β No personalization between visits π€¦ββοΈ
- Previous insights gone β Every interaction starts from zero π
- No learning across sessions β Same questions answered repeatedly π
Your agent has cross-session amnesia. Each new session ID means starting over, even for the same user ID.
Amazon Bedrock AgentCore Memory solves this. Your agents remember users across sessions, learn from past interactions, and provide personalized experiences that persist beyond session boundaries.
This tutorial shows you how to add long-term memory to your agents.
π§ Memory Architecture Explained
AgentCore Runtime (Built-in)
- Session memory - Context within conversations (automatic)
- Container persistence - Up to 8 hours or 15 minutes inactivity
- Same session ID - Full conversation history maintained
AgentCore Memory (This Tutorial)
- Cross-session persistence - Remember across different session IDs
- Long-term extraction - Key insights stored automatically
- User-centric storage - Same user ID, different sessions
- Intelligent retrieval - Relevant context when needed
AgentCore Services Overview
| Service | Purpose | Memory Features |
|---|---|---|
| β AgentCore Runtime | Serverless execution | Built-in session memory, Container isolation |
| β AgentCore Memory | Cross-session persistence | Long-term insights, User preferences |
| AgentCore Identity | Credential management | API keys, OAuth tokens |
| AgentCore Code Interpreter | Code execution | Secure sandbox, Data analysis |
| AgentCore Browser | Web interaction | Cloud browser automation |
| AgentCore Gateway | API management | Tool discovery, Service integration |
| AgentCore Observability | Monitoring | Tracing, Dashboards, Debugging |
β This tutorial: Memory service adds cross-session intelligence to Runtime's built-in session memory.
Prerequisites
Before you begin, verify that you have:
- AWS Account with appropriate permissions
- Python 3.10+ environment
- AWS CLI configured with
aws configure
New AWS customers receive up to $200 in credits
Start at no cost with AWS Free Tier. Get $100 USD at sign-up plus $100 USD more exploring key services.
Let's add cross-session memory to your agents. π§
Tutorial Roadmap:
Setup βοΈ β Code Agent π» β Test Memory β
β Deploy π β Validate π
Estimated time: 15 minutes
git clone https://github.com/aws-samples/sample-getting-started-with-amazon-agentcore
cd 02-agentcore-memory
Install Dependencies
pip install -r requirements.txt
Required packages:
bedrock-agentcore
strands-agents
strands-agents-tools
aws-opentelemetry-distro
Agent Implementation with Cross-Session Memory
Memory Configuration and Agent Creation
"""
Production-Ready AI Agent with Memory
Remembers conversations and user preferences across sessions
"""
import os
from strands import Agent
from strands_tools import calculator
from bedrock_agentcore.runtime import BedrockAgentCoreApp
from bedrock_agentcore.memory.integrations.strands.config import AgentCoreMemoryConfig, RetrievalConfig
from bedrock_agentcore.memory.integrations.strands.session_manager import AgentCoreMemorySessionManager
app = BedrockAgentCoreApp()
MEMORY_ID = os.getenv("BEDROCK_AGENTCORE_MEMORY_ID")
REGION = os.getenv("AWS_REGION", "us-west-2")
MODEL_ID = os.getenv("MODEL_ID", "us.anthropic.claude-3-7-sonnet-20250219-v1:0")
# HTTP headers are normalized to lowercase
CUSTOM_HEADER_NAME = 'x-amzn-bedrock-agentcore-runtime-custom-actor-id'
# Global agent instance
_agent = None
def get_or_create_agent(actor_id: str, session_id: str) -> Agent:
"""
Get existing agent or create new one with memory configuration.
Since the container is pinned to the session ID, we only need one agent per container.
"""
global _agent
if _agent is None:
# Configure memory with retrieval for user facts and preferences
memory_config = AgentCoreMemoryConfig(
memory_id=MEMORY_ID,
session_id=session_id,
actor_id=actor_id,
retrieval_config={
f"/users/{actor_id}/facts": RetrievalConfig(top_k=3, relevance_score=0.5),
f"/users/{actor_id}/preferences": RetrievalConfig(top_k=3, relevance_score=0.5)
}
)
# Create agent with memory session manager
_agent = Agent(
model=MODEL_ID,
session_manager=AgentCoreMemorySessionManager(memory_config, REGION),
system_prompt="You are a helpful assistant with memory. Remember user preferences and facts across conversations. Use the calculate tool for math problems.",
tools=[calculator]
)
return _agent
AgentCore Entry Point
from bedrock_agentcore import BedrockAgentCoreApp, RequestContext
@app.entrypoint
def invoke(payload, context: RequestContext):
"""AgentCore Runtime entry point with lazy-loaded agent"""
if not MEMORY_ID:
return {"error": "Memory not configured..."}
# Extract actor_id from custom header (HTTP headers are lowercase)
actor_id = 'default-user'
if context and hasattr(context, 'request_headers') and context.request_headers:
actor_id = context.request_headers.get(
'x-amzn-bedrock-agentcore-runtime-custom-actor-id',
'default-user'
)
session_id = context.session_id if context else 'default-session'
agent = get_or_create_agent(actor_id, session_id)
prompt = payload.get("prompt", "Hello!")
result = agent(prompt)
return {"response": result.message.get('content', [{}])[0].get('text', str(result))}
Memory Strategies
AgentCore Memory provides three built-in strategies for different use cases:
User Preferences Strategy
Automatically identifies and extracts user preferences, choices, and styles from conversations. This creates a persistent profile of each user for personalized interactions.
Example: An e-commerce agent remembers a user's favorite brands and preferred size, offering tailored product recommendations in future sessions.
Semantic Strategy
Identifies and extracts key factual information and contextual knowledge from conversations. This builds a persistent knowledge base about important entities, events, and details.
Example: A customer support agent remembers that order #ABC-123 relates to a specific support ticket, so you don't need to provide the order number again.
Session Summaries Strategy
Creates condensed, running summaries of conversations within a single session. This captures key topics and decisions for quick context recall.
Example: After a 30-minute troubleshooting session, the agent accesses a summary: "User reported issue with software v2.1, attempted a restart, and was provided a link to the knowledge base article."
For advanced use cases, you can configure custom strategies with overrides to fine-tune memory extraction with your own prompts and foundation models.
Deploy with Cross-Session Memory
Deploy your memory-enabled agent:
Configure Agent
agentcore configure -e my_agent_memory.py
Select 'yes' for memory when prompted
Select 'yes' for long-term memory extraction
Custom Header Configuration
During configuration, select YES for Request Header Allow list and add:
X-Amzn-Bedrock-AgentCore-Runtime-Custom-Actor-Id
This header allows passing a user identifier to namespace memory per user. The agent extracts it from context.request_headers (normalized to lowercase).
Launch to Production
agentcore launch
AgentCore automatically:
- Creates cross-session memory store
- Configures long-term extraction pipelines
- Sets up user-centric persistence
- Provides production endpoint
Test Cross-Session Memory in Production
Session ID Requirements
Session IDs must be at least 33 characters long for proper session management.
Custom Headers for User Identification
Long-term memory requires passing a user identifier via custom headers using boto3 event handlers. This enables memory to be namespaced per user across different sessions.
Short-term Memory Test (Same Session)
import json
import uuid
import boto3
import os
import sys
def test_short_memory(agent_arn, region=None):
"""Test short-term memory within a single session"""
# Extract region from ARN if not provided
if not region:
region = agent_arn.split(':')[3]
# Initialize client
client = boto3.client('bedrock-agentcore', region_name=region)
# Generate session ID
session_id = str(uuid.uuid4())
print(f"Testing short-term memory in session: {session_id}")
print(f"Region: {region}")
print("-" * 50)
try:
# First message - establish context
print("Message 1: Setting context...")
payload1 = json.dumps({"prompt": "My name is Alice and I like chocolate ice cream"}).encode()
response1 = client.invoke_agent_runtime(
agentRuntimeArn=agent_arn,
runtimeSessionId=session_id,
payload=payload1,
qualifier="DEFAULT"
)
content1 = []
for chunk in response1.get("response", []):
content1.append(chunk.decode('utf-8'))
result1 = json.loads(''.join(content1))
print(f"Agent: {result1.get('response', 'No response')}")
print()
# Second message - test memory recall
print("Message 2: Testing memory recall...")
payload2 = json.dumps({"prompt": "What is my name and what do I like?"}).encode()
response2 = client.invoke_agent_runtime(
agentRuntimeArn=agent_arn,
runtimeSessionId=session_id, # Same session
payload=payload2,
qualifier="DEFAULT"
)
content2 = []
for chunk in response2.get("response", []):
content2.append(chunk.decode('utf-8'))
result2 = json.loads(''.join(content2))
print(f"Agent: {result2.get('response', 'No response')}")
print("\nβ Short-term memory test completed")
except Exception as e:
print(f"Error: {e}")
import traceback
traceback.print_exc()
Run the test:
python test_short_memory.py "AGENT_ARN"
Long-term Memory Test (Different Sessions)
Important: Long-term memory extraction is an asynchronous background process that can take a minute or more. For production testing, you may need to wait several minutes between storing and retrieving long-term memories.
import json
import uuid
import boto3
import os
import sys
import time
def test_long_memory(agent_arn, region=None):
"""Test long-term memory across different sessions"""
if not region:
region = agent_arn.split(':')[3]
client = boto3.client('bedrock-agentcore', region_name=region)
event_system = client.meta.events
session_1 = str(uuid.uuid4())
session_2 = str(uuid.uuid4())
user_1 = f"user-{str(uuid.uuid4())[:8]}"
# Constants for event handler
EVENT_NAME = 'before-sign.bedrock-agentcore.InvokeAgentRuntime'
CUSTOM_HEADER_NAME = 'X-Amzn-Bedrock-AgentCore-Runtime-Custom-Actor-Id'
def add_custom_runtime_header(request, **kwargs):
"""Add custom header for user identification."""
request.headers.add_header(CUSTOM_HEADER_NAME, user_1)
try:
# Register event handler
handler = event_system.register_first(EVENT_NAME, add_custom_runtime_header)
# Session 1: Store user information
print(f"User: {user_1}")
print(f"Session 1: {session_1}")
# ... rest of code
# Wait for long-term memory extraction
print("β³ Waiting 10 seconds for long-term memory extraction...")
print("Note: Long-term memory is an asynchronous process that can take a minute or more.")
time.sleep(10)
# Session 2: Test memory recall
# ... rest of code
# Unregister event handler
event_system.unregister(EVENT_NAME, handler)
Run the test:
python test_long_memory.py "AGENT_ARN"
# Or using environment variables
export AGENT_ARN="your-agent-arn"
python test_long_memory.py
This test verifies AgentCore Memory's cross-session persistence:
- Stores user preferences in session 1
- Waits 25 seconds for long-term memory extraction
- Tests recall in different session 2 (same user ID)
- Verifies cross-session memory works
Memory Management Operations
AgentCore Memory provides comprehensive management capabilities:
- Save and retrieve insights - Store and access extracted knowledge
- Retrieve memory records - Access specific memory entries
- List memory records - Browse stored memories
- Delete memory records - Remove outdated information
Memory Architecture Benefits
| Runtime Only | Runtime + AgentCore Memory |
|---|---|
| β Session context (8 hours) | β Session context (8 hours) |
| β Lost after session ends | β Persistent across sessions |
| β No user learning | β User preferences remembered |
| β Repeat information | β Intelligent context retrieval |
| β Generic responses | β Personalized interactions |
Key Cross-Session Features
- User persistence - Same user ID, different session IDs remembered
- Automatic extraction - Key insights stored during conversations
- Intelligent retrieval - Relevant past context when needed
- Preference learning - User choices persist across visits
- Scalable architecture - Fully managed cross-session service
The invoke Function
The invoke function is the main entry point for your AgentCore agent. It:
- Receives user prompts and context from AgentCore Runtime
- Extracts session and actor IDs for memory management
- Creates or retrieves the agent instance with memory configuration
- Processes the user message and returns the response
@app.entrypoint
def invoke(payload, context):
"""AgentCore Runtime entry point with lazy-loaded agent"""
# Extract user prompt
prompt = payload.get("prompt", "Hello!")
# Get session/actor info for memory
actor_id = context.request_headers.get('X-Amzn-Bedrock-AgentCore-Runtime-Custom-Actor-Id', 'user') if context.request_headers else 'user'
session_id = context.session_id or 'default_session'
# Get agent with memory
agent = get_or_create_agent(actor_id, session_id)
# Process and return response
result = agent(prompt)
return {"response": result.message.get('content', [{}])[0].get('text', str(result))}
Clean Up
Remove all resources:
agentcore destroy
This removes AgentCore deployment, memory stores, ECR repository, IAM roles, and CloudWatch logs.
π You Just Built Cross-Session Memory AI Agents!
Your agents now remember users across sessions, learn from past interactions, and provide personalized experiences that persist beyond session boundaries. What intelligent applications will you build? π
β€οΈ If This Helped You
β€οΈ Heart it - helps others discover this tutorial
π¦ Unicorn it - if it blew your mind
π Bookmark it - for when you need it later
π€ Share it - with your team or on social media
π Resources
- Turn Your AI Script into a Production-Ready Agent
- My Amazon Bedrock AgentCore code sample
- Amazon Bedrock AgentCore Samples
- Amazon Bedrock AgentCore Memory Documentation
- Long-term Memory Configuration
- Built-in Memory Strategies
- Custom Memory Strategies
- AgentCore Memory SDK Python
AWS Free Tier:
- Get started with AWS Free Tier - Up to $200 in credits for new customers
My Other Tutorials:
Happy building! π
Β‘Gracias!
π»πͺπ¨π± Dev.to LinkedIn GitHub Twitter Instagram YouTube
Top comments (7)
Tremendo
totally agree
awesome!!!
Absolutely
This is a fantastic, hands-on walkthrough for solving one of the biggest pain points with AI agents
Awesome guide on AgentCore Memory! The breakdown of the cross-session amnesia problem and the clear Session vs. Cross-Session memory architecture is fantastic.
Some comments may only be visible to logged-in visitors. Sign in to view all comments.