The SupervisorAgent
is an advanced orchestration component that enables sophisticated multi-agent coordination within the Multi-Agent Orchestrator framework.
It implements a unique “agent-as-tools” architecture where team members are exposed to a supervisor agent as invocable tools, enabling parallel processing and contextual communication.
The diagram below illustrates the SupervisorAgent architecture, featuring a Lead Agent that coordinates with a team of specialized agents (A, B, and C). Two memory components—User-Supervisor Memory and Supervisor-Team Memory—support the interactions, enabling efficient information flow and conversation history management throughout the system.
Usage Patterns
The SupervisorAgent can be used in two primary ways:
1. Direct Usage
You can use the SupervisorAgent directly, bypassing the classifier, when you want dedicated team coordination for specific tasks:
// Create and configure SupervisorAgent
const supervisorAgent = new SupervisorAgent ( {
leadAgent: new BedrockLLMAgent ( {
name: " Support Team Lead " ,
description: " Coordinates support inquiries "
description: " Handles travel bookings " ,
description: " Handles payment issues " ,
agentId: " payment-agent-id " ,
const response = await supervisorAgent . processRequest (
" I need to modify my flight and check my refund status " ,
# Create and configure SupervisorAgent
supervisor_agent = SupervisorAgent ( SupervisorAgentOptions (
lead_agent = BedrockLLMAgent ( BedrockLLMAgentOptions (
name = " Support Team Lead " ,
description = " Coordinates support inquiries "
LexBotAgent ( LexBotAgentOptions (
description = " Handles travel bookings " ,
BedrockAgent ( BedrockAgentOptions (
description = " Handles payment issues " ,
agent_id = " payment-agent-id " ,
agent_alias_id = " alias-id "
response = await supervisor_agent. process_request (
" I need to modify my flight and check my refund status " ,
Here’s a diagram illustrating the code implementation above, showing how the BedrockLLMAgent (Lead Agent) processes the user’s flight modification request by coordinating with LexBotAgent and Amazon BedrockAgent, supported by dual memory systems for maintaining conversation context.
2. As Part of Classifier-Based Architecture
The SupervisorAgent can also be integrated into a larger system using the classifier, enabling complex hierarchical architectures:
const orchestrator = new MultiAgentOrchestrator ();
orchestrator . addAgent ( new BedrockLLMAgent ({
name: " General Assistant " ,
description: " Handles general inquiries "
// Add a SupervisorAgent for complex support tasks
orchestrator . addAgent ( new SupervisorAgent ({
leadAgent: new BedrockLLMAgent ({
description: " Coordinates support inquiries requiring multiple specialists "
team: [techAgent, billingAgent, lexBookingBot]
// Add another SupervisorAgent for product development
orchestrator . addAgent ( new SupervisorAgent ({
leadAgent: new AnthropicAgent ({
description: " Coordinates product development and feature requests "
team: [designAgent, engineeringAgent, productManagerAgent]
// Process through classifier
const response = await orchestrator . routeRequest (
orchestrator = MultiAgentOrchestrator ()
orchestrator. add_agent ( BedrockLLMAgent ( BedrockLLMAgentOptions (
name = " General Assistant " ,
description = " Handles general inquiries "
# Add a SupervisorAgent for complex support tasks
orchestrator. add_agent ( SupervisorAgent ( SupervisorAgentOptions (
lead_agent = BedrockLLMAgent ( BedrockLLMAgentOptions (
description = " Coordinates support inquiries requiring multiple specialists "
team = [ tech_agent, billing_agent, lex_booking_bot ]
# Add another SupervisorAgent for product development
orchestrator. add_agent ( SupervisorAgent ( SupervisorAgentOptions (
lead_agent = AnthropicAgent ( AnthropicAgentOptions (
description = " Coordinates product development and feature requests "
team = [ design_agent, engineering_agent, product_manager_agent ]
# Process through classifier
response = await orchestrator. route_request (
Here’s a diagram illustrating the code implementation above, showing a Classifier that routes user requests to appropriate teams. Three specialized units are shown: a General Assistant, a Support Team (handling tech, billing, and booking), and a Product Team (comprising design, engineering, and product management agents). Each team uses different agent types (BedrockLLMAgent, LexBotAgent, AnthropicAgent, AmazonBedrockAgent) based on their specific functions.
This flexibility allows you to:
Use SupervisorAgent directly for dedicated team coordination
Integrate it into classifier-based systems for dynamic routing
Create hierarchical structures with multiple specialized teams
Mix different types of agents (LexBot, Bedrock, Anthropic, etc.) in teams
Scale and adapt the architecture as needs evolve
Core Components
1. Supervisor (Lead Agent)
Must be either a BedrockLLMAgent or AnthropicAgent
Acts as the central coordinator
Communicates with team members through a tool interface
Maintains conversation context with both user and team members
2. Team Members
Collection of agents - each agent is wrapped as a tool for the supervisor
Can be any agent type supported by the framework
Operate independently and in parallel when possible
Memory Architecture
The SupervisorAgent implements a sophisticated three-tier memory system to maintain context across conversations:
1. User-Supervisor Memory
This is like the main conversation between a customer and the team leader:
User: I'm having trouble with my billing and the mobile app isn't working
Assistant: I understand you're having two issues. Let me help you with both your billing and app problems.
User: Yes, the app crashes when I try to view my bill
Assistant: I'll look into both issues. Let me check with our technical and billing teams.
2. Supervisor-Team Memory
Each team member maintains a private conversation with the supervisor:
# Tech Support Conversation
Supervisor: User is experiencing app crashes when viewing bills. Can you investigate?
Tech Support: Based on the symptoms, this might be a cache issue. I'll provide steps to clear it.
# Billing Team Conversation
Supervisor: Please check the user's billing status
Billing Team: Account is active, last payment received Jan 15, next due Feb 15
3. Combined Memory
The supervisor keeps track of all important information in an organized way:
User: I'm having trouble with the mobile app, what should I do?
Assistant: [Tech Support] The app crash is likely due to corrupted cache. Please ask the user to clear the app cache.
User: What is the status of my bills?
Assistant: [Billing Team] Account status is good. Last payment: Jan 15, Next due: Feb 15
Memory Processing Flow
Here’s a complete interaction showing how memory and communication work together:
Initial Request
User: I'm having trouble with my bill and the mobile app
Parallel Processing
# Supervisor communicates simultaneously with both teams
Supervisor → Tech Support: What could cause app issues when viewing bills?
Supervisor → Billing: Please verify account status
Team Responses
Tech Support → Supervisor: Likely a cache issue. Common after recent updates.
Billing → Supervisor: Account in good standing, no payment issues.
Unified Response
Supervisor → User: I've checked both issues. Your billing account is in good standing. For the app problem, it appears to be a cache issue. Would you like me to guide you through clearing your app's cache?
Configuration
Configuration Options
interface SupervisorAgentOptions extends AgentOptions {
leadAgent : BedrockLLMAgent | AnthropicAgent ; // The agent that leads the team coordination
team : Agent []; // Team of agents to coordinate
storage ?: ChatStorage ; // Memory storage implementation
trace ?: boolean ; // Enable detailed logging
extraTools ?: AgentTools | AgentTool []; // Additional tools for supervisor
class SupervisorAgentOptions ( AgentOptions ):
lead_agent: Agent # The agent that leads the team coordination
team: list[Agent] # Team of agents that can help in resolving tasks
storage: Optional[ChatStorage] # Memory storage for the team
trace: Optional[ bool ] # Enable tracing/logging
extra_tools: Optional[Union[AgentTools, list[AgentTool]]] # Additional tools for supervisor
Required Parameters
leadAgent
/lead_agent
: Must be either a BedrockLLMAgent or AnthropicAgent instance
team
: List of agents that will be coordinated by the supervisor
Optional Parameters
storage
: Custom storage implementation for conversation history (defaults to InMemoryChatStorage)
trace
: Enable detailed logging of agent interactions
extraTools
/extra_tools
: Additional tools to be made available to the supervisor
The SupervisorAgent includes a built-in tool for parallel message processing:
"description" : " Send messages to multiple agents in parallel. " ,
"description" : " Agent name to send message to. "
"description" : " Message content. "
"required" : [ " recipient " , " content " ]
"description" : " Array of messages for different agents. " ,
name: " analyze_sentiment " ,
description: " Analyze message sentiment " ,
description: " Text to analyze "
const supervisorAgent = new SupervisorAgent ( {
team: [techAgent, billingAgent] ,
name = " analyze_sentiment " ,
description = " Analyze message sentiment " ,
" description " : " Text to analyze "
supervisor_agent = SupervisorAgent ( SupervisorAgentOptions (
team = [ tech_agent, billing_agent ],
Communication Guidelines
Response Handling
Aggregates responses from all relevant agents
Maintains original agent responses without summarization
Provides final answers only when all necessary responses are received
Agent Interaction
Optimizes for parallel processing when possible
Maintains agent isolation (agents are unaware of each other)
Keeps inter-agent communications concise
Context Management
Provides full context when necessary
Reuses previous responses when appropriate
Maintains efficient conversation history
Input Processing
Forwards simple inputs directly to relevant agents
Extracts all relevant data before creating action plans
Never assumes parameter values
Best Practices
Agent Team Composition
Choose specialized agents with clear, distinct roles
Ensure agent descriptions are detailed and non-overlapping
Consider communication patterns when selecting team size
Storage Configuration
Use persistent storage (e.g., DynamoDBChatStorage) for production
Consider memory usage with large conversation histories
Implement appropriate cleanup strategies
Tool Management
Add custom tools through extraTools/extra_tools parameter
Keep tool functions focused and well-documented
Consider performance impact of tool complexity
Performance Optimization
Performance Optimization
Enable parallel processing where appropriate
Monitor and adjust team size based on requirements
Use tracing to identify bottlenecks
Configure memory storage based on expected conversation volumes
Complete Example
Here’s a complete example showing how to use the SupervisorAgent in a typical scenario:
} from ' multi-agent-orchestrator ' ;
// Function to analyze sentiment (implementation would go here)
async function analyzeSentiment ( text : string ) : Promise <{ sentiment : string ; score : number }> {
const orchestrator = new MultiAgentOrchestrator ();
// Create supervisor (lead agent)
const supervisor = new BedrockLLMAgent ( {
description: " Coordinates specialized team members " ,
modelId: " anthropic.claude-3-sonnet-20240229-v1:0 "
const techAgent = new BedrockLLMAgent ( {
description: " Handles technical issues " ,
modelId: " anthropic.claude-3-sonnet-20240229-v1:0 "
const billingAgent = new BedrockLLMAgent ( {
description: " Handles billing and payment queries " ,
modelId: " anthropic.claude-3-sonnet-20240229-v1:0 "
name: " analyze_sentiment " ,
description: " Analyze message sentiment " ,
description: " Text to analyze "
// Create SupervisorAgent
const supervisorAgent = new SupervisorAgent ( {
team: [techAgent , billingAgent] ,
storage: new DynamoDBChatStorage ( " conversation-table " , " us-east-1 " ) ,
extraTools: new AgentTools (customTools)
// Add supervisor agent to orchestrator
orchestrator . addAgent (supervisorAgent);
const response = await orchestrator . routeRequest (
" I'm having issues with my bill and the mobile app " ,
// Handle the response (streaming or non-streaming)
if (response . streaming ) {
console . log ( " \n ** STREAMING RESPONSE ** " );
console . log ( ` Agent: ${ response . metadata . agentName } ` );
// Handle streaming response
for await ( const chunk of response . output ) {
process . stdout . write (chunk);
console . log ( " \n ** RESPONSE ** " );
console . log ( ` Agent: ${ response . metadata . agentName } ` );
console . log ( ` Response: ${ response . output } ` );
console . error ( " Error processing request: " , error);
main () . catch (console . error );
from multi_agent_orchestrator.orchestrator import MultiAgentOrchestrator
from multi_agent_orchestrator.agents import (
from multi_agent_orchestrator.storage import DynamoDBChatStorage
from multi_agent_orchestrator.utils import AgentTool, AgentTools
orchestrator = MultiAgentOrchestrator ()
# Create supervisor and team
supervisor = BedrockLLMAgent ( BedrockLLMAgentOptions (
description = " Coordinates specialized team members "
tech_agent = BedrockLLMAgent ( BedrockLLMAgentOptions (
description = " Handles technical issues "
billing_agent = BedrockLLMAgent ( BedrockLLMAgentOptions (
description = " Handles billing and payment queries "
name = " analyze_sentiment " ,
description = " Analyze message sentiment " ,
" description " : " Text to analyze "
# Create and add supervisor agent
supervisor_agent = SupervisorAgent ( SupervisorAgentOptions (
team = [ tech_agent, billing_agent ],
storage = DynamoDBChatStorage () ,
orchestrator. add_agent ( supervisor_agent )
response = await orchestrator. route_request (
" I'm having issues with my bill and the mobile app " ,
# Handle response based on whether it's streaming or not
print ( " \n ** STREAMING RESPONSE ** " )
print ( f "Agent: {response.metadata.agent_name} " )
async for chunk in response.output:
print ( chunk , end = '' , flush = True )
print ( " \n ** RESPONSE ** " )
print ( f "Agent: {response.metadata.agent_name} " )
print ( f "Response: {response.output} " )
if __name__ == " __main__ " :
Limitations
LeadAgent must be either BedrockLLMAgent or AnthropicAgent
May require significant memory for large conversation histories
Performance depends on slowest agent in parallel operations
By leveraging the SupervisorAgent, you can create sophisticated multi-agent systems with coordinated responses, maintained context, and efficient parallel processing. The agent’s flexible architecture allows for customization while providing robust built-in capabilities for common coordination tasks.