Skip to content
Letta Platform Letta Platform Letta Docs
Sign up
Tutorials
Multi-agent patterns

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.

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)

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.

The hierarchical teams pattern uses four key components:

  1. Tool rules for cascade prevention: Each hierarchy level has coordination limits that prevent runaway message loops
  2. Shared archival memory: Agents at all levels contribute findings to a searchable knowledge base
  3. Shared memory blocks: Memory blocks make coordination state visible across layers (guidelines, priorities, project status)
  4. Hierarchical tagging: Agents are tagged by layer (["executive"], ["manager", "engineering"], ["worker", "engineering", "backend"])

Each hierarchy level follows a distinct coordination strategy:

LevelStrategyTool limitCoordination scope
ExecutiveSequential delegation10Delegates to managers one at a time
ManagerParallel delegation5Coordinates multiple workers simultaneously
WorkerImmediate completion2Archival operations only, no coordination tools

All coordinating agents (executives and managers) need the send_message_to_agents_matching_tags tool:

from letta_client import Letta
import os
client = Letta(api_key=os.getenv("LETTA_API_KEY"))
# Get the coordination tool for all managers
tools = client.tools.list(name="send_message_to_agents_matching_tags")
broadcast_tool = tools.items[0]

Create shared resources that all hierarchy levels can access:

# Shared memory block for organizational guidelines
guidelines_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 state
status_block = client.blocks.create(
label="status",
value="" # Agents populate during coordination
)
# Shared archive for project knowledge
project_archive = client.archives.create(
name="project_knowledge",
description="Shared knowledge base for all project contributors"
)

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.

Create managers that coordinate their specialized teams:

# Engineering manager
eng_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: 5 for parallel delegation
  • Both ["manager"] and a domain tag (e.g., ["engineering"])
  • A persona documenting which workers they coordinate and how to target them

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 needed
2. Delegate to FIRST department and WAIT for completion
3. After completion, delegate to NEXT department
4. 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
)

A two-layer hierarchy with a manager and workers:

from letta_client import Letta
import os
client = Letta(api_key=os.getenv("LETTA_API_KEY"))
# Get coordination tool
tools = client.tools.list(name="send_message_to_agents_matching_tags")
broadcast_tool = tools.items[0]
# Create shared resources
guidelines = 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 workers
backend_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 tool
manager = 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 workers
response = client.agents.messages.create(
agent_id=manager.id,
messages=[{
"role": "user",
"content": "Build a login feature with backend API and frontend form."
}]
)
# Cleanup
client.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)
  • Use tool rules to prevent cascades: Always configure tool_rules with max_count_per_step limits. 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.