Configuring a multi-agent system means getting four things right: the coordinator’s ability to delegate (Task in allowedTools), each sub-agent’s capabilities (tools field), each sub-agent’s identity (description + prompt), and cost/safety knobs (model, maxTurns). Miss any one and you get silent failures, misrouting, or runaway costs.
The coordinator must have Task in allowedTools
The Task tool is the mechanism for spawning sub-agents. If "Task" is not in the coordinator’s allowedTools, it receives a "Tool 'Task' is not available" error when it tries to delegate — regardless of how well its prompt is written. No prompt engineering overcomes a missing tool.
Typical coordinator: allowedTools=["Task", "Read", "Grep"]. Task for delegation, Read and Grep for its own exploration work.
Sub-agent tools: explicit allowlist, not inheritance
Each sub-agent’s tools field in AgentDefinition defines exactly which tools it can use. Omitting the field causes the sub-agent to inherit ALL available tools — including Bash, Write, and Edit it may not need. This is the most common security anti-pattern in multi-agent systems.
A code-review agent with inherited Bash access accidentally executed a command and modified source files. The fix: tools=["Read", "Grep", "Glob"] — read-only. The agent physically cannot call tools not in its list.
Per-agent security boundaries
Different agents need different tool sets matching their roles:
- Code-review:
[Read, Grep, Glob]— read-only, cannot modify anything - Test-runner:
[Read, Grep, Bash]— can execute tests but cannot write code - Deploy agent:
[Read, Bash, Write]— can execute deploy scripts and write config, plus PreToolUse hooks to validate deploy targets and block source file modifications
This is defense-in-depth: even if an agent’s prompt is poorly written, it structurally cannot exceed its tool boundaries.
Tools + hooks for fine-grained control
Sometimes the tools field alone isn’t enough. A deploy agent needs Bash access to run deployment scripts but must not modify .js, .ts, or .py source files. The tools field can’t enforce file-type restrictions within Bash.
Solution: give the agent Bash in tools (capability) and add a PreToolUse hook on Bash that inspects commands for source file modifications and denies them (enforcement). This layers tool-level access with hook-level enforcement for fine-grained security that neither mechanism achieves alone.
description vs prompt: different audiences
description — tells the COORDINATOR when to use this agent. The coordinator reads descriptions to select which sub-agent fits the task. “Handles payment disputes, invoice questions, and subscription changes. Use for any query about charges, payments, or billing history. NOT for refund processing — use the Refund agent.”
prompt — tells the AGENT how to behave. System instructions, behavioral rules, output format. The coordinator does NOT read sub-agent prompts for selection — it uses descriptions.
Description quality drives selection accuracy
Production data from a 4-agent customer support system with vague descriptions:
- Billing (“Handles billing”): 72% correct selection
- Shipping (“Handles shipping”): 68%
- Account (“Handles accounts”): 65%
- Refund (“Handles refunds”): 60%
The fix: expand each description with specific use cases, input types, and boundary conditions — including “NOT for” statements with redirects. A well-described agent on Haiku outperforms a vaguely-described agent on Opus because selection accuracy depends on the description, not the model.
model field: per-agent cost optimization
Sub-agents inherit the coordinator’s model by default. The model field in AgentDefinition overrides this per-agent:
| Agent | Task complexity | Model | Savings |
|---|---|---|---|
| Search | Simple keyword queries | Haiku | ~80% |
| Analysis | Deep paper analysis | Opus | (justified) |
| Synthesis | Moderate combining | Sonnet | ~50% |
A research system spending $3,000/month on all-Opus sub-agents can cut costs significantly by matching model to task complexity. There are no compatibility issues — each sub-agent runs independently, and the coordinator communicates through the Task tool regardless of sub-agent model.
maxTurns: per-agent turn limits
maxTurns caps how many reasoning-action cycles a sub-agent can perform. Set it per-agent based on task complexity:
- Search agent: 3 turns (simple queries, 1-2 tool calls)
- Analysis agent: 15 turns (deep work, many file reads)
- Simple lookup: 2 turns
A uniform limit (e.g., 5 for all agents) may prematurely terminate complex analysis while being unnecessarily generous for simple lookups. maxTurns complements stop_reason: stop_reason handles normal termination, maxTurns provides a safety net against infinite loops.
One-liner: Coordinator needs Task in allowedTools; sub-agents need explicit tools (not inherited), specific descriptions (not vague), per-agent model selection for cost, per-agent maxTurns for safety — and hooks layered on top of tools when fine-grained enforcement is needed.