The hierarchical teams pattern
Organize agents into hierarchical layers where managers coordinate work across levels with tag-based routing and shared memory.
Organize agents into hierarchical layers with clear reporting structures. Managers coordinate specialized teams using tag-based routing while sharing knowledge via common resources. Work flows both top-down through delegation and bottom-up through reporting.
When to use this pattern
Section titled “When to use this pattern”The hierarchical teams pattern works when you need to:
- Organize large agent systems with multiple specialized teams (such as engineering, marketing, and operations)
- Maintain clear reporting structures and accountability across layers
- Coordinate work across departments or functional areas
- Scale agent systems beyond flat team structures
- Delegate complex projects that require coordination at multiple levels
Example use case
Section titled “Example use case”An executive agent oversees a product launch with two managers (an engineering manager and a marketing manager). The engineering manager coordinates backend and frontend engineers to build authentication features, while the marketing manager coordinates content writers and designers to create launch materials. The executive delegates strategic goals to managers, managers break down work for specialized workers, and all agents share findings through the common archival memory. Each layer maintains context across sessions while coordinating with the appropriate hierarchy levels.
How it works
Section titled “How it works”The hierarchical teams pattern uses four key components:
- Hierarchical tagging: Agents are tagged by layer (such as
["executive"],["manager", "engineering"],["worker", "engineering", "backend"]) for organization and discovery. - Shared memory blocks: Memory blocks make the coordination state visible across layers (guidelines, priorities, project status).
- Shared archival memory: Agents at all levels contribute findings to a searchable knowledge base.
- Tool rules for cascade prevention: Each hierarchy level has coordination limits that prevent runaway message loops while enabling effective delegation.
Each hierarchy level follows a distinct coordination strategy:
Executives delegate sequentially:
- Process one department at a time to maintain control
- Wait for each department to complete before delegating to the next
- Use precise targeting (
match_all=["manager"]) to message only direct reports, not workers - Higher tool limits (10) accommodate nested delegation flows
Managers delegate in parallel:
- Can coordinate with multiple workers simultaneously
- Provide specific, complete instructions so workers can complete tasks without asking questions
- Moderate tool limits (5) allow multi-worker coordination
- Report completion only after all workers finish
Workers complete immediately:
- Execute tasks with reasonable assumptions when details are unclear
- Store findings in shared archival memory
- Low tool limits (2) for archival operations only, no coordination tools
The pattern’s key feature is controlled multi-layer coordination: Each manager uses the same send_message_to_agents_matching_tags tool to coordinate its team, but with different strategies. An executive delegates sequentially to managers using match_all=["manager"], match_some=["engineering"], who then delegate in parallel to workers using match_all=["worker", "engineering"], match_some=["backend"]. Tool rules at each layer prevent cascade messages where agents continuously respond to each other, consuming excessive tokens.
Implementation
Section titled “Implementation”Implement the hierarchical teams pattern using the following steps.
Step 1: Get the coordination tool
Section titled “Step 1: Get the coordination tool”All coordinating agents (executives and managers) need the send_message_to_agents_matching_tags tool:
from letta_client import Lettaimport os
client = Letta(api_key=os.getenv("LETTA_API_KEY"))
# Get the coordination tool for all managerstools = client.tools.list(name="send_message_to_agents_matching_tags")broadcast_tool = tools.items[0]This tool enables tag-based coordination at every hierarchy level. Executives delegate to managers, and managers delegate to workers using the same coordination mechanism.
Step 2: Create shared resources
Section titled “Step 2: Create shared resources”Create shared resources that all hierarchy levels can access:
# Shared memory block for organizational guidelinesguidelines_block = client.blocks.create( label="project_guidelines", description="Project guidelines and priorities from executive leadership", value="Priority: High-quality delivery. Timeline: 3 weeks. Coordinate across teams.")
# Shared archive for project knowledgeproject_archive = client.archives.create( name="project_knowledge", description="Shared knowledge base for all project contributors")Step 3: Create worker agents
Section titled “Step 3: Create worker agents”Create specialized workers at the bottom of the hierarchy:
# Backend engineer (Engineering team)backend_engineer = client.agents.create( name="backend_engineer", model="anthropic/claude-sonnet-4-5-20250929", memory_blocks=[{ "label": "persona", "value": "I implement backend features: APIs, databases, authentication, and server logic. I complete tasks immediately with reasonable assumptions." }], block_ids=[guidelines_block.id, status_block.id], tags=["worker", "engineering", "backend"], tools=["archival_memory_insert", "archival_memory_search"], tool_rules=[ {"tool_name": "archival_memory_insert", "type": "max_count_per_step", "max_count_limit": 2}, {"tool_name": "archival_memory_search", "type": "max_count_per_step", "max_count_limit": 2} ])client.agents.archives.attach(project_archive.id, agent_id=backend_engineer.id)
# Frontend engineer (Engineering team)frontend_engineer = client.agents.create( name="frontend_engineer", model="anthropic/claude-sonnet-4-5-20250929", memory_blocks=[{ "label": "persona", "value": "I implement frontend features: UI components, forms, and client-side logic. I complete tasks immediately with reasonable assumptions." }], block_ids=[guidelines_block.id, status_block.id], tags=["worker", "engineering", "frontend"], tools=["archival_memory_insert", "archival_memory_search"], tool_rules=[ {"tool_name": "archival_memory_insert", "type": "max_count_per_step", "max_count_limit": 2}, {"tool_name": "archival_memory_search", "type": "max_count_per_step", "max_count_limit": 2} ])client.agents.archives.attach(project_archive.id, agent_id=frontend_engineer.id)
# Content writer (Marketing team)content_writer = client.agents.create( name="content_writer", model="anthropic/claude-sonnet-4-5-20250929", memory_blocks=[{ "label": "persona", "value": "I create marketing content: blog posts, documentation, and copy. I complete tasks immediately with reasonable assumptions." }], block_ids=[guidelines_block.id, status_block.id], tags=["worker", "marketing", "content"], tools=["archival_memory_insert", "archival_memory_search"], tool_rules=[ {"tool_name": "archival_memory_insert", "type": "max_count_per_step", "max_count_limit": 2}, {"tool_name": "archival_memory_search", "type": "max_count_per_step", "max_count_limit": 2} ])client.agents.archives.attach(project_archive.id, agent_id=content_writer.id)
# Designer (Marketing team)designer = client.agents.create( name="designer", model="anthropic/claude-sonnet-4-5-20250929", memory_blocks=[{ "label": "persona", "value": "I create visual content: graphics, mockups, and design assets. I complete tasks immediately with reasonable assumptions." }], block_ids=[guidelines_block.id, status_block.id], tags=["worker", "marketing", "design"], tools=["archival_memory_insert", "archival_memory_search"], tool_rules=[ {"tool_name": "archival_memory_insert", "type": "max_count_per_step", "max_count_limit": 2}, {"tool_name": "archival_memory_search", "type": "max_count_per_step", "max_count_limit": 2} ])client.agents.archives.attach(project_archive.id, agent_id=designer.id)The worker’s key features include:
- Specialized expertise in specific domains (such as backend, frontend, content, or design)
- Tags identifying both team membership (
engineeringormarketing) and specialty (backend,frontend,content, ordesign) - Access to the shared guidelines and project archive
- No coordination tools (workers respond to managers; they do not delegate)
Step 4: Create manager agents
Section titled “Step 4: Create manager agents”Create managers that coordinate their specialized teams:
# Engineering managereng_manager = client.agents.create( name="engineering_manager", model="anthropic/claude-sonnet-4-5-20250929", memory_blocks=[{ "label": "persona", "value": """I am the Engineering Manager coordinating technical development.
My team workers have tags: [worker, engineering]- Backend engineers (tags: worker, engineering, backend)- Frontend engineers (tags: worker, engineering, frontend)
PARALLEL DELEGATION:- I can delegate to MULTIPLE workers SIMULTANEOUSLY- I analyze tasks and determine which workers are needed- I send SPECIFIC instructions to each worker (include framework, scope, defaults)- I wait for ALL workers to complete before reporting back
I use send_message_to_agents_matching_tags to coordinate my team:- For backend work: match_all=["worker", "engineering"], match_some=["backend"]- For frontend work: match_all=["worker", "engineering"], match_some=["frontend"]- For all engineering: match_all=["worker", "engineering"]
When delegating, I provide complete instructions so workers can complete tasks immediately without asking questions.""" }], block_ids=[guidelines_block.id, status_block.id], tags=["manager", "engineering"], tool_ids=[broadcast_tool.id], tool_rules=[ {"tool_name": "send_message_to_agents_matching_tags", "type": "max_count_per_step", "max_count_limit": 5} ])client.agents.archives.attach(project_archive.id, agent_id=eng_manager.id)
# Marketing managermarketing_manager = client.agents.create( name="marketing_manager", model="anthropic/claude-sonnet-4-5-20250929", memory_blocks=[{ "label": "persona", "value": """I am the Marketing Manager coordinating launch materials.
My team workers have tags: [worker, marketing]- Content writers (tags: worker, marketing, content)- Designers (tags: worker, marketing, design)
PARALLEL DELEGATION:- I can delegate to MULTIPLE workers SIMULTANEOUSLY- I analyze tasks and determine which workers are needed- I send SPECIFIC instructions to each worker (include format, audience, key points)- I wait for ALL workers to complete before reporting back
I use send_message_to_agents_matching_tags to coordinate my team:- For written content: match_all=["worker", "marketing"], match_some=["content"]- For design work: match_all=["worker", "marketing"], match_some=["design"]- For all marketing: match_all=["worker", "marketing"]
When delegating, I provide complete instructions so workers can complete tasks immediately without asking questions.""" }], block_ids=[guidelines_block.id, status_block.id], tags=["manager", "marketing"], tool_ids=[broadcast_tool.id], tool_rules=[ {"tool_name": "send_message_to_agents_matching_tags", "type": "max_count_per_step", "max_count_limit": 5} ])client.agents.archives.attach(project_archive.id, agent_id=marketing_manager.id)Managers have the following critical requirements:
- The persona must document which workers the manager coordinates with its tags.
- The persona must show how to use
match_allandmatch_somefor targeting workers. - The persona must include parallel delegation instructions and guidance to provide specific instructions to workers.
- Managers need both
["manager"]and a domain tag (such as["engineering"]or["marketing"]). - Managers must have the coordination tool and
tool_ruleswithmax_count_per_step: 5to allow parallel delegation to multiple workers (and workers should not). - Managers have access to shared status blocks to track coordination state.
Step 5: Create the executive agent
Section titled “Step 5: Create the executive agent”Create the executive agent that coordinates managers:
executive = client.agents.create( name="executive_director", model="anthropic/claude-sonnet-4-5-20250929", memory_blocks=[{ "label": "persona", "value": """I am the Executive Director coordinating high-level projects.
Available managers and their tags:- Engineering manager (tags: manager, engineering) - Handles technical implementation- Marketing manager (tags: manager, marketing) - Handles launch materials and marketing
SEQUENTIAL DELEGATION STRATEGY:When I receive a task requiring multiple departments:1. Analyze which departments are needed2. Delegate to FIRST department and WAIT for completion3. After first department completes, delegate to NEXT department4. Continue until all departments complete5. Synthesize final results
I use send_message_to_agents_matching_tags to coordinate managers:- For technical work: match_all=["manager"], match_some=["engineering"]- For marketing work: match_all=["manager"], match_some=["marketing"]- For broad coordination: match_all=["manager"]
CRITICAL TARGETING:- Always use match_all=["manager"], match_some=["department"] to target ONLY managers- This prevents accidentally messaging workers directly- Workers should only receive messages from their managers, not from me
I analyze projects and delegate to appropriate managers based on their expertise.""" }], block_ids=[guidelines_block.id, status_block.id], tags=["executive", "leadership"], tool_ids=[broadcast_tool.id], tool_rules=[ {"tool_name": "send_message_to_agents_matching_tags", "type": "max_count_per_step", "max_count_limit": 10} ])client.agents.archives.attach(project_archive.id, agent_id=executive.id)The executive’s key features include:
- Sequential delegation strategy - Delegates to one department at a time to maintain control and prevent cascade messages
- Higher tool limit (
max_count_limit: 10) - Accommodates nested delegation where executive messages trigger manager delegations to workers within the same coordination flow - Precise targeting - Uses
match_all=["manager"]to ensure only managers receive executive messages, preventing workers from receiving out-of-hierarchy instructions - Shared resource access - Can update guidelines, search archives, and track status across all hierarchy levels
Step 6: The executive coordinates the hierarchy
Section titled “Step 6: The executive coordinates the hierarchy”The executive agent receives high-level tasks and autonomously coordinates work across hierarchy levels:
# Send complex multi-team project to executiveresponse = client.agents.messages.create( agent_id=executive.id, messages=[{ "role": "user", "content": """Build a user authentication feature and create launch materials.
Engineering requirements:- Backend: Authentication API with JWT tokens and database schema- Frontend: Login form, signup form, and session management
Marketing requirements:- Launch blog post announcing the feature- Social media graphics for promotion
Please delegate to your managers and coordinate the implementation.""" }], timeout=180 # Complex hierarchies may take longer)How hierarchical coordination works
Section titled “How hierarchical coordination works”This pattern implements a three-tier workflow optimized for controlled, efficient coordination:
Executive (Sequential delegation):
- Analyzes the project scope to identify which departments are needed.
- Delegates to FIRST department using precise tag-based routing (
match_all=["manager"], match_some=["engineering"]) - Waits for manager completion before proceeding to next department.
- Delegates to NEXT department (such as
match_all=["manager"], match_some=["marketing"]) - Synthesizes results across all departments after all complete.
Managers (Parallel delegation):
- Receive task from executive and analyze which workers are needed.
- Delegate to MULTIPLE workers SIMULTANEOUSLY using tag-based routing:
- Backend work:
match_all=["worker", "engineering"], match_some=["backend"] - Frontend work:
match_all=["worker", "engineering"], match_some=["frontend"] - Content work:
match_all=["worker", "marketing"], match_some=["content"] - Design work:
match_all=["worker", "marketing"], match_some=["design"]
- Backend work:
- Provide specific, complete instructions so workers can complete tasks without asking questions.
- Wait for ALL workers to complete before reporting back.
- Synthesize team results and report completion upward to executive.
Workers (Immediate completion):
- Receive task from manager with specific instructions.
- Execute immediately using reasonable assumptions for any unclear details.
- Store findings in shared archive for cross-functional knowledge sharing.
- Return results to manager synchronously.
This three-tier workflow (sequential → parallel → immediate) balances control with efficiency. The executive maintains strategic oversight by processing one department at a time, managers maximize team productivity by coordinating workers in parallel, and workers complete tasks promptly to avoid coordination delays.
Minimal example
Section titled “Minimal example”Here is a minimal two-layer hierarchy with a manager and workers:
from letta_client import Lettaimport os
client = Letta(api_key=os.getenv("LETTA_API_KEY"))
# Get coordination tooltools = client.tools.list(name="send_message_to_agents_matching_tags")broadcast_tool = tools.items[0]
# Create shared resourcesguidelines = client.blocks.create( label="guidelines", value="Deliver high-quality work on schedule.")status = client.blocks.create( label="status", value="" # Agents populate during coordination)archive = client.archives.create(name="team_knowledge")
# Create two workersbackend_worker = client.agents.create( model="anthropic/claude-sonnet-4-5-20250929", memory_blocks=[{ "label": "persona", "value": "I implement backend features. I complete tasks immediately with reasonable assumptions." }], block_ids=[guidelines.id, status.id], tags=["worker", "engineering", "backend"], tools=["archival_memory_insert", "archival_memory_search"], tool_rules=[ {"tool_name": "archival_memory_insert", "type": "max_count_per_step", "max_count_limit": 2}, {"tool_name": "archival_memory_search", "type": "max_count_per_step", "max_count_limit": 2} ])client.agents.archives.attach(archive.id, agent_id=backend_worker.id)
frontend_worker = client.agents.create( model="anthropic/claude-sonnet-4-5-20250929", memory_blocks=[{ "label": "persona", "value": "I implement frontend features. I complete tasks immediately with reasonable assumptions." }], block_ids=[guidelines.id, status.id], tags=["worker", "engineering", "frontend"], tools=["archival_memory_insert", "archival_memory_search"], tool_rules=[ {"tool_name": "archival_memory_insert", "type": "max_count_per_step", "max_count_limit": 2}, {"tool_name": "archival_memory_search", "type": "max_count_per_step", "max_count_limit": 2} ])client.agents.archives.attach(archive.id, agent_id=frontend_worker.id)
# Create manager with coordination toolmanager = client.agents.create( model="anthropic/claude-sonnet-4-5-20250929", memory_blocks=[{ "label": "persona", "value": """I coordinate engineering work.
Team workers:- Backend engineers (tags: worker, engineering, backend)- Frontend engineers (tags: worker, engineering, frontend)
I use send_message_to_agents_matching_tags to delegate:- Backend work: match_all=["worker", "engineering"], match_some=["backend"]- Frontend work: match_all=["worker", "engineering"], match_some=["frontend"]
I provide specific instructions so workers can complete tasks immediately without asking questions.""" }], block_ids=[guidelines.id, status.id], tags=["manager", "engineering"], tool_ids=[broadcast_tool.id], tool_rules=[ {"tool_name": "send_message_to_agents_matching_tags", "type": "max_count_per_step", "max_count_limit": 5} ])client.agents.archives.attach(archive.id, agent_id=manager.id)
# Manager delegates to workersresponse = client.agents.messages.create( agent_id=manager.id, messages=[{ "role": "user", "content": "Build a login feature with backend API and frontend form." }])# Manager analyzes task and routes work to both backend and frontend workers
# Cleanupclient.agents.delete(backend_worker.id)client.agents.delete(frontend_worker.id)client.agents.delete(manager.id)client.archives.delete(archive.id)client.blocks.delete(guidelines.id)client.blocks.delete(status.id)Best practices
Section titled “Best practices”-
Use tool rules to prevent cascades: Always configure
tool_ruleswithmax_count_per_steplimits for coordination tools. Without these limits, agents may continuously message each other across hierarchy layers, consuming excessive tokens. Set executives to 10 (for nested delegation), managers to 5 (for parallel worker delegation), and workers to 2 (for archival tools only). -
Design clear hierarchies: Limit hierarchy depth to three or four layers maximum. Deeper hierarchies increase coordination complexity and latency.
-
Use precise tag targeting: Executives must use
match_all=["manager"], match_some=["department"]to target ONLY managers and prevent accidentally broadcasting to workers. Workers should only receive messages from their direct managers, never from executives. -
Include coordination protocols in personas: Add explicit instructions about when to delegate, when to wait for completion, and when to report back. Executives should delegate sequentially (one department at a time), managers should delegate in parallel (multiple workers simultaneously), and workers should complete immediately with reasonable assumptions.
-
Use descriptive tags: Tag agents by layer and specialty (such as
["manager", "engineering"],["worker", "engineering", "backend"]) for precise routing. -
Document team structures in personas: Each manager’s persona should list its direct reports with complete tags. This ensures accurate delegation.
-
Use status blocks for coordination state: Shared status blocks help agents track task assignments and completion, preventing coordination loops and duplicate work.
-
Share knowledge through archives: Use archival memory for cross-functional knowledge sharing. Workers and managers insert findings that the executive can search.
-
Managers should provide specific instructions: When delegating to workers, managers should include all necessary details (framework, scope, defaults, format, audience) so workers can complete tasks immediately without asking clarifying questions.
-
Start with bounded tasks: When testing hierarchical patterns, use simple, focused tasks (1-2 deliverables) to verify coordination works before scaling to complex multi-deliverable projects.
-
Expect async coordination: Complex hierarchies involve many agents working asynchronously. Use appropriate timeouts and query message histories to track their progress.
-
Check actual message counts in cloud: After running hierarchical workflows, verify message counts in the cloud to detect cascades. If you see significantly more messages than expected, review your tool rules and targeting patterns.