# Weekend #2: Scafolding the 3-Way LLM Orchestration

> Source: <https://dev.to/jsulaiman/weekend-2-scafolding-the-3-way-llm-orchestration-4f4i>
> Published: 2026-07-25 00:53:26+00:00

Last time, I closed with a line I half-meant as a joke: "a 3-way orchestration between ChatGPT, Claude, and my local LLM, to maintain my vibe coding momentum even when I hit token usage limits." One of you commented that you couldn't wait for your Claude Code session to refresh at 9:50am. Same feeling, different weekend. So this time I actually built the thing.

**The question that started it**

I'm running Qwen 2.5-Coder 32B locally via Ollama on an M1 Max, 64GB unified memory — fixed hardware, not upgrading it any time soon. The question was blunt: can this local setup actually stand in for Claude Code when I hit a wall, or am I fooling myself?

Short answer: not as-is, but closer than I expected. Qwen2.5-Coder 32B benchmarks around GPT-4o territory — fine for autocomplete, weak on the multi-step, tool-calling agentic work Claude Code does well. The real fix wasn't a bigger local model alone, it was pairing a better local model with a proper agent harness instead of raw Ollama chat.

**What changed on the local side**

Swapped in Qwen3-Coder-Next — a MoE model, 80B total params but only 3B active, so it actually fits in 64GB unified memory (tight: ~49GB at Q4, so nothing else memory-hungry runs alongside it). Benchmarks land close to Sonnet-4.5-class coding performance, which is the first time "local" has felt like a real second seat at the table rather than a toy.

Harness matters as much as the model. Raw ollama run isn't an agentic loop — I put OpenCode in front of it instead, which turns the local model into something that can actually read a repo, plan, and edit multiple files with tool calls, the same shape of workflow Claude Code and Codex CLI already give me.

Building the actual orchestration

This is the part I actually spent the weekend on: agent-orchestra, a small, transparent coordinator that lets me hand a task to Claude Code, OpenAI's Codex CLI, or my local OpenCode+Qwen agent — and run all three in parallel against the same repo without them stepping on each other.

**The mechanics, deliberately boring:**

Git worktrees — every task gets its own branch and its own working directory, so three agents can edit the same repo at once with zero collision.

A stdlib-only Python dispatcher (orchestrate.py) — no dependencies, ~250 lines, add/run/status/review/merge/discard as subcommands. Queue a task, walk away, come back to a diff.

No auto-merge, anywhere. Every agent's output lands on its own branch, gets auto-committed for a clean diff, and sits at status: review until I explicitly merge it. Treat every agent like a fast, inconsistent junior dev — because that's what it is.

Per-agent concurrency caps — the local model is capped at one concurrent job (only one thing realistically fits in memory at a time), Claude and Codex get more headroom since they're just network calls.

Before trusting any of this with real work, I wrote fake claude/ codex/opencode stand-ins and ran the whole add → run → review → merge lifecycle against a throwaway git repo. Worth doing — it caught a real bug (worktrees nested inside the target repo cluttered git status with untracked noise), which reshaped the final design: agent-orchestra now lives as its own standalone tool, outside any project it's pointed at, invoked via a shell alias against whatever repo you cd into. Clean separation, no clutter, and it's now getting its own init-repo.sh to turn into a real GitHub repo (gh repo create ... --push, one command).

**The plot twist: almost shipped on a dead product**

I went looking for a nicer interface than raw tmux panes. Found Vibe Kanban — genuinely great looking, real Kanban board, diff review, built-in browser preview, supports exactly the agents I care about. Then I actually opened its GitHub repo and the README's first line now reads: "Vibe Kanban is sunsetting." Glad I checked before building on it.

Landed instead on Claude Squad — actively maintained, same tmux-plus-worktree bones I'd already built by hand, but wrapped in a real terminal UI: a session list, a live diff tab, a one-key commit/push. Configured it with three profiles — claude, codex, local — so switching agents is a picker, not an env var.

**Then I actually ran it**

Design docs are cheap. So I moved the whole thing to ~/tools, ran the install script for real, and let it pull Qwen3-Coder-Next — a genuine 51GB blob, which is exactly the number I'd guessed at on paper. Six tools, one script, no manual intervention: Ollama, Claude Code, Codex CLI, OpenCode, GitHub CLI, Claude Squad, all confirmed working via a check subcommand I'd built specifically so I wouldn't have to take my own setup script's word for it.

Outcome: Claude Code, invoked headlessly, in its own git worktree, wrote a file and a test, committed to its own branch, and sat there waiting for me to review the diff — exactly the shape I designed for. That's the loop working end to end, on real hardware, with a real bug found and fixed along the way instead of staying theoretical.

**Two ways to drive it now:**

Claude Squad for anything I want to watch happen or steer — day-to-day driving.

orchestrate.py for fire-and-forget batches — queue five small tasks across three agents before bed, review diffs in the morning.

One honest gap: I haven't actually validated the local-model path yet. First attempt sat at "starting on local..." long enough that I bailed and routed that task to Claude instead — Qwen3-Coder-Next's cold start, loading 49GB into unified memory before it generates a token, is a real wait, not a rounding error. Works fine once warm, in theory; I just haven't sat through it yet. Next session's job.

Up next

Now that the three agents can actually share work without me babysitting context switches, the next itch is closing the loop further: can the orchestrator route tasks by difficulty on its own instead of me manually picking an assignee? I still owe the local-model path a real cold-start timing test. And I still owe myself that always-on architecture-hygiene dashboard from last time a proper look.

What's your local-model breaking point — the task you've tried offloading to a local LLM that just wasn't worth the fight?
