"Refactor the authentication system."

Give that to a single agent and watch it try to do everything at once — gather context, review the existing code, plan the new design, write it, test it — all in one ballooning conversation. It loses the thread halfway through, forgets a decision it made twenty messages ago, and hands you something that's 80% done and 100% untrustworthy. We've all seen the output. I called it the slop tax once.

The fix isn't a smarter model. It's a smaller scope per call. You want one agent gathering context, another reviewing for security, and a third writing tests — each focused, each with its own clean context, reporting back to a coordinator that synthesizes. That's multi-agent delegation, and Octomind gives you three ways to do it depending on how much structure you want.

The Mental Model

Think of your main session as an orchestrator, not a worker. Its job is to break a big task into focused subtasks, hand each to a specialist, and assemble the results. Each specialist runs in its own isolated context with its own tools and — crucially — its own model. A context-gathering agent doesn't need your best reasoning model. A security reviewer does. You decide per agent.

Three ways to spawn specialists, in increasing flexibility:

  1. Static [[agents]] — predefined local specialists, best for stable project roles.
  2. The tap tool — run a community-maintained specialist with zero config.
  3. The dynamic agent tool — let the orchestrator invent a specialist on the fly.

Let's walk through each.

Option 1: Static Agents You Define Once

When you have specialists you'll reuse across a project, define them. A sub-agent is a role plus an agent entry that points at it.

First the roles. Note that every field except model is required — system, welcome, temperature, top_p, top_k all have to be present or the config won't load. Set welcome = "" for agents you never start interactively:

toml
[[roles]]
name = "context_gatherer"
model = "openrouter:google/gemini-2.5-flash-preview"  # fast, cheap, big context
temperature = 0.2
top_p = 0.7
top_k = 20
welcome = ""
system = """
You are a codebase researcher. Find the relevant files, read key interfaces
and signatures, note patterns and dependencies, and report findings concisely.
Working directory: {{CWD}}
"""

[roles.mcp]
server_refs = ["filesystem"]
allowed_tools = ["filesystem:view", "filesystem:workdir"]

[[roles]]
name = "code_reviewer"
model = "anthropic:claude-sonnet-4"  # best reasoning where it matters
temperature = 0.1
top_p = 0.7
top_k = 20
welcome = ""
system = """
You are a senior code reviewer. Flag security vulnerabilities, performance
issues, and error-handling gaps. Be specific: file, line, issue, suggestion.
Working directory: {{CWD}}
"""

[roles.mcp]
server_refs = ["filesystem"]
allowed_tools = ["filesystem:view"]

Two things to notice. The cheap model goes to the researcher; the expensive model goes to the reviewer. And the reviewer is read-onlyallowed_tools = ["filesystem:view"] means it physically cannot edit your files. A reviewer that can't write is a reviewer you can trust.

One caveat before you copy this: filesystem isn't a built-in server. Those tools ship with Octomind's default tap (muvon/tap), so if you've disabled MCP or removed that tap, server_refs = ["filesystem"] resolves to nothing. The tap system docs cover how the filesystem tools become available.

Now expose them as tools:

toml
[[agents]]
name = "context_gatherer"
description = "Gathers codebase context: files, interfaces, patterns, dependencies."
command = "octomind acp context_gatherer"
workdir = "."

[[agents]]
name = "code_reviewer"
description = "Reviews code for security, performance, and design issues."
command = "octomind acp code_reviewer"
workdir = "."

The positional argument in command is the role name — keep the agent name and role name identical so the wiring is obvious. Each entry becomes a tool called agent_<name>, and the orchestrator calls it like any other tool:

text
> Refactor the authentication module to support OAuth2

AI: "This is complex. Let me gather context first."
    → agent_context_gatherer("Find all auth-related files, interfaces, patterns")
    → agent_code_reviewer("Review src/auth/ for security issues to fix in the refactor")
    → synthesizes both into a concrete plan, then implements with full context

Each sub-agent runs as an isolated subprocess via ACP, does its focused job, and returns. The orchestrator never has to hold all that detail in its own context — it gets the conclusions.

Option 2: Borrow a Specialist from a Tap

Defining roles is worth it for stable specialists. But if someone has already built the agent you need, don't. The tap registry ships ready-made specialists — security auditors, language-specific developers, and more — and the orchestrator can run one directly with the tap tool, no config edits:

json
{"action": "discover", "intent": "review code for OWASP Top 10 issues"}
{"action": "run", "role": "security:owasp", "prompt": "Audit src/auth/ for OWASP issues", "background": true}

discover matches your intent semantically against the registry and returns the best fits. background: true returns immediately and drops the result into your session as a message when it's done. This is the lowest-friction path: a whole specialist agent, its own system prompt and toolkit, summoned for one task and gone.

Option 3: Let the Orchestrator Invent One

Sometimes the specialist you need is too one-off to define and doesn't exist in any tap. The dynamic agent tool lets the orchestrator create a sub-agent at runtime:

json
{"action": "add", "name": "test_writer",
 "description": "Writes unit tests for given code",
 "system": "You write comprehensive unit tests. Focus on edge cases and error paths.",
 "server_refs": ["filesystem"],
 "allowed_tools": ["filesystem:view", "filesystem:text_editor"]}

{"action": "enable", "name": "test_writer"}

Now agent_test_writer exists for the rest of the session. (Handy shortcut: omit server_refs and the servers are inferred from your allowed_tools prefixes.) Unlike static agents, dynamic ones run in-process — no subprocess spawn — which makes them cheap to create for a single task.

The Real Unlock: Parallelism

Delegation stops being merely tidier and starts being faster when you add async: true. The agent runs in the background while the orchestrator keeps working. Results land in the session inbox when each finishes:

text
> Run the quarterly security audit on the whole codebase

AI: agent_context_gatherer("Map all external API endpoints", async=true)
    agent_code_reviewer("Scan for OWASP Top 10 vulnerabilities", async=true)
    # both run concurrently; AI continues with other analysis
    # "[Async agent 'context_gatherer' completed]" arrives in the inbox
    # "[Async agent 'code_reviewer' completed]" arrives in the inbox

Concurrency is capped at your machine's CPU core count, and every job is cancelled on session exit, so you can fan out aggressively without babysitting it. For a big audit, two or three agents working in parallel turns a slow serial crawl into something that finishes while you get coffee.

How to Actually Use This

A few rules I've landed on after running this pattern daily:

  • Match the model to the job. Cheap and fast for gathering and grunt work; expensive and smart for review and architecture. This is also your single biggest cost lever — don't pay Sonnet rates to list files.
  • Make reviewers read-only. allowed_tools = ["filesystem:view"]. A review agent that can edit will "helpfully" change things you didn't ask it to.
  • Start with the tap tool. Define static [[agents]] only when no tap covers the role or you need something local-only. Less config is less to maintain.
  • Keep specialists narrow. "Find auth files and report" beats "understand the whole system." The whole point is focused scope per call.

The orchestrator-and-specialists shape is how you get an AI to handle a task too big for one context window: not by making the window bigger, but by never asking one agent to hold the whole thing. The full reference — required role fields, async semantics, tap-run resumption, dynamic agent actions — is in Multi-Agent Delegation.

Get Octomind — and stop asking one agent to do five jobs.