You're right that it's "just swap one prompt for another." So what actually changes when people say multi-agent? One thing — and it isn't the prompt. Grounded in your real loop.
May 31, 2026 · grounded in orchestrator.mjs, skills.mjs, router.mjs, tools/registry.mjs
A skill swaps the instructions inside one shared context. A separate agent spins up a second context — its own message history and its own tool set — and hands back only a result. Same model calls either way. The real axis is context isolation + tool scoping, not prompt text. Everything else follows from that one difference.
What actually differs
Both approaches are "call OpenAI with a prompt." Your instinct is correct. Here's the one knob that moves:
Axis
Skill (what you run now)
Separate agent
Prompt / instructions
Swapped — SKILL.md prose injected into the system message
Swapped — sub-agent gets its own system prompt
Context / history
Shared. One message thread. The model sees the whole conversation + every tool result
Isolated. Its own thread. Caller never sees the sub-agent's internal turns
Tools visible
All of them. Every turn loads ALL_TOOLS regardless of skill
Scoped. Sub-agent sees only its 4–6 relevant tools
Output to caller
n/a — it's all one turn
A summary. The messy middle is discarded
New intelligence?
None, either way. Multi-agent is just more loops, scoped differently. No magic appears.
So the prompt is a red herring. The thing that changes is what's in the context window and which tools are on the table. A skill keeps one big shared context; a separate agent fences off a private one.
Where your code sits today
One orchestrator.mjs loop — the only place OpenAI is called. router.mjs picks a SKILL.md to splice into the system prompt (or none, and the model self-selects via use_skill). Crucially: tools are global — the orchestrator loads ALL_TOOLS every turn and the skill prose only suggests which fit. You have skills. You do not have separate agents. That's a fine place to be.
The picture
Left: today. Right: the messy middle (scraping, 6 tool calls, big JSON) stays out of the main thread.
Pros & cons
Skills you, now
one loop, one context, global tools
Pros
Dead simple. One loop to reason about and debug. Your turn-trace captures it cleanly.
No context loss. The model sees the whole conversation — it can't "forget" what another agent knew.
Cheap to add. New workflow = drop a SKILL.md + one registry line.
Model self-routes via use_skill — no routing layer to maintain.
Cons
Context bloat. Every tool result + all history piles into one window. Long jobs balloon it.
Tool overload. All ~10 tools shown every turn; at 20–30 the model mis-picks more.
Generalist prompt. One system message trying to be triage + dispatch + follow-up.
Separate agents later, selectively
isolated context, scoped tools
Pros
Clean main thread. A verbose job's 10 tool calls collapse to one summary line.
Sharper tool selection. 5 tools beat 30 for accuracy.
Independent tuning. Own model (cheaper for narrow jobs), own iteration cap, own evals.
Cons
Handoff context loss — the big one, see below.
More moving parts — routing, state, tracing across loops.
Latency stacks — sequential model calls add up.
Overkill at your scale — solving a problem you don't have yet.
The #1 cost of going multi-agent
⚠ Handoff context loss. A sub-agent only knows what you pass it. Forget to forward one fact — the tenant already said the leak is under the sink, the owner caps repairs at $500 — and it makes a worse decision than your single agent would have, because your single agent saw everything. This is the most common way real multi-agent systems get dumber, not smarter. Skills are strictly safer for correctness; multi-agent trades that safety for a cleaner context and tighter tools. Only make that trade when the bloat is actually hurting you.
What you should do
Stay on skills. Peel out one sub-agent only when the context tells you to.
Now: skills are the right call — 2 skills, ~10 tools, one conversation per handle. Nothing is bloated. Keep adding workflows as SKILL.md files.
The tripwire: the line that loads ALL_TOOLS every turn. When tool count crosses ~15–20, or one workflow generates verbose intermediate output that crowds the thread, that's the signal — not a calendar date.
First thing to peel out: the PMS / AppFolio dispatch flow. It's self-contained, tool-heavy (scrape, match, send), and spits out messy intermediate JSON you don't want in the main context. Textbook sub-agent.
How — no framework: a sub-agent is just a tool. Write dispatch_vendor whose run() fires its own scoped model loop (its own prompt + 4–6 tools) and returns a one-line summary. Your orchestrator already runs arbitrary tools — it won't even know the tool happened to call a model inside. That's multi-agent, built from the loop you already have.
Rule: skills until the context hurts; then fence off the worst offender as a tool. You'll never need a framework to do it.