> ## Documentation Index
> Fetch the complete documentation index at: https://praison.ai/docs/llms.txt
> Use this file to discover all available pages before exploring further.

# Hierarchical Workflows

> Manager-based validation for graceful workflow failure handling

Hierarchical workflows add a manager agent that validates each step's output before the next step runs, stopping gracefully with a clear reason if a step fails.

> [!NOTE]
>
> This page covers **`AgentFlow(process="hierarchical")`** — where a manager *validates* each step's output before the next step runs. If you want a manager that **delegates tasks to agents by name** (the classic `PraisonAIAgents(agents=[...], tasks=[...], process="hierarchical")` flow), see [Hierarchical Process](https://praison.ai/docs/features/hierarchical-process.md).

> [!NOTE]
>
> Steps inside hierarchical mode inherit the same `max_retries`, `guardrails`, and `output_file` policies as top-level steps. See [Nested workflows → Retry, guardrails, and `output_file`](https://praison.ai/docs/docs/features/nested-workflows#retry-guardrails-and-output_file-inside-nested-steps).

```python theme={"theme":{"light":"vitesse-light","dark":"vitesse-dark"}}
from praisonaiagents import Agent, AgentFlow

researcher = Agent(name="researcher", role="Research topics")
writer = Agent(name="writer", role="Write content")
workflow = AgentFlow(
    steps=[researcher, writer],
    process="hierarchical",
    manager_llm="gpt-4o-mini",
)
workflow.start("Summarise quantum computing for executives")
```

The user submits a multi-step brief; the manager validates each agent output before the workflow continues.

```mermaid theme={"theme":{"light":"vitesse-light","dark":"vitesse-dark"}}
graph LR
    subgraph "Hierarchical Workflow"
        In[📄 User Brief] --> A1[🤖 Agent 1]
        A1 --> V1{"Manager<br/>Validation"}
        V1 -->|Approved| A2[🤖 Agent 2]
        V1 -->|Rejected| Fail[❌ Failed + Reason]
        A2 --> V2{"Manager<br/>Validation"}
        V2 -->|Approved| Out[✅ Result]
        V2 -->|Rejected| Fail
    end

    classDef agent fill:#8B0000,stroke:#7C90A0,color:#fff
    classDef manager fill:#189AB4,stroke:#7C90A0,color:#fff
    classDef success fill:#10B981,stroke:#7C90A0,color:#fff
    classDef fail fill:#F59E0B,stroke:#7C90A0,color:#fff

    class In,A1,A2 agent
    class V1,V2 manager
    class Out success
    class Fail fail
```

## How It Works

```mermaid theme={"theme":{"light":"vitesse-light","dark":"vitesse-dark"}}
sequenceDiagram
    participant User
    participant AgentFlow
    participant Manager
    participant Agent

    User->>AgentFlow: Submit task
    AgentFlow->>Agent: Run step 1
    Agent-->>AgentFlow: Output
    AgentFlow->>Manager: Validate output
    alt Approved
        Manager-->>AgentFlow: Proceed to step 2
    else Rejected
        Manager-->>AgentFlow: Stop with failure_reason
        AgentFlow-->>User: {status: failed, failure_reason: ...}
    end
    AgentFlow-->>User: {status: completed, output: ...}
```

```mermaid theme={"theme":{"light":"vitesse-light","dark":"vitesse-dark"}}
graph TB
    subgraph Workflow["Hierarchical Workflow"]
        direction TB
        A[/"Input"/]:::input --> B["Step 1: Agent"]:::agent
        B --> C{"Manager<br/>Validation"}:::manager
        C -->|Approved| D["Step 2: Agent"]:::agent
        C -->|Rejected| E[/"Failed + Reason"/]:::output
        D --> F{"Manager<br/>Validation"}:::manager
        F -->|Approved| G[/"Completed"/]:::output
        F -->|Rejected| E
    end
    
    classDef input fill:#8B0000,color:#fff,stroke:#7C90A0
    classDef output fill:#8B0000,color:#fff,stroke:#7C90A0
    classDef agent fill:#8B0000,color:#fff,stroke:#7C90A0
    classDef manager fill:#189AB4,color:#fff,stroke:#7C90A0
```

> [card] Sequential (Default)
>
> Steps run one after another without validation

> [card] Hierarchical
>
> Manager validates each step before proceeding

## Quick Start

**1. Simple Usage**

> [tab] Python
>
> ```python theme={"theme":{"light":"vitesse-light","dark":"vitesse-dark"}}
> from praisonaiagents import AgentFlow, Agent
>
> researcher = Agent(name="researcher", role="Research topics")
> writer = Agent(name="writer", role="Write content")
>
> workflow = AgentFlow(
>     steps=[researcher, writer],
>     process="hierarchical",  # Enable manager validation
>     manager_llm="gpt-4o-mini"  # LLM for manager agent
> )
>
> result = workflow.start("Write about AI trends")
>
> if result["status"] == "failed":
>     print(f"Workflow failed: {result['failure_reason']}")
> else:
>     print(f"Output: {result['output']}")
> ```

> [tab] YAML
>
> ```yaml theme={"theme":{"light":"vitesse-light","dark":"vitesse-dark"}}
> name: research-workflow
> process: hierarchical
> manager_llm: gpt-4o-mini
>
> agents:
>   researcher:
>     role: Research Analyst
>     goal: Research topics thoroughly
>     backstory: Expert researcher
>
>   writer:
>     role: Content Writer
>     goal: Write engaging content
>     backstory: Professional writer
>
> steps:
>   - agent: researcher
>     action: Research the topic
>
>   - agent: writer
>     action: Write article based on research
> ```

**2. With Configuration**

Define the same workflow in YAML with process: hierarchical and a manager\_llm — see the YAML tab.

## Parameters

**process** `string` (default: sequential)

Workflow execution mode:

* `sequential` - Steps run without validation (default)
* `hierarchical` - Manager validates each step

**manager\_llm** `string` (default: null)

LLM model for the manager agent. If not specified, uses the workflow's `default_llm`.

## Manager Validation

The manager agent evaluates each step's output based on:

**1. Task Completion**

Does the output address the task?

**2. Quality Check**

Is the output meaningful (not an error)?

**3. Expected Output**

Does it meet the step's expected output criteria?

## Handling Failures

```python Check Status theme={"theme":{"light":"vitesse-light","dark":"vitesse-dark"}}
result = workflow.start("My task")

if result["status"] == "failed":
    # Workflow was rejected by manager
    print(f"Reason: {result['failure_reason']}")
    
    # Check which step failed
    for step in result["steps"]:
        if step["status"] == "failed":
            print(f"Failed step: {step['step']}")
elif result["status"] == "completed":
    print("All steps validated successfully!")
```

```python With Callbacks theme={"theme":{"light":"vitesse-light","dark":"vitesse-dark"}}
def on_step_error(workflow, step, error):
    print(f"Step '{step.name}' failed: {error}")

workflow = AgentFlow(
    steps=[agent1, agent2],
    process="hierarchical",
    hooks={"on_step_error": on_step_error}
)
```

## Result Structure

```python theme={"theme":{"light":"vitesse-light","dark":"vitesse-dark"}}
{
    "output": "Final output from last step",
    "steps": [
        {"step": "researcher", "output": "...", "status": "completed"},
        {"step": "writer", "output": "...", "status": "failed", "failure_reason": "..."}
    ],
    "variables": {...},
    "status": "failed",  # or "completed"
    "failure_reason": "Manager rejected step 'writer': Output lacks detail"
}
```

## When to Use

> [accordion] Quality-Critical Workflows
>
> When each step must meet quality standards before proceeding.

> [accordion] Multi-Agent Pipelines
>
> When agents depend on validated output from previous agents.

> [accordion] Production Workflows
>
> When you need graceful failure handling with clear reasons.

## Forcing Tool Usage

> [!WARNING]
>
> When agents have tools assigned, the LLM may skip calling them even with explicit instructions. Use `tool_choice: required` to **force** the LLM to call a tool before responding.

```mermaid theme={"theme":{"light":"vitesse-light","dark":"vitesse-dark"}}
graph LR
    subgraph Without["tool_choice: auto (default)"]
        A1["Agent with tools"]:::agent --> B1{"LLM decides"}:::manager
        B1 -->|"May skip"| C1["Response without tool"]:::output
        B1 -->|"May call"| D1["Tool call → Response"]:::output
    end
    
    subgraph With["tool_choice: required"]
        A2["Agent with tools"]:::agent --> B2["Must call tool"]:::manager
        B2 --> C2["Tool call → Response"]:::output
    end
    
    classDef agent fill:#8B0000,color:#fff,stroke:#7C90A0
    classDef output fill:#8B0000,color:#fff,stroke:#7C90A0
    classDef manager fill:#189AB4,color:#fff,stroke:#7C90A0
```

> [tab] YAML
>
> ```yaml theme={"theme":{"light":"vitesse-light","dark":"vitesse-dark"}}
> agents:
>   researcher:
>     role: Research Specialist
>     goal: Find latest information
>     tools:
>       - search_web
>     tool_choice: required  # Forces tool usage
>     llm: gpt-4o-mini
> ```

> [tab] Python
>
> ```python theme={"theme":{"light":"vitesse-light","dark":"vitesse-dark"}}
> from praisonaiagents import Agent
>
> researcher = Agent(
>     name="researcher",
>     role="Research Specialist",
>     tools=["search_web"],
>     model="gpt-4o-mini"
> )
> # Set tool_choice for YAML workflows
> researcher._yaml_tool_choice = "required"
> ```

**tool\_choice** `string` (default: auto)

Controls when the LLM calls tools:

* `auto` - LLM decides whether to call tools (default)
* `required` - LLM **must** call a tool before responding
* `none` - LLM cannot call tools

> [!TIP]
>
> Always use `tool_choice: required` for agents with tools in hierarchical workflows. This ensures the manager can validate that tools were actually used.

## Comparison

| Feature | Sequential | Hierarchical |
| - | - | - |
| **Validation** | None | After each step |
| **Failure Handling** | Continues on error | Stops with reason |
| **Performance** | Faster | Slightly slower |
| **Use Case** | Simple pipelines | Quality-critical flows |

> [!TIP]
>
> Use `hierarchical` mode when you need **guaranteed quality** at each step. Use `sequential` mode for **faster execution** when validation isn't critical.

## Real-World Examples

> [accordion] Research & Writing Pipeline
>
> ```python theme={"theme":{"light":"vitesse-light","dark":"vitesse-dark"}}
> from praisonaiagents import AgentFlow, Agent
>
> researcher = Agent(
>     name="researcher",
>     role="Research Analyst",
>     goal="Find accurate, up-to-date information",
>     backstory="Expert researcher with attention to detail",
>     model="gpt-4o-mini"
> )
>
> writer = Agent(
>     name="writer",
>     role="Content Writer", 
>     goal="Write engaging, clear content",
>     backstory="Professional writer who creates compelling articles",
>     model="gpt-4o-mini"
> )
>
> editor = Agent(
>     name="editor",
>     role="Editor",
>     goal="Polish and improve content quality",
>     backstory="Experienced editor with keen eye for detail",
>     model="gpt-4o-mini"
> )
>
> workflow = AgentFlow(
>     name="content-pipeline",
>     steps=[researcher, writer, editor],
>     process="hierarchical",
>     manager_llm="gpt-4o-mini"
> )
>
> result = workflow.start("Write an article about AI in healthcare")
> ```

> [accordion] Data Analysis Pipeline
>
> ```python theme={"theme":{"light":"vitesse-light","dark":"vitesse-dark"}}
> from praisonaiagents import AgentFlow, Agent
>
> collector = Agent(
>     name="collector",
>     role="Data Collector",
>     goal="Gather and prepare data",
>     model="gpt-4o-mini"
> )
>
> analyst = Agent(
>     name="analyst",
>     role="Data Analyst",
>     goal="Analyze data and find insights",
>     model="gpt-4o-mini"
> )
>
> reporter = Agent(
>     name="reporter",
>     role="Report Writer",
>     goal="Create clear reports from analysis",
>     model="gpt-4o-mini"
> )
>
> workflow = AgentFlow(
>     name="data-pipeline",
>     steps=[collector, analyst, reporter],
>     process="hierarchical",
>     manager_llm="gpt-4o-mini"
> )
>
> result = workflow.start("Analyze Q4 sales trends")
>
> if result["status"] == "failed":
>     print(f"Pipeline failed: {result['failure_reason']}")
> ```

> [accordion] Code Review Pipeline
>
> ```python theme={"theme":{"light":"vitesse-light","dark":"vitesse-dark"}}
> from praisonaiagents import AgentFlow, Agent
>
> reader = Agent(
>     name="code_reader",
>     role="Code Reader",
>     goal="Understand code structure",
>     model="gpt-4o-mini"
> )
>
> reviewer = Agent(
>     name="reviewer",
>     role="Code Reviewer",
>     goal="Find issues and improvements",
>     model="gpt-4o-mini"
> )
>
> suggester = Agent(
>     name="suggester",
>     role="Improvement Suggester",
>     goal="Suggest specific code improvements",
>     model="gpt-4o-mini"
> )
>
> workflow = AgentFlow(
>     name="code-review-pipeline",
>     steps=[reader, reviewer, suggester],
>     process="hierarchical",
>     manager_llm="gpt-4o-mini",
>     output="verbose"  # See validation results
> )
>
> result = workflow.start("Review this Python module for best practices")
> ```

## Best Practices

> [accordion] Use a cheaper model for the manager
>
> The manager only validates output, so a smaller `manager_llm` like `gpt-4o-mini` keeps cost low without hurting quality.

> [accordion] Force tool usage in tool-heavy steps
>
> Set `tool_choice="required"` so the manager can confirm tools actually ran before approving a step.

> [accordion] Always check result status
>
> Inspect `result["status"]` and `result["failure_reason"]` before using the output — hierarchical workflows fail gracefully rather than raising.

> [accordion] Keep steps single-purpose
>
> Narrow, well-scoped steps make manager validation more reliable than broad, multi-goal steps.

## Related

> [card] [AgentFlow](https://praison.ai/docs/features/agentflow)
>
> Deterministic multi-step pipelines

> [card] [Conditional Execution](https://praison.ai/docs/features/conditions.md)
>
> Branch workflows on runtime conditions

> [card] [AgentTeam](https://praison.ai/docs/features/agentteam)
>
> Multi-agent task orchestration

> [card] [Handoffs](https://praison.ai/docs/features/handoffs.md)
>
> Transfer control between agents


This documentation is built and hosted on [Mintlify](https://mintlify.com), a developer documentation platform.