A crewai hierarchical crew manager agent changes how multi-agent workflows distribute work: instead of a linear handoff, a manager breaks the goal into subtasks and assigns them dynamically. This pattern fits open-ended problems where you can’t predetermine the task order. Below we build one from scratch with runnable code and a clear verification path.
What a hierarchical crew actually does
In a sequential CrewAI process, tasks execute in the order you list them; the output of one feeds the next via context. That’s deterministic and cheap. A hierarchical process inserts a planning layer. The manager agent receives the top-level objective, writes a plan, and calls workers as needed. Workers never see the whole pipeline—only their slice.
This matters when the decomposition isn’t fixed. Example: “investigate why latency spiked” might require a log analyst first, then a database expert, but only if the logs point to a query issue. Hard-coding that branch is fragile. A crewai hierarchical crew manager agent makes the branch at runtime.
Step 1: Install and import the stack
CrewAI depends on LangChain chat models for LLM abstraction. Install the core package and the OpenAI-compatible client:
pip install crewai langchain-openai
Pin versions. CrewAI’s API stabilized around 0.28+, but minor releases still move Process semantics. Import the primitives:
from crewai import Agent, Task, Crew, Process
from langchain_openai import ChatOpenAI
If you’re on Python 3.12, create a clean venv. Pydantic v2 transitions have caused silent Agent config drops in mixed environments. I always run python -m venv .crew && source .crew/bin/activate before installing.
Step 2: Define worker agents
Workers should be narrow and stateless. The manager decides invocation, so don’t embed sequencing hints in their goal. Here are two specialists: a researcher with a search tool stub, and a writer.
researcher = Agent(
role="Senior Web Researcher",
goal="Find authoritative sources on a given technical topic",
backstory="You filter primary sources and ignore vendor marketing.",
llm=ChatOpenAI(model="gpt-4o"),
allow_delegation=False,
verbose=True,
tools=[], # attach a real search tool in production
)
writer = Agent(
role="Technical Writer",
goal="Convert research notes into concise engineering documentation",
backstory="You write for practitioners and cut filler ruthlessly.",
llm=ChatOpenAI(model="gpt-4o"),
allow_delegation=False,
verbose=True,
)
Set allow_delegation=False on every worker. In a hierarchical crew, only the manager may delegate. If a worker also delegates, you get recursive spawn loops that silently drain your token budget. When building a crewai hierarchical crew manager agent, this is the first footgun to eliminate.
If you want a single endpoint that fronts 240+ models and automatically falls back when a provider is rate-limited, point ChatOpenAI at n4n.ai’s OpenAI-compatible endpoint instead of a vendor base URL. The client code is identical; only base_url and api_key change.
Step 3: Configure the manager agent
You can pass manager_llm to the crew and let CrewAI build a default manager, or define a custom manager_agent. I recommend the custom agent: it gives you a system prompt and a recognizable log role.
manager = Agent(
role="Engineering Lead",
goal="Decompose the request into atomic tasks and assign each to the correct specialist",
backstory="You value correctness and minimal latency; you never re-assign without new info.",
llm=ChatOpenAI(model="gpt-4o"),
allow_delegation=True,
verbose=True,
)
allow_delegation=True is mandatory. Omit it and CrewAI raises ValueError during crew assembly in hierarchical mode. The manager’s backstory is where you encode guardrails—e.g., “never call writer before researcher has produced sources.”
Using manager_llm instead looks like:
# Crew(process=Process.hierarchical, manager_llm=ChatOpenAI(model="gpt-4o"))
But then you lose the ability to inspect the manager as a first-class agent in crew.agents.
Step 4: Define tasks and assemble the crew
In hierarchical mode you still declare Task objects, but you do not pre-wire context. The manager reads the top-level task and builds the subgraph. Define one objective task:
brief = Task(
description=(
"Produce a 300-word internal note on vector database trade-offs for "
"our retrieval pipeline. Cite at least two authoritative sources."
),
expected_output="Markdown note with inline citations.",
agent=manager, # hierarchical mode reassigns; this is just a placeholder
)
Assemble the crew with Process.hierarchical and your manager:
crew = Crew(
agents=[researcher, writer, manager],
tasks=[brief],
process=Process.hierarchical,
manager_agent=manager,
verbose=True,
max_rpm=30, # hierarchical spikes concurrency; throttle
)
If you chose manager_llm, exclude manager from agents and drop manager_agent. Passing both triggers a validation error. The max_rpm cap protects shared model endpoints from the burst of parallel calls a manager can generate.
Step 5: Run the crew and verify success
Execute synchronously:
result = crew.kickoff()
print(result)
Verification should be multi-layered, not just “it printed.” Do these:
- Read the manager log. With
verbose=True, you’ll see lines likeManager assigned task X to researcher. Confirm the order matches your intent. If the manager callswriterfirst, yourbrieflacks an explicit “research first” cue. - Measure token spend. Wrap the call or use your gateway’s per-token metering. Expect 3–5× the tokens of an equivalent sequential crew because the manager re-injects context on each handoff.
- Structural assertions. Parse the result:
import re
text = str(result)
assert re.search(r"\[.+?\]\(https?://", text), "missing markdown citation"
assert 250 <= len(text.split()) <= 400, "length out of spec"
- Snapshot history.
crew.historycontains each delegation. Serialize to JSON in CI and diff against a golden file. This catches silent prompt drift in the manager.
If those checks pass, your crewai hierarchical crew manager agent is operating correctly.
How this compares to a sequential crew
A sequential crew for the same note would define research_task and write_task explicitly, with write_task taking research_task as context. It’s 40% cheaper and deterministic. Use sequential when the step graph is known at author time. Use hierarchical when the graph depends on intermediate findings—exactly the case the manager resolves at runtime.
Debugging common failures
- Manager loops: Identical worker calls in logs mean the manager’s plan lacks termination. Add “stop when the note is written” to its backstory.
- Worker returns None: Usually the manager’s subtask is too vague. Make the top-level
descriptiondemand concrete deliverables per role. - Rate limit storms: Hierarchical concurrency is high. Set
max_rpmas shown, or rely on an inference gateway’s automatic fallback rather than writing your own retry.
Treat the manager as a real lead, not a router. With the setup above, you have a reproducible, testable multi-agent system that scales without becoming a token furnace.