Delegate to child Agents safely
Give a coordinator explicit child routes, attenuated capabilities, depth limits, and policy middleware.
When to delegate
Delegate when a subtask has a distinct instruction set, model, tool set, authority boundary, or budget profile. Do not create a child Agent merely to wrap a function: a typed Tool is simpler and more deterministic.
A useful coordinator decides which specialist should work. Deterministic business code still decides approvals, compensation, and final side effects.
Register a child route
The model sees an AgentDescriptor, while the host owns the actual child
Agent and delegated capability set.
use std::sync::Arc;
use runifold::{AgentDescriptor, CapabilitySet};
let child = Arc::new(
runtime
.agent("researcher")
.system("Research one focused question.")
.build()?,
);
let coordinator = runtime
.agent("coordinator")
.child(
AgentDescriptor::new(
"ask_researcher",
"Delegate one focused research question",
),
child,
CapabilitySet::new(),
)
.max_delegation_depth(3)
.build()?;Route names share the model-callable namespace with Tools. Duplicate names are a build error instead of silent replacement.
Authority attenuation
The parent run must hold the route capability, and every capability requested for the child must already be held by the parent. Delegation can preserve or reduce authority; it cannot amplify it.
Build the child's capability set explicitly. A research Agent normally needs read-only search, not the coordinator's ability to send email or approve a payment.
Gateway policy
Gateway middleware is an around-call boundary for authorization, audit, rate-limiting, input transformation, and deliberate retry. Middleware may deny or observe a call, but it cannot replace route identity or bypass lifecycle, depth, budget, and authority checks.
Put stable business policy in middleware or application code, not in the coordinator's prompt. Test deny-before-I/O behavior.
Failure and accounting
Each successful delegation creates a child Run, consumes the shared delegation budget, and contributes usage to the same run tree. Parent cancellation and deadline propagate to the child.
Set both max_delegation_depth and Budget.delegations. The first prevents
recursive topology from growing without bound; the second controls total work
across siblings and descendants.
Do not blindly retry an interrupted child. It may already have consumed model tokens or completed an external effect. Use checkpoints or the effect boundary when recovery must cross process failure.