DEV Community

Cover image for I stopped building agent teams and started using AI agent delegation with a queue
Lars Winstand
Lars Winstand

Posted on • Originally published at standardcompute.com

I stopped building agent teams and started using AI agent delegation with a queue

I keep seeing the same architecture mistake:

A team gets one assistant working.

Then they add a researcher agent, a coder agent, a verifier agent, a critic agent, maybe a planner agent, and suddenly GPT, Claude, Gemini, Codex, and a local Ollama model are all passing long prompts back and forth like a broken relay race.

It looks smart in a diagram.

In production, it usually turns into latency, retries, weird state bugs, and a lot of "why did this cost so much?"

My take now is simple:

If you're doing AI agent delegation, start with a shared task queue, one orchestrator, and structured outputs. Not a council of agents debating in a chat.

That pattern is easier to debug, maps cleanly to n8n/OpenClaw/custom workers, and avoids a lot of the cost and context churn that shows up when every subtask hops models and providers.

The architecture that keeps winning

The more I look at real agent systems, the less I believe in agent theater.

If your workflow is mostly:

  • read something
  • extract fields
  • classify it
  • draft a response
  • verify a claim
  • publish or hand off

...you probably do not need five agents talking to each other.

You need:

  1. one orchestrator
  2. a durable queue
  3. workers with narrow responsibilities
  4. typed outputs
  5. retries and idempotency

That's the pattern.

Not glamorous. Very effective.

What I mean by AI agent delegation

When I say "AI agent delegation," I do not mean giving each agent a personality and letting them freestyle.

I mean this:

  • the orchestrator decides the next task
  • the task goes into a queue
  • a worker picks it up
  • the worker returns a structured result
  • the orchestrator decides what happens next

That can still involve multiple models.

But the coordination happens through artifacts and jobs, not through one giant multi-agent chat transcript.

Why queue-based orchestration beats agent chat

The main advantage is control.

With a queue, every handoff is explicit.

You know:

  • what task was created
  • which worker ran it
  • which model handled it
  • what schema came back
  • whether it failed
  • whether it retried
  • what the next transition was

That makes debugging sane.

With a chat-based multi-agent setup, state gets smeared across messages. One bad summary or one malformed handoff and the whole thing gets fuzzy fast.

A practical task queue shape

Instead of this:

  • planner agent asks researcher agent
  • researcher agent asks critic agent
  • critic agent asks coder agent
  • verifier agent reviews everyone

Do this:

{
  "task_id": "task_4821",
  "type": "extract_pricing",
  "input": {
    "url": "https://example.com/pricing"
  },
  "expected_schema": "PricingExtractionV1",
  "priority": "normal"
}
Enter fullscreen mode Exit fullscreen mode

Then let workers consume tasks like:

  • research_company
  • extract_pricing
  • classify_lead
  • draft_email
  • verify_claims
  • generate_patch
  • publish_result

Each worker does one thing.

Each worker returns one schema.

The orchestrator owns the flow.

This maps directly to n8n queue mode

This is one reason I like this pattern so much: it already matches how automation systems scale.

In n8n, queue mode is basically this architecture:

  • main instance receives triggers
  • Redis stores pending executions
  • worker instances pull jobs independently

You enable it with:

EXECUTIONS_MODE=queue
Enter fullscreen mode Exit fullscreen mode

That is not just an n8n implementation detail.

It's a solid mental model for AI orchestration.

If you're already building automations in n8n, Make, Zapier, OpenClaw, or custom Python workers, queue-based delegation fits naturally.

Structured outputs remove a lot of fake multi-agent complexity

A lot of "multi-agent reasoning" is really just compensation for unreliable formatting.

One model returns messy text.
Another model converts it to JSON.
A third model critiques the JSON.
A fourth model repairs the fields.

That is often not intelligence.

It's a schema problem.

If your worker can reliably emit structured output, you can delete a surprising amount of orchestration.

Example worker contract:

{
  "company_name": "Standard Compute",
  "pricing_model": "flat monthly",
  "plans": [9, 29, 99, 399],
  "openai_compatible": true,
  "best_for": ["agents", "automations", "n8n", "Make", "Zapier"]
}
Enter fullscreen mode Exit fullscreen mode

Once outputs are typed, workers become interchangeable.

That matters a lot.

The real unlock: route by task type, not by agent personality

This is where most teams overcomplicate things.

Model switching can absolutely help.

I am not against using different models.

I am against using different models for vague reasons.

Good routing logic looks like this:

Task type Best fit
Repo edits, test fixes, code transforms Codex or a strong coding model
Search-heavy research Gemini
Cheap extraction/classification Ollama with Llama or Qwen
Final synthesis, planning, ambiguous reasoning GPT or Claude

Bad routing logic looks like this:

  • every agent has a favorite model
  • the same 8k-token context gets resent to three providers
  • tasks switch models mid-step without a clean artifact handoff
  • teams assume "more perspectives" means "better output"

Usually it means more latency.

And more cost.

A minimal orchestrator/worker design

Here's the shape I'd build before touching anything fancy.

1. Orchestrator creates tasks

from dataclasses import dataclass
from typing import Any

@dataclass
class Task:
    task_id: str
    task_type: str
    payload: dict[str, Any]
    expected_schema: str


def plan_next_step(document_url: str) -> list[Task]:
    return [
        Task(
            task_id="t1",
            task_type="extract_pricing",
            payload={"url": document_url},
            expected_schema="PricingExtractionV1",
        ),
        Task(
            task_id="t2",
            task_type="draft_summary",
            payload={"url": document_url},
            expected_schema="SummaryV1",
        ),
    ]
Enter fullscreen mode Exit fullscreen mode

2. Workers consume from the queue

import json


def handle_task(task: Task) -> dict:
    if task.task_type == "extract_pricing":
        return run_extraction_worker(task.payload)
    if task.task_type == "draft_summary":
        return run_summary_worker(task.payload)
    raise ValueError(f"Unknown task type: {task.task_type}")
Enter fullscreen mode Exit fullscreen mode

3. Validate output before accepting it

from jsonschema import validate

PRICING_EXTRACTION_V1 = {
    "type": "object",
    "properties": {
        "pricing_model": {"type": "string"},
        "plans": {
            "type": "array",
            "items": {"type": "number"}
        }
    },
    "required": ["pricing_model", "plans"]
}


def validate_result(result: dict, schema: dict) -> None:
    validate(instance=result, schema=schema)
Enter fullscreen mode Exit fullscreen mode

This alone will save you from a lot of downstream chaos.

Ollama makes local workers much more useful now

One reason this queue pattern has gotten better is that local models can participate cleanly when they return structured output.

That means your local extraction worker and your cloud synthesis worker can share the same contract.

Example with Ollama:

curl -X POST http://localhost:11434/api/chat \
  -H "Content-Type: application/json" \
  -d '{
    "model": "llama3.1",
    "messages": [
      {"role": "user", "content": "Extract the country name, capital, and languages for Canada."}
    ],
    "stream": false,
    "format": {
      "type": "object",
      "properties": {
        "name": {"type": "string"},
        "capital": {"type": "string"},
        "languages": {
          "type": "array",
          "items": {"type": "string"}
        }
      },
      "required": ["name", "capital", "languages"]
    }
  }'
Enter fullscreen mode Exit fullscreen mode

That's useful because now you can do this:

  • local model for extraction/classification
  • stronger hosted model for synthesis
  • one queue
  • one schema contract
  • one orchestrator

No agent roleplay required.

The hidden problem with model switching: cache and latency churn

This is the part people skip in architecture diagrams.

Every time you bounce a task between models, you risk paying for:

  • repeated context packing
  • provider round-trip latency
  • cold-ish prompt state
  • duplicated long-context processing
  • weaker cache locality

If the handoff artifact is small and well-defined, that trade can be worth it.

If you're passing giant transcripts around, it usually isn't.

This is exactly why I prefer queue-based delegation over chat-based councils.

A queue pushes you toward small handoffs.

That is good systems design.

OpenClaw is powerful, but it can tempt you into overbuilding

I like OpenClaw for the same reason many developers do:

  • local-first control
  • model-agnostic routing
  • failover options
  • visibility into available providers and workers

But tools like OpenClaw also make it easy to create a six-agent cast just because you can.

You run something like:

openclaw status --all
Enter fullscreen mode Exit fullscreen mode

...and suddenly you're designing a cinematic universe instead of a workflow.

My opinion: use OpenClaw as a control plane, not as an excuse for autonomous chaos.

It should help with:

  • worker assignment
  • routing
  • failover
  • diagnostics
  • model availability

Not with inventing unnecessary conversations between bots.

The 3 patterns I keep seeing, ranked

Here's the opinionated version.

Pattern What happens in practice
Single assistant with tools Lowest orchestration overhead. Best default for many workflows.
Task queue with specialized workers Best balance of control, scale, debuggability, and model flexibility.
Autonomous multi-agent council Highest complexity. Often adds latency, duplicate context, and failure modes faster than it adds value.

If you're moving from one assistant to many, the middle row is usually the right move.

When multi-agent teams actually make sense

There are real cases where more autonomous agent behavior is justified.

Examples:

  • long-running incident response
  • software agents exploring unfamiliar codebases
  • adaptive research systems dealing with contradictory evidence
  • environments where goals change mid-run and the model needs to re-plan

Those are real use cases.

But even there, I still want:

  • explicit artifacts
  • task boundaries
  • stored state outside the chat log
  • schemas for important outputs
  • observable transitions

So yes, autonomy can be useful.

But explicit orchestration still wins.

The setup I'd build tomorrow

If I had to build this in n8n, OpenClaw, or a custom Python stack tomorrow, I'd do this:

1. Keep one planner

Use GPT or Claude only when task decomposition is actually needed.

2. Put every task in a durable queue

Redis is enough for a lot of systems.

3. Force every worker to return typed output

No freeform handoffs if the next step depends on exact fields.

4. Route by task type

  • code_patch -> Codex
  • search_research -> Gemini
  • classification -> Ollama
  • final_synthesis -> GPT or Claude

5. Keep state outside the model

Store summaries, artifacts, retries, approvals, and execution history in your app.

Not in a giant shared conversation.

Why this matters even more when you're paying for AI at scale

Once agent workflows run 24/7, architecture mistakes stop being cute.

Every extra model hop, every repeated long-context call, every unnecessary verifier agent turns into operational drag.

This is also why predictable pricing matters so much for teams building automations and agents.

If you're running queue-based AI workers in n8n, Make, Zapier, OpenClaw, or custom pipelines, per-token billing creates a weird incentive: you start designing around cost fear instead of system clarity.

That's a bad trade.

A lot of teams would rather have one OpenAI-compatible endpoint and flat monthly pricing so they can focus on worker design, routing, and reliability instead of watching token meters all day.

That's the appeal of Standard Compute: unlimited AI compute at a predictable monthly price, using an OpenAI-compatible API, so you can build agent workers and automations without token anxiety.

That model fits queue-based orchestration especially well.

Because once your architecture is clean, the next bottleneck is usually cost unpredictability.

Final take

If your current idea of AI agent delegation is "a bunch of agents talking to each other," I think you're starting in the wrong place.

Start with:

  • one orchestrator
  • one queue
  • specialized workers
  • structured outputs
  • explicit routing

Then add autonomy only where it clearly pays for itself.

Not a council.

A queue.

Boring architecture wins a lot more often than people want to admit.

Top comments (0)