
Building a Bot: Using Strands SDK to create a League of Legends Agent
Work on building an interactive agent with the Strands SDK. Learn memory management, tool interactions, and other engagement patterns.
Welcome to Day 5 of Challenge #2ย ! Today, you'll move beyond simple RAG queries to create an autonomous agent capable of sophisticated analysis, conversation management, and multi-step reasoning about your League of Legends match data.
What You Will Need
๐ป Your AWS account with Bedrock access
๐ง Your existing Knowledge Base from previous setup
โ๏ธ Python 3.10+ development environment
โฐ About 60 minutes
๐ Basic understanding of Python and AWS services
๐ง Your existing Knowledge Base from previous setup
โ๏ธ Python 3.10+ development environment
โฐ About 60 minutes
๐ Basic understanding of Python and AWS services
What You Will Accomplish Today
โ
Set up the Strands SDK development environment
โ Create an AI agent connected to your Bedrock Knowledge Base
โ Implement custom tools and autonomous behaviors
โ Configure agent memory and conversation handling
โ Deploy your agent with proper monitoring and security
โ Test multi-step analytical workflows
โ Create an AI agent connected to your Bedrock Knowledge Base
โ Implement custom tools and autonomous behaviors
โ Configure agent memory and conversation handling
โ Deploy your agent with proper monitoring and security
โ Test multi-step analytical workflows
Step 1: Understanding Strands Agents ๐ค
What is an AI Agent?
An AI agent is an AI system that can:
- Maintain conversation context and memory
- Use multiple tools and services autonomously
- Make independent decisions based on context
- Execute complex multi-step workflows
- Self-reflect and correct mistakes

Strands Agents is an open source SDK that takes a model-driven approach to building and running AI agents in just a few lines of code . Unlike simple RAG implementations, Strands supports sophisticated patterns including multi-agent orchestration, semantic search for managing thousands of tools, and advanced reasoning capabilities.
Key Features of Strands Agents
Strands Agents includes the following capabilities:
- Model-first design: Built around the concept that the foundation model is the core of agent intelligence, enabling sophisticated autonomous reasoning
- AWS service integration: Seamless connection to Amazon Bedrock, AWS Lambda, AWS Step Functions, and other AWS services
- Foundation model selection: Supports various models including Anthropic Claude, Amazon Nova models on Amazon Bedrock
- Multimodal capabilities: Support for text, speech, and image processing
- Tool ecosystem: Rich set of tools for AWS service interaction with extensibility for custom tools
Step 2: Setting Up Your Development Environment ๐ ๏ธ
Install Required Packages
1
2
pip install strands-agents
pip install boto3Configure AWS Credentials
Ensure your AWS credentials are properly configured with Bedrock access (if working locally)
1
aws configureMake sure your IAM user or execution role has the necessary Bedrock permissions to invoke models and access your Knowledge Base, as well as utilize agent features:
Example IAM Policy:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
{
"Version": "2012-10-17",
"Statement": [
{
"Sid": "BedrockFullAccess",
"Effect": "Allow",
"Action": [
"bedrock:InvokeModel",
"bedrock:InvokeModelWithResponseStream",
"bedrock:Retrieve",
"bedrock:RetrieveAndGenerate",
"bedrock:InvokeAgent",
"bedrock:GetAgent",
"bedrock:ListAgents"
],
"Resource": "*"
},
{
"Sid": "BasicLogging",
"Effect": "Allow",
"Action": [
"logs:CreateLogGroup",
"logs:CreateLogStream",
"logs:PutLogEvents"
],
"Resource": "*"
}
]
}
Step 3: Initialize Your Basic Agent Structure
Create a new Python file
league_analytics_agent.py, or create a new Jupyter notebook in SageMaker Studio:1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
import os
from strands import Agent, tool
from strands.models import BedrockModel
from strands.memory import ConversationMemory
# Configuration - Replace with your actual values
KNOWLEDGE_BASE_ID = "your-kb-id-here" # From Day 4 setup
REGION = "us-east-1" # Your AWS region
MODEL_ID = "anthropic.claude-sonnet-4-20250514-v1:0" #or whatever model you like
# Initialize Bedrock model
model = BedrockModel(
model_id=MODEL_ID,
region_name=REGION,
)
# Create the basic agent
agent = Agent(
model=model,
system_prompt="""You are a League of Legends analytics expert. You have access to match data
through a knowledge base and can perform sophisticated analysis of champion performance,
meta trends, and gameplay patterns. Always provide specific data-driven insights and
cite your sources when making claims about game statistics."""
)Step 4: Adding Knowledge Base Integration Tool
Now let's create a custom tool that integrates with your Bedrock Knowledge Base:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
import boto3
from typing import Dict, Any
# Initialize Bedrock client
bedrock_client = boto3.client('bedrock-agent-runtime', region_name=REGION)
def query_match_data(query: str, max_results: int = 5) -> str:
"""
Query the League of Legends match data knowledge base for specific information.
Args:
query: The question about match data, champion performance, or meta analysis
max_results: Number of relevant documents to retrieve (default: 5)
Returns:
Detailed analysis based on the match data
"""
try:
response = bedrock_client.retrieve_and_generate(
input={'text': query},
retrieveAndGenerateConfiguration={
'type': 'KNOWLEDGE_BASE',
'knowledgeBaseConfiguration': {
'knowledgeBaseId': KNOWLEDGE_BASE_ID,
'modelArn': MODEL_ID,
'retrievalConfiguration': {
'vectorSearchConfiguration': {
'numberOfResults': max_results
}
}
}
}
)
# Extract the generated answer
answer = response.get('output', {}).get('text', '')
# Get source citations for transparency
citations = []
for citation in response.get('citations', []):
for ref in citation.get('retrievedReferences', []):
citations.append({
'content_snippet': ref.get('content', {}).get('text', '')[:200] + '...',
'metadata': ref.get('metadata', {})
})
result = f"Analysis: {answer}\n\nSources: {len(citations)} match data references used"
return result
except Exception as e:
return f"Error querying match data: {str(e)}"
# Add the tool to the agent
agent.tools.append(query_match_data)Step 5: Implementing Advanced Analysis Tools
Let's add specialized tools for different types of League of Legends analysis, specifically, champion-based analysis.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
def analyze_champion_performance(champion_name: str, role: str = None, rank_tier: str = None) -> str:
"""
Analyze detailed performance metrics for a specific champion.
Args:
champion_name: Name of the champion to analyze
role: Specific role/position (optional)
rank_tier: Rank tier to filter by (optional)
Returns:
Comprehensive champion performance analysis
"""
query_parts = [f"champion performance analysis for {champion_name}"]
if role:
query_parts.append(f"in the {role} role")
if rank_tier:
query_parts.append(f"in {rank_tier} ranked games")
query_parts.extend([
"including win rate, KDA ratios, item build success rates,",
"pick rate trends, ban rate, and comparison to other champions in the same role"
])
full_query = " ".join(query_parts)
return query_match_data(full_query, max_results=8)
def analyze_meta_trends(patch_version: str = None, time_period: str = "last 30 days") -> str:
"""
Analyze current meta trends and shifts in champion popularity.
Args:
patch_version: Specific patch to analyze (optional)
time_period: Time period for trend analysis
Returns:
Meta trend analysis with rising/falling champions
"""
query_parts = ["meta trends analysis showing"]
if patch_version:
query_parts.append(f"changes in patch {patch_version}")
else:
query_parts.append(f"trends over the {time_period}")
query_parts.extend([
"including champion pick rate changes, win rate shifts,",
"emerging strategies, item build evolution, and role meta shifts"
])
full_query = " ".join(query_parts)
return query_match_data(full_query, max_results=10)
def compare_team_compositions(comp1_description: str, comp2_description: str) -> str:
"""
Compare the effectiveness of different team compositions.
Args:
comp1_description: Description of first team composition
comp2_description: Description of second team composition
Returns:
Comparative analysis of team composition effectiveness
"""
query = f"""
Compare team composition effectiveness between:
Composition 1: {comp1_description}
Composition 2: {comp2_description}
Include win rates, synergy analysis, power spikes, team fight effectiveness,
objective control, and matchup considerations
"""
return query_match_data(query, max_results=12)
# Add specialized tools to agent
agent.tools.extend([analyze_champion_performance, analyze_meta_trends, compare_team_compositions])Step 6: Configure Memory and Context Management ๐ง
Implement simple but effective memory management using Strands SDK:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
from strands.memory import ConversationMemory
# Configure conversation memory for context retention
memory = ConversationMemory(
memory_size=10, # Keep last 10 exchanges
include_system_messages=True
)
# Update agent with memory capabilities
agent = Agent(
model=model,
memory=memory,
system_prompt="""You are a League of Legends analytics expert with conversation memory.
Remember previous questions and analyses within our conversation to provide contextual responses.
Reference past discussions when relevant and build upon previous insights.""",
tools=[query_match_data, analyze_champion_performance, analyze_meta_trends, compare_team_compositions]
)
# Simple context-aware message handler
async def handle_message_with_memory(message: str):
"""Process messages with conversation context"""
# Get recent conversation for context
recent_messages = agent.memory.get_recent_messages(limit=3)
# Check for follow-up patterns
if any(word in message.lower() for word in ["that champion", "this build", "same", "also"]):
message += " (Reference previous discussion context)"
print(f"Processing query with memory context: {message[:100]}...")
return await agent.process_message(message)Step 7: Adding Agent Behaviors and Error Handling
Configure intelligent behaviors and robust error handling:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
# Add conversation handlers
async def handle_message(message: str):
"""Pre-process user input for better analysis"""
# Log the interaction
print(f"Processing query: {message[:100]}...")
# Enhance queries with context
if "champion" in message.lower() and "vs" in message.lower():
message += " Include matchup statistics and win rate comparisons."
elif "meta" in message.lower():
message += " Focus on recent trends and statistical significance."
return await agent.process_message(message)
async def handle_error(error: Exception):
"""Handle errors gracefully with helpful suggestions"""
error_msg = str(error)
if "knowledge base" in error_msg.lower():
return {
"error": "Unable to access match data",
"suggestion": "Please verify your Knowledge Base is active and try a more specific query"
}
elif "timeout" in error_msg.lower():
return {
"error": "Query took too long to process",
"suggestion": "Try breaking your question into smaller, more focused queries"
}
else:
return {
"error": f"Analysis error: {error_msg}",
"suggestion": "Please rephrase your question or try a different approach"
}Step 8: Testing Your Agent ๐งช
Let's verify everything works with comprehensive testing :
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
async def test_agent():
"""Test the agent with various League of Legends queries"""
test_queries = [
"What are the most successful item builds for Jinx in ranked games?",
"Show me the current meta trends for ADC champions",
"Compare the effectiveness of engage supports versus enchanter supports",
"Which champions have the highest win rate in Diamond+ games?",
"Analyze the performance of Azir in mid lane during the current patch"
]
print("๐งช Testing League Analytics Agent...")
for i, query in enumerate(test_queries, 1):
try:
print(f"\n--- Test {i}: {query} ---")
response = await agent.process_message(query)
print(f"โ
Response: {response[:200]}...")
metrics.log_query(True)
except Exception as e:
print(f"โ Error: {str(e)}")
metrics.log_query(False)
print(f"\n๐ Test Summary: {metrics.successful_queries}/{metrics.query_count} successful")
# Run tests
if __name__ == "__main__":
import asyncio
asyncio.run(test_agent())Checklist โ
Verify you've completed all key components:
- โ Basic agent setup with Bedrock model
- โ Knowledge Base tool integration
- โ Custom analysis tools for League data
- โ Memory management implementation
- โ Comprehensive testing
BONUS OPPORTUNITY: Comment a unique prompt you gave to your agent and what the output was!
Next Steps: Production Deployment ๐
Tomorrow, we'll take your Strands agent from development to a public endpoint. You'll learn how to:
โ
Create a serverless API using API Gateway and Lambda
โ Configure proper authentication and authorization
โ Set up request/response handling for your agent
โ ...and more!
โ Configure proper authentication and authorization
โ Set up request/response handling for your agent
โ ...and more!
This deployment will make your agent accessible via HTTP endpoints, enabling integration with web applications, chat interfaces, or any systems that can make API requests. Happy Hacking!
Enjoyed reading this content? Let the author know!
Your likes, comments, shares, and saves help creators reach more builders.
Loading recommendations
Loading article