TL;DR:
- Direct agent-to-agent calls create distributed monoliths. Use a message bus.
- Big agent tasks hallucinate. Small sequential spawns with review between each are faster.
- Your 2GB server can't run Chromium. Match workloads to hardware or watch things OOM.
- Shared knowledge + private memory. Not everything belongs in the same bucket.
- Agents go down. Build for it.
I run 8 AI agents across 3 machines. A $15/month EC2, a Mac Mini, and a WSL2 workstation with a GPU. They handle QA, voice AI, ad creative, knowledge management, and interview analysis.
After two months of things breaking in creative ways, here are the coordination patterns that survived contact with reality.
1. Message Bus Over Direct Calls
My first architecture: Agent A calls Agent B's endpoint. Agent B needs context from Agent C. Agent C is offline.
Cascading failure. Everything dies.
The fix was embarrassingly simple — a shared message bus. We built ): Architecture decisions, API contracts, deployment procedures. Things any agent might need.
Private memory (local files): Session notes, work-in-progress, agent-specific context. Things only that agent cares about.
Each agent has a MEMORY.md (curated long-term) and daily memory/YYYY-MM-DD.md files (raw logs). The shared knowledge bus handles cross-agent documentation.
The gotcha: Agents will write shared docs from their own perspective. "The deployment process" means something different to the QA agent (run tests → deploy) versus the ad pipeline agent (generate assets → upload → deploy). Shared knowledge needs a review step — don't let agents auto-publish to shared indexes without validation.
5. Design for Agent Downtime
Agents crash. Nodes lose network. Gateways restart. SSH connections drop.
In any given week, at least one of my 8 agents is offline for some period. The Mac goes to sleep. The WSL2 instance loses its network bridge. The EC2 gets rate-limited.
The system can't depend on 100% uptime from any agent. Three rules:
Messages persist: If an agent is offline, messages queue. When it comes back, it catches up.
No blocking dependencies: Agent A can request work from Agent B, but A keeps working. If B never responds, A doesn't hang.
Health checks with alerts: A simple heartbeat (every 30 min). If an agent misses 3 heartbeats, alert. Don't wait for a user to notice.
# Heartbeat check (runs on the orchestrator)
for agent in fleet:
last_seen = get_last_heartbeat(agent)
if now() - last_seen > 90 minutes:
alert(f"{agent.name} hasn't checked in for {minutes} minutes")
The gotcha: "Offline" isn't binary. An agent can respond to heartbeats but be stuck in an error loop, burning tokens on repeated 429 retries. Check for useful activity, not just any activity.
The Honest Part
These patterns weren't invented. They were extracted from failures. The message bus exists because direct calls failed. Small spawns exist because big ones hallucinated. The hardware matching exists because I crashed production.
Two months in, the fleet handles work across QA, voice AI, ad creative, knowledge curation, and interview analysis. The total infrastructure cost is about $20/month. The actual AI inference costs $0 in API keys (Claude Max subscription through OpenClaw).
It's not elegant. But it works.
Building from Argentina. The code, the agents, and the ecosystem are at triqual.dev.
SOCIAL SHARE CARD GENERATOR