Eight AI Agents, One AMD Box: My Local Agent Stack (OpenClaw)
- Category
- AI & Local LLM
- Posted
- July 11, 2026
- By
- Jacob Lloyd β written with AI assistance, post-project
- Read time
- 8 min read
In plain terms: A tour of the eight AI helpers running on one small computer in my house, each with its own name and job β from answering family questions to drafting emails. Most of the work costs nothing because it runs locally, and private conversations never leave the building. It shows what a household AI setup can look like without monthly fees.
There are eight AI agents with names living on a mini PC in my house right now. They have jobs, a pecking order, and a group chat my whole family can open from a phone. Running all of them costs about $24 a month β DeepSeek's cheap API does the day-to-day thinking, and the jobs that shouldn't leave the house run on free local models.
tl;dr
- What it is: OpenClaw, a self-hosted AI agent gateway, running 8 named agents β each with its own job, model routing, and tool permissions β behind a chat app I built.
- What it costs: about $24/month of DeepSeek API for the day-to-day work; $0 for the local models that cover vision and private jobs.
- What you need: a machine with serious memory (mine: 128GB unified, 64GB as VRAM), Linux, and patience for systemd.
- What you end up with: one chat URL for the whole house, agents that hand work to each other and chase the ones that go quiet, local image generation, and email drafts that nothing sends without me.
What you end up with
The day-to-day first. This is DisPatch, the chat app I built to front the gateway β shots are sandbox demo data from that write-up, my real threads stay mine.



| What | The number |
|---|---|
| Named agents | 8 (Bits, Flash, Brains, Hermes, Doxy, Charley, Alpha, Beta) |
| Cloud models in the routing table | 2 (DeepSeek flash and pro) |
| Local model entries | ~7 on the main box, 6 more on a second PC for overflow |
| Biggest local model | a 120B-parameter MoE, running on an integrated GPU |
| Measured monthly cloud bill | about $24 (DeepSeek, the primary driver) |
| Gateway port | 18789 |
| Chat port | 8765, on the home network |
| Nightly backup | 02:17 |
| Gateway heartbeat | every 2 hours |
| Watchdog window | 5 minutes, then a silent worker gets chased |
The box
All of this runs on one machine. No rack, no cloud GPU rental, no second mortgage.
- AMD Ryzen AI Max+ 395 ("Strix Halo") β 32 threads, Radeon 8060S integrated GPU
- 128GB unified memory, 64GB of it carved out as GPU VRAM (the OS sees roughly 62GB left over)
- 1TB NVMe, running Bazzite Linux (immutable, Fedora Atomic-based)
- ROCm, not CUDA β behaves a little differently than the tutorials assume, but it works
That 64GB carve-out is the headline: enough to run a 120B mixture-of-experts model locally, at usable speed, on an integrated GPU. A second PC on my network serves overflow and fallback models.
The cast
Instead of one chat tab talking to one model, I've got a small office. Everyone has a job and a model that fits it β cheap DeepSeek cloud for most of the work, free local models where privacy or vision matters. (The local models were the original plan; in practice their load times and lower ceiling made them the fallback tier, not the default.)
| Agent | Job | Primary model | Runs on |
|---|---|---|---|
| Bits | Front desk. Talks to me, does zero tool work herself, farms everything out | DeepSeek (cloud, flash tier) | cloud |
| Flash | Quick jobs β summaries, lookups, routine edits. Zero personality, pure tool | DeepSeek (cloud, flash tier) | cloud |
| Brains | Hard thinking β architecture, debugging, code review | DeepSeek (cloud, pro tier) | cloud |
| Hermes | Deploys and coding, bridged in through a separate agent runtime. Dry-run by default; real deploys need my explicit go | DeepSeek (cloud, pro tier) | cloud |
| Doxy | Bulk grinding work. No API meter on a local model, so it runs all night for free | 120B MoE (local) | this box |
| Charley | Vision β actually looks at screenshots, diagrams, error dialogs | Gemma-4 31B, vision-capable (local) | this box |
| Alpha / Beta | Safe "front desk" bots for family devices, read-only tools only | flash (cloud) / Gemma-4 26B (local) | mixed |
Every agent has fallback models β if the primary is busy or down, it quietly drops to a backup, cloud or local. Beta and Charley are hard-restricted to read-only tools: look things up, make pictures, never touch files or run commands. Exactly what you want in a bot a ten-year-old can open. Cross-agent messaging is on, gated by an allowlist of who may talk to whom.
The pieces
None of this is one program. It's eight small services, each doing one job, all supervised by systemd instead of a babysitting script.
| Service | What it does | Where |
|---|---|---|
openclaw-gateway.service | The OpenClaw gateway β the brain of the stack | port 18789, loopback only, token auth |
local-chat.service | DisPatch, the chat front end | port 8765, LAN |
lm-studio.service | Local model server (an extracted AppImage) serving every local model, plus the embedding model | port 1234, local |
comfyui.service | Image generation (ComfyUI + Z-Image Turbo on the iGPU) β agents and chat can start and stop it | local, on demand |
openclaw-email.service | Email triage β drafts replies, never sends one | β |
hermes-gateway.service | A separate gateway bridging in the deploy/coding agent | β |
openclaw-backup.timer | Nightly backup | fires at 02:17 |
dispatch-tracker-watch.path | The watchdog trigger (more on this below) | β |
Every unit restarts itself on failure, tuned so a crash means seconds of downtime, not a 2am page. The LM Studio unit health-checks its own API before calling itself ready. The gateway's config hot-reloads, so most routing changes need no restart. Auto-update is off on purpose β an update broke the stack exactly once, and now version bumps happen on my schedule. Checking on the whole zoo:
systemctl --user status openclaw-gateway local-chat lm-studio comfyui
journalctl --user -u openclaw-gateway -f
How a chat message actually moves
The route is what you'd guess: browser β DisPatch β gateway β the agent's model, local or cloud, and back the same way. Two details matter: if the primary model is busy or down, a fallback answers instead, and delivery back to the browser is acknowledged over redundant paths, so a dropped connection doesn't lose the message.
Getting real work done
Chat replies are the easy case. The useful pattern is asking for something big and letting the roster sort out who does it.
The heavy lifting β batch image work, long refactors, anything boring β goes to Doxy on the free local 120B, which will grind for an hour for the cost of electricity.
Keeping tabs on itself
Dispatched work that silently dies is worse than work that never started β you don't find out until you go looking. So there's a watchdog, the one piece of this stack I'm actually proud of.
This replaced a genuinely bad idea: a perpetual every-five-minute LLM cron. It spammed the model and caused its own request timeouts β the watchdog was creating the exact problem it existed to catch. The event-driven version arms only when there's a dispatch to watch, then deletes itself either way.
What it costs
The economics are the whole point of the roster split. Cloud pricing, per million tokens:
| Model | Input | Output |
|---|---|---|
| DeepSeek flash tier (Bits, Flash, Alpha) | $0.14 / M tokens | $0.28 / M tokens |
| DeepSeek pro tier (Brains, Hermes) | $0.435 / M tokens | $0.87 / M tokens |
| Local 120B (Doxy), local vision (Charley), local Gemma (Beta) | $0 | $0 |
Even the "expensive" tier is fractions of a cent per typical request. The real savings are in where the volume sits: repetitive thousands-of-tokens jobs go to the free local model; the cloud meter only spins for judgment calls. Memory search runs on a local embedding model too, so the constant background lookups never touch a paid API either.
The rules it won't break
A gateway that can spawn agents and run tools needs guardrails that don't depend on the model behaving.
- Camera access, screen recording, SMS, and contacts/calendar commands are denied outright at the gateway level β not "the agent shouldn't," actually blocked.
- Beta and Charley get read-only tools. No file writes, no shell, no matter how nicely you ask.
- Plugins are a strict allowlist of seven: two local model providers, DeepSeek, Brave web search, a headless browser, agent-to-agent memory, and the deploy bridge. Nothing else loads, installed or not.
- Hermes β the only agent that can touch production β dry-runs by default. A real deploy needs my explicit go, and my business site's deploys sit behind the same gate.
Gotchas
The honest list β things that actually broke, in the order they bit me:
- Local models need
reasoning: trueset explicitly. Mine emit a separate reasoning stream before the real answer; with the flag wrong, the gateway read that as a stall and killed the request around 6.5 minutes in. The model wasn't stuck β it was thinking out loud on a channel the gateway didn't know about. - Every timeout defaults to cloud speed. A 120B on an iGPU is slow, not broken. I raised provider, turn, and abort timeouts to roughly 20, 30, and 35 minutes; before that, long jobs got killed mid-thought for the crime of being local.
- LM Studio's AppImage SIGBUS-crashed whenever its
/tmpFUSE mount got recycled under memory pressure β a genuine bus error, not an OOM kill. Extracting the AppImage and running it as a plain systemd service ended it. - The messaging allowlist is case-sensitive, but the gateway lowercases agent IDs internally. Cross-agent sends failed until I added lowercase duplicates of every name. No error, no log line β just nothing delivered.
- Cross-agent messaging needs two separate switches β the feature flag and the session-visibility setting. Enable one without the other and the default quietly blocks every send.
- A scheduled LLM watchdog is a self-inflicted outage β the every-five-minute cron story above. Event-driven beat scheduled, easily.
- An agent once resurrected its own bad config. An identity-reconcile pass re-injected a stale workspace file and crash-looped the gateway. Config an agent can touch is config that can bite you back.
- A non-empty plugin allowlist is absolute. Marking an entry
enabled: truedoes nothing if its ID isn't also in the allow list. The allow list wins, silently.