Multi-agent lifecycle hooks fire on both sync (
team.start()) and async (team.astart()) workflows, and callbacks may be either regular functions or async def coroutines. See Async and Sync Callbacks below.Quick Start
1
Task Lifecycle Logging
Log every task transition with
on_task_start and on_task_complete:2
Async Workflow with async def Hooks
Run the team with
astart() and use async def callbacks to await I/O directly:3
Custom Completion Checker
Override the default completion logic with your own validation:
How It Works
Async and Sync Callbacks
MultiAgentHooksConfig accepts either regular functions or async def coroutines for on_task_start and on_task_complete.
- In sync workflows (
team.start()), only sync callables are meaningful — anasync defhere would return an un-awaited coroutine. - In async workflows (
team.astart()/arun_task()), the framework detects the callable type and does the right thing:async defcallbacks areawaited inline.- Sync callbacks are offloaded to the default executor via
loop.run_in_executor(None, ...), so a blocking hook can’t stall the event loop.
- Exceptions raised by either callback are logged (
logger.error) and swallowed — they never abort the task.
Global Variables Propagation
Passvariables= once at the team level and every task substitutes them into its description at runtime:
variables= are shallow-copied into task.variables before each task runs (unless the task defines its own variables), then substituted into task.description. The shallow copy means a task mutating its own variables no longer leaks back into the team-level dict, so parallel tasks in a process="workflow" team with async_execution=True on each task don’t stomp on each other.
process accepts "sequential", "hierarchical", or "workflow". Passing any other value (including "parallel") raises ValueError at PraisonAIAgents(...) construction. To fan out tasks in parallel, keep process="workflow" and set async_execution=True on each Task.Configuration Options
MultiAgentHooksConfig SDK Reference
Full parameter reference for MultiAgentHooksConfig
Common Patterns
Pattern 1 — Logging workflow progress
Pattern 2 — Quality gate with retry logic
Pattern 3 — Async I/O in a completion hook
Best Practices
Keep hooks lightweight
Keep hooks lightweight
Callbacks are invoked on the orchestrator’s task-completion path. In sync workflows, an expensive hook blocks the next task. In async workflows, sync hooks are offloaded to a thread executor and
async def hooks are awaited, so blocking work is safer — but a slow hook still increases end-to-end task latency. Prefer async def for I/O-bound work (DB writes, HTTP notifications) and keep CPU-bound work off the hook path entirely.Prefer async def hooks with astart()
Prefer async def hooks with astart()
When you run the team with
astart(), use async def callbacks for on_task_start / on_task_complete so you can await I/O directly. Sync callbacks still work — the framework offloads them to the default executor — but writing them as coroutines is clearer and avoids an unnecessary executor hop.Use completion_checker for quality gates
Use completion_checker for quality gates
The
completion_checker is ideal for enforcing output quality requirements — minimum length, required fields, absence of error text. Return False to trigger a retry and True to accept the result.Don't mutate task objects in hooks
Don't mutate task objects in hooks
Hook callbacks receive task references. Mutating task properties during execution can cause unexpected behavior. Use hooks for observation and notification, not for changing task state.
Related
Async Agents
Run multi-agent workflows with astart()
Hooks
Single-agent lifecycle hooks
Callbacks
Agent callback system
Multi-Agent Execution
Configure iteration and retry limits

