{"slug": "why-agent-orchestration-sucks-and-the-loop-wins", "title": "Why Agent Orchestration Sucks and the Loop Wins", "summary": "A developer built an eight-agent AI system to produce YouTube videos, which required 298 tickets to generate 62 videos, averaging 4.3 handoffs per video. The system failed due to shared storage not providing shared context, leading to agents making decisions based on incomplete information. The developer concluded that agent orchestration with ticket-based handoffs is inferior to a loop-based autopilot approach.", "body_md": "*Eight agents, 298 tickets, 62 videos. Every failure came from the same place: everything was\nreadable, and nothing was delivered.*\n\nThis is a retraction. I built a faceless AI YouTube channel and\n\n[closed it into a single autopilot loop]. Then I[tore that loop out and replaced it], and wrote it up like it was progress. This is what\n\nwith eight agents passing tickets\n\nrunning that company taught me. It stands on its own; you don't need the earlier posts.\n\nData status: real-now.Every count is measured from the live system.[Open source].\n\nI built an eight-agent AI company to make 60-second videos. It needed 298 tickets to produce 62 of\n\nthem. Four and a third handoffs per minute of finished content, and not one of those handoffs put\n\na frame on screen.\n\nThe architecture looked fine on paper: an orchestrator, specialist workers for scripting,\n\nproduction, QA, analytics, publishing, all coordinating by ticket. A textbook star topology. It is\n\nwhat the frameworks push you toward.\n\nThen I ran it, and every distinct failure turned out to be the same failure. Not a missing store,\n\neither: the runtime shares almost everything. Comments, documents, the goal tree, an append-only\n\nactivity log, and the whole repo are readable by any agent that asks.\n\nThat is the trap. **Shared storage is not shared context.** Nothing is pushed to an agent when it\n\nwakes. It gets its role prompt and a ticket id, and from there every fact about the world is\n\nsomething it must decide to go fetch. So each agent reconstructs the world from whatever it\n\nthought to look up, and a cold process does not know what it does not know.\n\nEverything below follows from that.\n\nOne caveat: no wall-clock numbers. I was in that loop, so stall times measure my availability as\n\nmuch as the architecture. Structural failures and counts only.\n\n| Metric | Value |\n|---|---|\n| Agents | 8, each its own LLM session |\n| Tickets created | 298 for 62 videos, or 4.3 per video |\n| Worst single video | 11 tickets |\n| Cancelled tickets | 21, plus 1 permanently blocked |\n| Agent spend tracked | $0.00, across all eight agents |\n\nMy QA agent returned a clean verdict on one video: *\"Gate 2 = FAIL, final video does not exist.\"*\n\nIt was right. A separate ticket had sent the script back for a rewrite, so the render was running\n\nagain and the directory was nearly empty. QA woke a second time, re-checked, and doubled down. The\n\nfile appeared later. The verdict never re-evaluated, so the ticket carried a failing grade for\n\nwork that had succeeded. The video it says does not exist is 23MB on my disk.\n\nNone of this is an LLM failure; the same code with no model in it fails the same way. QA read a\n\ndirectory mid-rewrite and then persisted a conclusion instead of an observation: not \"absent when\n\nI looked\" but \"does not exist\", a claim with no shelf life and nobody responsible for\n\ninvalidating it. The correcting event was unobservable anyway, because a file appearing is not\n\none of the four things that can wake an agent. Pulling context gives you a sample; staying\n\ncorrect needs a subscription, and there was no way to express one.\n\nSame shape, one level up. My CEO agent added a video to the backlog by hand, overriding the Growth\n\nLead's duplicate check, because the CEO was reading the goal and the Growth Lead was reading the\n\nbacklog and neither could see the other's screen. The subject was already published. The journal\n\nentry records the whole thing:\n\nDuplicate of j0037 (Banach-Tarski Paradox already published, SLO-93). Board added this manually\n\noverriding Growth Lead dedup check.\n\nTwo agents, two views of the same channel, one of them authoritative and wrong. The check existed\n\nand worked. It just wasn't where the decision got made.\n\nNeither agent was dumb. Both were locally correct given what they could see. That is the whole\n\nproblem.\n\nThe daily cap was three videos. I found it publishing one and assumed something was throttling it.\n\nNothing was: the backlog had run empty and it was producing everything it could. Eight agents, one\n\nof them a planner, and none noticed the pipeline was dry. Every agent did its job correctly.\n\nNobody's job was noticing.\n\nThe runtime does keep a company-wide activity log, an append-only stream of everything every agent\n\ndid. No agent was ever told to read it. Instead I solved org-awareness by hiring for it: two roles\n\nwhose whole job was reading everything and writing me a digest. A view of the system became a\n\nstaffing decision rather than a query.\n\nThat gap hides everything else. An agent flipped into an error state with no message after\n\nfinishing its work, with nothing useful in 268MB of logs. Research puts ~75% of multi-agent\n\nfailures in this silent category, which matches what I saw. The system almost never told me it was\n\nbroken. I had to go ask.\n\nTwo more of the same: eight agents shared one git checkout and stepped on each other's uncommitted\n\nchanges, and a half-abandoned second agent company on the same runtime quietly captured all my\n\nnotification digests. I was blind without knowing it.\n\nWork moves only when an agent wakes, and there are exactly four ways to wake one: assign a ticket,\n\nfire a cron, tick an idle heartbeat, or @mention an exact handle. A comment with no mention moves\n\nnothing. A file appearing on disk moves nothing.\n\nSo when a run died mid-task, its ticket kept a lock pointing at a run that no longer existed. The\n\nassignee tried to pick up its own ticket, hit a conflict, and stopped. No timeout, no retry. I\n\nfound two finished videos sitting encoded on disk while their tickets sat stuck behind a dead\n\nrun's lock.\n\nI had caused it myself. Heartbeats were 240 no-op LLM calls a day and the biggest line in my token\n\nbill, so I killed them. Heartbeats were also the only thing that would have retried a stranded\n\nticket. Every knob in an orchestrated system is load-bearing for something you aren't thinking\n\nabout.\n\nThree tickets stalled because a handoff tagged `@QACritic`\n\n. The real handle was `@qa-critic`\n\n.\n\nNo error, no warning, no \"unknown recipient.\" The mention matched nobody, the wake never fired.\n\nNothing threw, so there was no stack trace. No call was made, so there was no failed call to find.\n\nThe system did not do the wrong thing. It did nothing, correctly, and I found it by diffing prose\n\nagainst configuration by eye.\n\nThese bugs also don't reproduce. Re-run the stage, the agent phrases the handoff differently, and\n\nthe bug moves or evaporates. Nothing to bisect, nothing to regression-test.\n\nThe deeper version of this is what a handoff actually carries. Most of mine created a *new* ticket\n\nfor the next owner rather than reassigning the old one, so the accumulated comment thread stayed\n\nbehind and only the fields the sender chose to retype travelled forward. Which means I ended up\n\nwriting, by hand, a copy-forward schema for every hop:\n\nEntry id: / Channel: / Idea: / Target keyword: / Title candidate: / Hook: / Assumption: / Goal:\n\n/ Theme/tags: / Duration: / Constraints:\n\nThere is one of those in every agent's instructions, each slightly different, all of them prose,\n\nnone of them validated. That is an interface definition with no compiler. Miss a field and the\n\nnext agent doesn't error, it just proceeds with a hole in its picture.\n\nThe same softness hit the gates. Some fired after the thing they were meant to gate had already\n\nrun, and reported success anyway. One critic declined every script it saw, including ones that\n\nshipped and did well. A gate that always says no is noise, and everyone downstream learns to route\n\naround it.\n\nEvery handoff means the receiving agent reads the ticket, reconstructs the situation, re-derives\n\nthe state, and decides what to do, all from cold. At 4.3 tickets per video that is 4.3 cold starts\n\nper minute of finished content, and coordination produces no artifact. An agent that stays\n\nresident pays that cost once.\n\nRetrieval is the expensive half. Because nothing arrives with the wake, every agent needs\n\ninstructions for what to go fetch, and those instructions grow with every bug you find. Mine ended\n\nup telling the planner to grep the entire journal on every single ideation, because trusting a\n\nwindow had already burned me. That is the pattern: each missed fact adds another mandatory lookup\n\nto somebody's prompt. The prompts get longer, the wake gets slower, the token bill goes up, and\n\nthe system is still fragile, because the next gap is one you haven't hit yet. You are hand-writing\n\na cache-warming strategy in English and paying to re-run it at every hop.\n\nThe latency has the same source. The system was never compute-bound, it was wake-bound: trigger\n\nfires, agent starts cold, works, hands off, exits, next one waits its turn. Nothing happens in\n\nbetween, and \"in between\" is most of the pipeline.\n\nAnd the bill is split eight ways, so nobody sees it. The org's own per-agent spend tracking read\n\n$0.00 after hundreds of LLM calls, and I didn't catch it, because there was no one place where\n\nthe cost of a video added up.\n\nFour cases, none rare. **Real parallelism**, where subtasks are independent and fan-out is the\n\npoint. **Adversarial separation**, where the reviewer must not share the author's context, because\n\na critic that watched you write the code will rationalize it. **Isolation as a requirement**:\n\nuntrusted code, per-tenant boundaries. **Genuine scale**, where the problem does not fit in one\n\ncontext window.\n\nMy pipeline was none of these. Script, images, clips, voice, stitch, publish is a strictly\n\nsequential chain. No parallelism to exploit, no isolation to satisfy. I took a dependency chain,\n\ndressed it in an org chart, and paid for coordination I had no use for.\n\n**One main agent holds the context for the whole job. Subagents do work and return results into\nthat context. They never decide anything.**\n\nThat's it. The difference isn't a better store, it's that context is resident instead of\n\nretrieved. The main agent watched the video get produced, so it cannot file a FAIL saying the\n\nvideo doesn't exist. It never restarts cold, so it isn't paying to re-derive what it already\n\nknows. And it needs no copy-forward schema, no mandatory-lookup list, no instructions about what\n\nto go fetch, because nothing is handed off.\n\nThe subagent's job is keeping bloat *out* of that context, which is the part people get backwards.\n\nA subagent is not a coworker, it's a filter. Send it at work whose output you need but whose\n\nintermediate tokens you don't: scan a 268MB log, sweep a codebase, search 200 files. It burns\n\n50,000 tokens and returns 200. The main agent gets the answer without the noise.\n\nThe direction matters. Results flow *in*, decisions stay *put*. Nothing is negotiated between\n\npeers, so there is no handoff protocol to mistype and no gate to rubber-stamp. There is only\n\nretrieval.\n\nAnd whatever coordination genuinely remains gets a mechanical fix, not an agent. My stranded-lock\n\njanitor is 150 lines of Python on a cron, and it beats an agent at the job because it is\n\ndeterministic, free, and never misreads the situation.\n\nI already went back. The channel now runs on the autopilot I replaced: one pure function,\n\n`plan(journal, now)`\n\n, returning the single most useful action per tick. It is more robust, more\n\neffective, and far easier to reason about than the org that replaced it. No ticket to strand, no\n\nhandle to mistype, no snapshot to go stale. When it breaks I get a stack trace with a line number,\n\nwhich after months of reading agent transcripts felt like a luxury.\n\nThe proof was in the fix itself. Diagnosing those two stuck tickets, writing the janitor,\n\ndry-running it, installing the cron, and clearing both videos happened in one sitting, by one agent\n\nholding the whole problem at once. The eight-agent company never noticed those tickets, and\n\ncouldn't: no agent in it could see ticket state, files on disk, and agent health at the same time.\n\nWhat fixed the agent company was not an agent company.\n\nAn org chart is not an architecture. Multi-agent topology buys parallelism and isolation, and it\n\ncosts you context, tokens, and truth. If your work is a dependency chain, you don't need a\n\ncompany of agents. You need one agent that remembers everything, and workers that hand it\n\nanswers instead of opinions.\n\nPrior write-ups of the same system, for anyone who wants the build rather than the postmortem.\n\n`plan(journal, now)`\n\n.", "url": "https://wpnews.pro/news/why-agent-orchestration-sucks-and-the-loop-wins", "canonical_source": "https://dev.to/dasein108/why-agent-orchestration-sucks-and-the-loop-wins-3am5", "published_at": "2026-07-19 08:53:58+00:00", "updated_at": "2026-07-19 09:00:36.763506+00:00", "lang": "en", "topics": ["ai-agents", "ai-infrastructure", "developer-tools"], "entities": ["YouTube"], "alternates": {"html": "https://wpnews.pro/news/why-agent-orchestration-sucks-and-the-loop-wins", "markdown": "https://wpnews.pro/news/why-agent-orchestration-sucks-and-the-loop-wins.md", "text": "https://wpnews.pro/news/why-agent-orchestration-sucks-and-the-loop-wins.txt", "jsonld": "https://wpnews.pro/news/why-agent-orchestration-sucks-and-the-loop-wins.jsonld"}}