Learnixo

CrewAI Multi-Agents · Lesson 14 of 16

Hierarchical Process: Manager Delegates Tasks

What is the Hierarchical Process?

In Process.hierarchical, CrewAI creates a manager agent that reads the task list and dynamically assigns each task to the most appropriate agent. The manager plans, delegates, reviews intermediate outputs, and decides when the crew's goal is achieved.

This differs from sequential where tasks run in a fixed order. In hierarchical mode, the manager can:

  • Reorder tasks based on what's been completed
  • Ask an agent to redo work if the output is insufficient
  • Route the same task to a different agent if the first attempt fails

When to Use Hierarchical vs Sequential

| Scenario | Sequential | Hierarchical | |---|---|---| | Fixed pipeline with known steps | Yes | Overkill | | Tasks have a natural order | Yes | Overkill | | Dynamic routing needed | No | Yes | | Manager needs to evaluate quality | No | Yes | | Open-ended research with unknown steps | No | Yes | | Complex multi-agent workflows | Sometimes | Yes |

Use hierarchical when the manager needs judgment about what to do next, not just execution in order.


Basic Hierarchical Setup

Python
from crewai import Agent, Task, Crew, Process
from langchain_openai import ChatOpenAI

# Specialist agents (no manager role needed  CrewAI creates the manager)
pharmacologist = Agent(
    role="Clinical Pharmacologist",
    goal="Analyze drug mechanisms and clinical profiles",
    backstory="Board-certified pharmacologist with 20 years in clinical research",
    verbose=True,
)

regulatory_expert = Agent(
    role="Regulatory Affairs Specialist",
    goal="Analyze drug regulatory status and compliance requirements",
    backstory="Former FDA reviewer with expertise in drug approvals",
    verbose=True,
)

medical_writer = Agent(
    role="Medical Writer",
    goal="Produce accurate, clear drug information documents",
    backstory="Experienced medical writer for pharmaceutical companies",
    verbose=True,
)

# Tasks  the manager decides which agent handles each
pharmacology_task = Task(
    description="Provide a comprehensive pharmacological profile of {drug_name}",
    expected_output="Pharmacological report: mechanism, PK/PD, indications, side effects, interactions",
    agent=pharmacologist,
)

regulatory_task = Task(
    description="Provide the regulatory status of {drug_name} in the US and EU",
    expected_output="Regulatory report: approval dates, indications, black box warnings, REMS if applicable",
    agent=regulatory_expert,
)

synthesis_task = Task(
    description=(
        "Write a comprehensive drug monograph for {drug_name} "
        "incorporating the pharmacological and regulatory information."
    ),
    expected_output=(
        "Drug monograph (800 words): Clinical Overview, Pharmacology, Regulatory Status, "
        "Prescribing Considerations, Patient Counseling Points"
    ),
    agent=medical_writer,
)

crew = Crew(
    agents=[pharmacologist, regulatory_expert, medical_writer],
    tasks=[pharmacology_task, regulatory_task, synthesis_task],
    process=Process.hierarchical,
    manager_llm=ChatOpenAI(model="gpt-4o", temperature=0),  # Manager's brain
    verbose=True,
)

result = crew.kickoff(inputs={"drug_name": "Rivaroxaban"})
print(result.raw)

The manager_llm Parameter

The manager agent uses manager_llm to reason about task delegation. Use a capable model here:

Python
from langchain_openai import ChatOpenAI
from langchain_anthropic import ChatAnthropic

# Option 1: OpenAI GPT-4o (default choice for most use cases)
crew = Crew(
    ...
    process=Process.hierarchical,
    manager_llm=ChatOpenAI(model="gpt-4o", temperature=0),
)

# Option 2: Anthropic Claude (strong reasoning for complex delegation)
crew = Crew(
    ...
    process=Process.hierarchical,
    manager_llm=ChatAnthropic(model="claude-opus-4-7", temperature=0),
)

The temperature=0 keeps the manager deterministic. The manager needs logical reasoning, not creativity.


Custom Manager Agent

If you need more control, provide your own manager agent:

Python
from crewai import Agent

custom_manager = Agent(
    role="Drug Information Director",
    goal=(
        "Coordinate specialist agents to produce comprehensive, accurate drug information. "
        "Ensure quality by reviewing outputs before finalizing."
    ),
    backstory=(
        "20 years managing medical information departments at pharmaceutical companies. "
        "Expert at identifying gaps in drug documentation and directing specialists."
    ),
    llm=ChatOpenAI(model="gpt-4o", temperature=0),
    verbose=True,
)

crew = Crew(
    agents=[pharmacologist, regulatory_expert, medical_writer],
    tasks=[pharmacology_task, regulatory_task, synthesis_task],
    process=Process.hierarchical,
    manager_agent=custom_manager,  # Use instead of manager_llm
    verbose=True,
)

Use manager_agent when you want the manager to have a specific role, goal, and backstory that shapes its delegation behavior.


Full Example: Hierarchical Drug Research System

Python
from crewai import Agent, Task, Crew, Process
from langchain_openai import ChatOpenAI

# Research team
literature_researcher = Agent(
    role="Medical Literature Researcher",
    goal="Find and synthesize relevant clinical trials and pharmacological data",
    backstory="Research pharmacist with expertise in systematic reviews and meta-analyses",
    verbose=True,
)

safety_analyst = Agent(
    role="Drug Safety Analyst",
    goal="Identify and analyze adverse events, drug interactions, and safety signals",
    backstory="Pharmacovigilance expert, formerly at the FDA Adverse Event Reporting System",
    verbose=True,
)

clinical_advisor = Agent(
    role="Clinical Practice Advisor",
    goal="Translate research into practical clinical recommendations",
    backstory="Hospital pharmacist with 15 years of direct patient care experience",
    verbose=True,
)

document_specialist = Agent(
    role="Medical Documentation Specialist",
    goal="Produce publication-ready pharmaceutical documentation",
    backstory="Medical writer with experience in drug package inserts and clinical guidelines",
    verbose=True,
)

# Tasks
research_task = Task(
    description=(
        "Research the clinical evidence for {drug_name} in {indication}. "
        "Include pivotal trials, meta-analyses, and recent real-world evidence."
    ),
    expected_output=(
        "Evidence summary: key trials, effect sizes, number needed to treat, "
        "quality of evidence (GRADE), and research gaps"
    ),
    agent=literature_researcher,
)

safety_task = Task(
    description=(
        "Analyze the complete safety profile of {drug_name}. "
        "Focus on: frequency of adverse events, drug interactions, contraindications, "
        "and any recent safety updates or black box warnings."
    ),
    expected_output=(
        "Safety report: common adverse events (with frequency %), "
        "serious adverse events, drug interactions (list at least 10), "
        "contraindicated populations, monitoring requirements"
    ),
    agent=safety_analyst,
)

clinical_task = Task(
    description=(
        "Based on the evidence and safety data, develop practical clinical recommendations "
        "for prescribing {drug_name} in {indication}."
    ),
    expected_output=(
        "Clinical recommendations: patient selection criteria, dosing guidance, "
        "monitoring parameters, when to avoid, patient counseling points"
    ),
    agent=clinical_advisor,
)

final_document_task = Task(
    description=(
        "Produce a comprehensive drug information monograph for {drug_name} "
        "in {indication} using all research, safety, and clinical data."
    ),
    expected_output=(
        "Complete drug monograph (1200 words): "
        "Indications, Clinical Evidence (with citations), "
        "Pharmacology, Safety Profile, Prescribing Recommendations, "
        "Patient Counseling, References"
    ),
    agent=document_specialist,
)

crew = Crew(
    agents=[literature_researcher, safety_analyst, clinical_advisor, document_specialist],
    tasks=[research_task, safety_task, clinical_task, final_document_task],
    process=Process.hierarchical,
    manager_llm=ChatOpenAI(model="gpt-4o", temperature=0),
    verbose=True,
)

result = crew.kickoff(inputs={
    "drug_name": "Apixaban",
    "indication": "atrial fibrillation stroke prevention",
})

print(result.raw)

Manager Behavior

The manager in hierarchical mode:

  1. Reviews all tasks and assigns them to specialist agents in the most logical order
  2. After each task completes, reviews the output quality
  3. If output is insufficient, may ask the agent to revise or reassign to another agent
  4. Decides when all tasks are complete and the crew's goal is achieved

This means the manager adds overhead (extra LLM calls) but provides quality control that sequential mode doesn't have.


Cost Considerations

Hierarchical mode is more expensive than sequential:

  • Manager LLM calls: one per task assignment (at minimum)
  • Manager review calls: one per task completion
  • Total: roughly 2× the LLM calls of sequential for the same task set

Use hierarchical when the quality improvement justifies the cost. For simple, well-defined pipelines, sequential is faster and cheaper.