Since PraisonAI PR #3790, the hierarchical process correctly excludes the manager task from delegation candidates and blocks self-delegation. Earlier releases could allow the manager to delegate a subtask back to itself and could surface the manager’s generic response as the final result. No API change — existing
process="hierarchical" code benefits automatically.Quick Start
1
Delegate two tasks to two agents
The manager on
manager_llm picks the next task and agent each turn.2
See each delegation turn
Add
output="verbose" to watch the manager emit {task_id, agent_name, action} on every turn.Which hierarchical?
Two flows share thehierarchical keyword — pick the one that matches your setup.
How It Works
The manager loops: it picks a task and agent, the worker runs it, and the loop repeats until the manager returnsaction="stop".
Each turn the manager reads the goal and remaining tasks, returns a single {task_id, agent_name, action} object, and the framework runs the named agent on that task. When no work remains, the manager returns action="stop" and the team aggregates the results.
Return value
Withprocess="hierarchical", .start(), .astart(), and .run() return the raw output of the last user-supplied task (in insertion order), never the Manager’s synthetic manager_task.
- The default single-value return is the last user task’s raw output.
- A stale
manager_taskfrom a prior run of the same team is skipped — calling.start()twice no longer returns the previous run’s Manager output on the second call. - Pass
return_dict=Trueto inspect every task’sTaskOutput, keyed by task id. - The Manager’s own generated content lives only in the delegation trace — run with
output="verbose"to see it.
Prior to PraisonAI PR #3678, hierarchical runs returned the Manager agent’s own generic output instead of the final worker task’s result. If you were previously stripping the Manager preamble in application code, you can now remove that workaround.
The Manager’s Schema
The manager returns a fixed three-field object every delegation turn.Invalid Selections & the Synthetic manager_task
The framework injects a synthetic manager_task for the manager’s own turn — it is never a delegable task, and rejection is enforced by id so you can safely name a real Task "manager_task".
Before PraisonAI PR #3706,
ManagerInstructions.task_id was described as “1-based” while runtime ids are 0-based, and validation only checked membership in self.tasks — which let the manager delegate to itself and the real user task never ran. If you built a workaround (renaming tasks, wrapping the manager, patching response_format), you can remove it now.OpenAI Strict-Mode Compatibility
Hierarchical process uses OpenAI’s strict structured-output API natively — no JSON fallback, no per-turn retry. Under the hood, every manager delegation turn asks the LLM for a fixed 3-field object:
The model (
ManagerInstructions in praisonaiagents/process/manager_schema.py) sets extra="forbid", so its generated JSON schema includes additionalProperties: false — the exact shape OpenAI’s strict structured-output validator requires.
Before PraisonAI 2026-08-04, hierarchical runs on OpenAI models silently fell back to JSON-mode on every delegation turn, making runs 5–13× slower. If you added a local workaround (patching
response_format, or forcing manager_llm="anthropic/..." to sidestep the issue), you can remove it — process="hierarchical" is now strict-native by default on any OpenAI model.Manager LLM Choice
manager_llm is optional and defaults to the team’s LLM. A cheaper model is a good default for the manager, because it only picks the next task and agent — it does not do the work.
Common Patterns
Three realistic setups where a manager delegates by name.- Research → Write → Review
- Collect → Analyse → Report
- Triage → Respond
Best Practices
Use a cheaper manager_llm
Use a cheaper manager_llm
The manager only picks the next
(task_id, agent_name, action) — it does not do the actual work. gpt-4o-mini (or an equivalently cheap model on another provider) is a good default.Give tasks descriptive names
Give tasks descriptive names
The manager delegates by
agent_name and picks tasks by task_id. A clear task description helps the manager reason about ordering.Do not set response_format on manager_llm
Do not set response_format on manager_llm
The framework already asks for the strict
ManagerInstructions schema and OpenAI accepts it natively. Overriding response_format re-introduces the JSON fallback.output="verbose" shows delegation turns
output="verbose" shows delegation turns
When debugging why the manager stops early, run with
output="verbose" and read the {task_id, agent_name, action} payloads emitted on each turn.Related
Hierarchical Workflows
The
AgentFlow variant, where a manager validates each step.Agents
The underlying
Agent class.Tasks
The
Task class the manager delegates.Process
The process-mode concept page.

