"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:
- Static
[[agents]]— predefined local specialists, best for stable project roles. - The
taptool — run a community-maintained specialist with zero config. - The dynamic
agenttool — 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:
[[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-only — allowed_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:
[[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:
> 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 contextEach 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:
{"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:
{"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:
> 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 inboxConcurrency 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
taptool. 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.



