Introducing the Stateful Runtime Environment for Agents in Amazon Bedrock
Back to Tutorials
techTutorialintermediate

Introducing the Stateful Runtime Environment for Agents in Amazon Bedrock

February 27, 20262 views4 min read

Learn how to create and deploy a stateful agent using Amazon Bedrock's new runtime environment with persistent memory and orchestration capabilities.

Introduction

In this tutorial, you'll learn how to create and deploy a stateful agent using Amazon Bedrock's new Stateful Runtime Environment. This technology enables persistent orchestration and memory for multi-step AI workflows, allowing agents to maintain context across interactions. We'll build a simple customer service agent that can remember conversation history and provide personalized responses.

Prerequisites

  • Amazon Web Services (AWS) account with appropriate permissions
  • AWS CLI installed and configured
  • Python 3.8 or higher
  • Boto3 library installed (pip install boto3)
  • Basic understanding of AWS Bedrock and AI agents

Step 1: Set Up Your AWS Environment

1.1 Create Required IAM Role

First, we need to create an IAM role that grants Bedrock access to execute our agent. This role will have the necessary permissions to interact with Bedrock and other AWS services.

aws iam create-role \
  --role-name BedrockAgentRole \
  --assume-role-policy-document file://trust-policy.json

The trust policy allows Bedrock to assume this role. You'll need to create a file called trust-policy.json with the following content:

{
  "Version": "2012-10-17",
  "Statement": [
    {
      "Effect": "Allow",
      "Principal": {
        "Service": "bedrock.amazonaws.com"
      },
      "Action": "sts:AssumeRole"
    }
  ]
}

1.2 Attach Required Policies

Next, attach the necessary policies to your role to allow Bedrock to execute agents:

aws iam attach-role-policy \
  --role-name BedrockAgentRole \
  --policy-arn arn:aws:iam::aws:policy/service-role/AWSBedrockExecutionRoleForAgents

Step 2: Create Your Stateful Agent

2.1 Define Agent Configuration

We'll create a basic agent configuration that includes state management capabilities:

import boto3
import json

bedrock_agent = boto3.client('bedrock-agent')

agent_config = {
    "agentName": "CustomerServiceAgent",
    "agentResourceRoleArn": "arn:aws:iam::YOUR_ACCOUNT:role/BedrockAgentRole",
    "autoPrepare": True,
    "idleSessionTTLInSeconds": 3600,
    "description": "Stateful customer service agent with memory",
    "statefulRuntime": True,
    "guardrailConfiguration": {
        "guardrailId": "YOUR_GUARDRAIL_ID",
        "guardrailVersion": "DRAFT"
    }
}

response = bedrock_agent.create_agent(**agent_config)
print(json.dumps(response, indent=2, default=str))

The key parameter here is statefulRuntime: True, which enables the persistent memory capabilities for your agent.

2.2 Create Agent Prompt

Define the agent's behavior and personality through a prompt template:

prompt_template = {
    "name": "CustomerServicePrompt",
    "content": "You are a helpful customer service agent. Remember previous conversations and provide personalized responses. Current conversation context: {context}"
}

response = bedrock_agent.create_prompt(
    agentId=response['agent']['agentId'],
    promptTemplate=prompt_template
)

Step 3: Implement State Management

3.1 Create Knowledge Base

Set up a knowledge base to store customer information and service history:

knowledge_base_config = {
    "name": "CustomerKnowledgeBase",
    "description": "Stores customer information and service history",
    "roleArn": "arn:aws:iam::YOUR_ACCOUNT:role/BedrockAgentRole",
    "vectorStore": {
        "pinecone": {
            "serverless": True,
            "region": "us-east-1"
        }
    }
}

response = bedrock_agent.create_knowledge_base(**knowledge_base_config)
print(json.dumps(response, indent=2, default=str))

This knowledge base will help maintain state by storing conversation history and customer preferences.

3.2 Implement Conversation Memory

Create a simple memory management system for your agent:

def store_conversation_state(agent_id, session_id, conversation_history):
    # Store conversation state in DynamoDB or similar
    dynamodb = boto3.resource('dynamodb')
    table = dynamodb.Table('AgentConversationMemory')
    
    table.put_item(
        Item={
            'agentId': agent_id,
            'sessionId': session_id,
            'conversationHistory': conversation_history,
            'lastUpdated': datetime.utcnow().isoformat()
        }
    )

def retrieve_conversation_state(agent_id, session_id):
    dynamodb = boto3.resource('dynamodb')
    table = dynamodb.Table('AgentConversationMemory')
    
    response = table.get_item(
        Key={
            'agentId': agent_id,
            'sessionId': session_id
        }
    )
    
    return response.get('Item', {}).get('conversationHistory', [])

Step 4: Deploy and Test Your Agent

4.1 Prepare Agent for Deployment

Before deployment, we need to prepare the agent with all necessary components:

prepare_response = bedrock_agent.prepare_agent(
    agentId=response['agent']['agentId']
)
print(json.dumps(prepare_response, indent=2, default=str))

This step ensures all components are ready for execution and that the stateful runtime environment is properly configured.

4.2 Test Agent Interaction

Test your stateful agent with a sample conversation:

def test_agent_interaction(agent_id, session_id, user_input):
    # Send user input to agent
    response = bedrock_agent.invoke_agent(
        agentId=agent_id,
        agentAliasId='DRAFT',
        sessionId=session_id,
        inputText=user_input
    )
    
    # Process the response
    if 'output' in response:
        print(f"Agent Response: {response['output']['text']}")
        
        # Update conversation state
        conversation_history = retrieve_conversation_state(agent_id, session_id)
        conversation_history.append({
            'user': user_input,
            'agent': response['output']['text'],
            'timestamp': datetime.utcnow().isoformat()
        })
        store_conversation_state(agent_id, session_id, conversation_history)
    
    return response

# Test with sample interaction
session_id = 'session-12345'
test_agent_interaction(response['agent']['agentId'], session_id, "Hello, I need help with my order")

This demonstrates how the agent maintains state between interactions, remembering previous conversation context.

Step 5: Monitor and Optimize

5.1 Set Up Monitoring

Implement monitoring to track agent performance and state management:

import boto3
import time

def monitor_agent_performance(agent_id):
    cloudwatch = boto3.client('cloudwatch')
    
    # Get agent metrics
    response = cloudwatch.get_metric_statistics(
        Namespace='AWS/Bedrock',
        MetricName='AgentInvocations',
        StartTime=datetime.utcnow() - timedelta(hours=1),
        EndTime=datetime.utcnow(),
        Period=300,
        Statistics=['Sum', 'Average'],
        Dimensions=[{
            'Name': 'AgentId',
            'Value': agent_id
        }]
    )
    
    return response

5.2 Optimize State Management

Optimize your state management to prevent memory bloat:

def optimize_conversation_memory(conversation_history, max_length=10):
    # Keep only the most recent interactions
    if len(conversation_history) > max_length:
        return conversation_history[-max_length:]
    return conversation_history

This optimization ensures your agent doesn't consume excessive memory while maintaining useful context.

Summary

In this tutorial, you've learned how to create a stateful agent using Amazon Bedrock's new runtime environment. You've set up the required IAM permissions, configured agent state management, and implemented conversation memory. The key advantages of this approach include persistent context across interactions, secure execution, and the ability to maintain long-term conversation state. This foundation allows you to build sophisticated multi-step AI workflows that can remember and respond to user needs across multiple interactions.

Remember to monitor your agent's performance and optimize state management as your agent scales to ensure optimal performance and cost efficiency.

Source: OpenAI Blog

Related Articles