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:
- Delegate complex projects that require coordination at multiple levels
- Scale agent systems beyond flat team structures
- Coordinate work across departments or functional areas
- Maintain clear reporting structures and accountability across layers
- Organize large agent systems with multiple specialized teams (engineering, marketing, operations)
Example use case
Section titled “Example use case”An executive agent oversees a product launch with two managers (engineering and marketing). 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. 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:
- Tool rules for cascade prevention: Each hierarchy level has coordination limits that prevent runaway message loops
- Shared archival memory: Agents at all levels contribute findings to a searchable knowledge base
- Shared memory blocks: Memory blocks make coordination state visible across layers (guidelines, priorities, project status)
- Hierarchical tagging: Agents are tagged by layer (
["executive"],["manager", "engineering"],["worker", "engineering", "backend"])
Each hierarchy level follows a distinct coordination strategy:
| Level | Strategy | Tool limit | Coordination scope |
|---|---|---|---|
| Executive | Sequential delegation | 10 | Delegates to managers one at a time |
| Manager | Parallel delegation | 5 | Coordinates multiple workers simultaneously |
| Worker | Immediate completion | 2 | Archival operations only, no coordination tools |
Implementation
Section titled “Implementation”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]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 status block for coordination statestatus_block = client.blocks.create( label="status", value="" # Agents populate during coordination)
# 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)Workers have no coordination tools - they respond to managers and complete tasks.
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 delegate to MULTIPLE workers SIMULTANEOUSLY- I provide SPECIFIC instructions to each worker- I wait for ALL workers to complete before reporting back
I use send_message_to_agents_matching_tags to coordinate:- Backend work: match_all=["worker", "engineering"], match_some=["backend"]- Frontend work: match_all=["worker", "engineering"], match_some=["frontend"]- All engineering: match_all=["worker", "engineering"]""" }], 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)Managers need:
- The coordination tool with
max_count_per_step: 5for parallel delegation - Both
["manager"]and a domain tag (e.g.,["engineering"]) - A persona documenting which workers they coordinate and how to target them
Step 5: Create the executive agent
Section titled “Step 5: Create the executive agent”Create the executive 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:- Engineering manager (tags: manager, engineering)- Marketing manager (tags: manager, marketing)
SEQUENTIAL DELEGATION:1. Analyze which departments are needed2. Delegate to FIRST department and WAIT for completion3. After completion, delegate to NEXT department4. 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"]
CRITICAL: Always use match_all=["manager"] to target ONLY managers.Workers should only receive messages from their managers.""" }], 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 has a higher tool limit (max_count_limit: 10) to accommodate nested delegation flows.
Step 6: The executive coordinates the hierarchy
Section titled “Step 6: The executive coordinates the hierarchy”Send a complex multi-team project to the executive:
response = 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)Minimal example
Section titled “Minimal example”A 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.")status = client.blocks.create(label="status", value="")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." }], 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." }], 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: match_all=["worker", "engineering"], match_some=["backend"]- Frontend: match_all=["worker", "engineering"], match_some=["frontend"]
I provide specific instructions so workers can complete tasks immediately.""" }], 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." }])
# 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. Set executives to 10, managers to 5, and workers to 2. - Design clear hierarchies: Limit hierarchy depth to 3-4 layers maximum. Deeper hierarchies increase coordination complexity and latency.
- Use precise tag targeting: Executives must use
match_all=["manager"]to target ONLY managers and prevent accidentally broadcasting to workers. - Include coordination protocols in personas: Executives should delegate sequentially, managers in parallel, and workers should complete immediately.
- Document team structures in personas: Each manager’s persona should list its direct reports with complete tags.
- Use status blocks for coordination state: Shared status blocks help agents track task assignments and prevent duplicate work.
- Managers should provide specific instructions: Include all necessary details so workers can complete tasks without asking clarifying questions.
- Start with bounded tasks: Test with simple 1-2 deliverable tasks before scaling to complex multi-deliverable projects.
- Expect async coordination: Use appropriate timeouts and query message histories to track progress.