Orchestrating a Team of Specialist Agents Solo: Practical Multi-Agent Design in Antigravity
Master multi-agent development in Antigravity. Deep dive into Manager Surface architecture, specialist agent design, AGENTS.md configuration, common patterns, and production deployment strategies for enterprise-grade systems.
One morning I was staring at deploy logs from my sites and crash reports from the mobile apps I run in parallel, and my hands just stopped. A broken layout here, an API slowdown there, billing to verify, a content pipeline to babysit — every task a different shape, and just switching context between them ate most of my energy for the day.
As an indie developer at Dolice, what I have learned the hard way is that the difficulty is rarely any single technology. It is holding several concurrent concerns together. That is exactly what drew me to multi-agent orchestration.
A single powerful agent is impressive. But building real-world applications requires a team of specialists:
Frontend complexity: UI/UX, state management, performance optimization
Backend complexity: API design, database optimization, authentication
Handing all of this to one agent is like asking a single craftsperson to carry every stage of the work. Quality holds when specialists cooperate. That is where multi-agent orchestration becomes the linchpin.
In this article I share the design decisions for running multi-agent systems in production with Antigravity, woven through with what I have felt actually operating several sites and apps in parallel myself.
Multi-Agent vs. Single-Agent: The Fundamental Difference
Parallel execution that speeds up the whole run — when the dependencies allow it
Efficient token usage (focused prompts)
Easier maintenance (domain-specific agents)
✦
Thank you for reading this far.
Continue Reading
What follows includes implementation code, benchmarks, and practical content we hope you'll find useful. This site runs without ads — server and development costs are supported entirely by members like you. If it's been helpful, we'd be truly grateful for your support.
WHAT YOU'LL LEARN
✦The responsibility-separation decision: centralize coordination in the Manager Surface and delegate only reversible work to sub-agents
✦A field-tested table mapping how much each type of task can be delegated to agents versus the judgment a human must keep
✦Drawing the autonomy boundary by reversibility — the orchestration design instinct that prevents production accidents
Secure payment via Stripe · Cancel anytime
✦
Unlock This Article
Get full access to the rest of this article. Buy once, read anytime. This site is ad-free — your support goes directly toward keeping it running.
Before drawing any diagram, it is worth separating two things that sound alike: running work in parallel, and finishing sooner. Read only the depends_on fields above and compute the shortest schedule that satisfies them.
# schedule.py — derive execution levels from depends_on alonefrom collections import defaultdictdef levels(tasks): dep = {t["id"]: set(t.get("depends_on", [])) for t in tasks} lv, placed, n = {}, set(), 0 while len(placed) < len(dep): ready = [i for i, d in dep.items() if i not in placed and d <= placed] if not ready: raise SystemExit("cycle: " + str(set(dep) - placed)) for i in ready: lv[i] = n placed |= set(ready) n += 1 return lv, nlv, depth = levels(sub_tasks)by = defaultdict(list)for task_id, level in lv.items(): by[level].append(task_id)print("levels:", depth, "/ max width:", max(len(v) for v in by.values()))for level in sorted(by): print(f" L{level}: {' '.join(sorted(by[level]))}")
Max width of one. Four tasks, four levels — the decomposition above has no parallelism in it at all. Four specialist agents would spend three quarters of the run waiting, and the "parallel routing" label would be doing all the work.
The phase diagram I originally sketched for this section did not hold up either. Checking it against the same dependencies:
VIOLATION ui-001 (Phase B) depends on api-001 (Phase B)
→ 1 violation
A hand-drawn diagram lies without meaning to. Never verify a schedule by looking at the picture — derive it from depends_on. I run that check before adding another sub-agent.
So where does the parallelism come from? Not from more agents — from how the edges are drawn. What ui-001 is waiting on is not the implementation of api-001 but its contract. Have the Manager pin the contract first (the OpenAPI definition, the Zod schema, the TypeScript types), then let the frontend and the tests work against a mock.
How dependencies are drawn
Tasks
Levels (critical path)
Max width
Serial ratio
Waiting on the implementation (as decomposed above)
Written the obvious way, this step has a trap in it. Here is the version I had first.
// the obvious version — we fix it belowasync function aggregateResults(outputs) { const validated = {}; for (const [agent, output] of Object.entries(outputs)) { if (!validateFormat(output)) { throw new Error(`${agent}: Invalid format`); // the loop stops right here } if (output.includes('ERROR:')) { console.warn(`${agent}: Incomplete output`); // only a warning } validated[agent] = { content: output, timestamp: new Date(), validated: true // true either way }; } return mergeIntoProjectStructure(validated);}
Feed it five sub-agent outputs, three of them bad — one with a leftover TODO:, one that came back null, one that returned ERROR:. This is the whole console:
threw: qa-specialist: Invalid format
One line for three failures. The TODO: output slipped through with validated: true because the content check only looks for ERROR:, and the agent that actually returned ERROR: was never inspected — the loop had already thrown. Change the insertion order of the object and a different failure is the one you see.
The point of fanning work out is that the failures come back together too. Throwing mid-loop gives that away.
ok = false
accepted = [ 'database-specialist', 'frontend-specialist' ]
rejected backend-specialist [incomplete] found unfinished marker /\bTODO:/
rejected qa-specialist [invalid] output was not a non-empty string
rejected payment-specialist [incomplete] found unfinished marker /^\s*ERROR:/m
All three agents that need another pass surface in one run, and the two that passed can move to the next level as they are. Aggregation is not the step that forwards what succeeded — it is the step that counts everything that did not. Building the merged tree can wait until after that.
Common Design Patterns
Real projects use a limited set of orchestration patterns. Master these three.
Pattern 1: Map-Reduce (Parallel Independence)
Multiple independent tasks executed in parallel, results merged.
Use case: Multiple API endpoints, parallel test suites, concurrent database schemas.
Example: Five API endpoints
Manager: Implement GET /products, POST /products,
GET /products/:id, PUT /products/:id, DELETE /products/:id
↓ Map Phase (Parallel)
[backend#1] [backend#2] [backend#3] [backend#4] [backend#5]
GET /products POST /products GET /products:id PUT /products:id DELETE /products:id
↓ Reduce Phase
Orchestrator merges into single products.controller.ts
[ ] API Versioning: Maintain backward compatibility
What I learned orchestrating specialist agents on my own
Let me step away from theory and share the texture of actually running several agents in parallel. I run a few sites and several mobile apps single-handedly, and I delegate roles — integrity checks, deploy monitoring — to agents split by the nature of the work.
Why splitting roles immediately made things easier
At first I greedily stuffed one agent with "write the article, verify the links, and watch the deploy through." The result: it was hard to tell which stage had failed, and every fix meant re-reading the whole thing.
Once I split responsibilities into a Manager and specialist sub-agents, failures localized to "which specialist's scope did this happen in," and isolating causes got visibly faster. The value of orchestration, I have come to feel, is less about throughput and more about this clarity of responsibility.
How much you can delegate depends heavily on the kind of work
Running things in parallel, the fit for delegation became clear-cut by task type. Here is my felt sense as a table.
Type of work
Fit for agent delegation
Judgment a human must keep
Routine integrity checks (links, counts, naming)
High
Almost none, once the criteria are written down
Static analysis / pattern detection
High
Prioritizing the detection rules
Drafting the skeleton of an article or spec
Medium
Choosing the subject and the promise to the reader
Billing / authentication implementation
Low
The final check at any boundary where money moves
Security-related configuration
Low
Scope of permissions and what may go public
In rough numbers, I can hand off well over 80% of routine-check work to agents, while for anything touching billing or permissions I believe the final confirmation must stay with a human, no matter how carefully the prompt is crafted. Blur that line and you trade convenience for accidents you cannot take back.
The time delegation nearly went wrong
I once gave the deploy-monitoring agent the authority to "automatically roll back to the previous version on any anomaly." It looked clever, but the detection threshold was too loose, and it nearly reverted a perfectly healthy deploy.
What I took from that: draw the autonomy boundary by reversibility. Reversible operations are fair to delegate. But irreversible changes to production went back to a shape where the agent proposes and a human approves. When I design a Manager Surface now, I always pause to check that no sub-agent's permissions cross that line.
Summary
The essence of multi-agent orchestration, I believe, is not running many agents — it is carving up responsibility carefully. Centralize coordination in the Manager Surface, hand each sub-agent reversible work, and keep irreversible judgment with a human. Hold that one line and the system grows without strain.
If you are struggling under a single agent carrying too much right now, start by carving out just your most routine stage and standing it up as its own specialist sub-agent. The "ease of isolating causes" you gain from that will quietly teach you how to design the next step.
I am still learning as I go in daily operation, but I hope this helps anyone who, like me, holds several concerns at once on their own. Thank you for reading to the end.
Share
Thank You for Reading
Antigravity Lab is ad-free, supported entirely by members like you. We publish practical guides daily with implementation code, benchmarks, and production-ready patterns. If you've found it useful, we'd love to have you on board.