---
title: The hierarchical teams pattern | Letta Docs
description: 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

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

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

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:

| Level         | Strategy              | Coordination 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

### Step 1: Define coordination constraints

Before creating agents, define coordination constraints for each layer and encode them in prompts/tool rules:

- Executive: sequential delegation
- Manager: bounded parallel delegation
- Worker: immediate completion

### Step 2: Create shared resources

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"
)
```

### 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

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 coordinate teams using tag-based routing:
- 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"]
)
client.agents.archives.attach(project_archive.id, agent_id=eng_manager.id)
```

Managers need:

- Coordination constraints (for example, bounded delegation per step)
- 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

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 tag-based routing 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"]
)
client.agents.archives.attach(project_archive.id, agent_id=executive.id)
```

The executive has a higher coordination limit to accommodate nested delegation flows.

### 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

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"))


# 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 constraints
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 tag-based routing 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"]
)
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)
```

## Best practices

- **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.
