DEV Community

Cover image for I thought Siri was enough until I mapped the 5-step voice pipeline and realized local-first beats cloud-only for agent workflows
Lars Winstand
Lars Winstand

Posted on • Originally published at standardcompute.com

I thought Siri was enough until I mapped the 5-step voice pipeline and realized local-first beats cloud-only for agent workflows

I thought Siri was enough until I mapped the 5-step voice pipeline and realized local-first beats cloud-only for agent workflows

I was three hours into a hands-free setup, Siri missed another command, and that was the moment I stopped treating voice as a UX problem.

It’s an architecture problem.

Once I mapped the whole pipeline, the failure mode became obvious:

  1. Wake word
  2. Speech-to-text
  3. Intent routing
  4. Model/tool call
  5. Response

That split changed how I think about voice agents for automations.

If you’re building always-on workflows with Home Assistant, OpenClaw, n8n, Make, Zapier, or a custom agent stack, the question is not "which assistant sounds smartest?"

The real question is:

What should run locally, what should hit the cloud, and what breaks first when the workflow has to survive all day?

While researching this, I ran into a thread on r/openclaw about a local-first voice-driven agent for RSI. What stood out wasn’t just accessibility. It was that the same design pressure shows up everywhere in agent systems: once something is always listening, latency and reliability matter more than model prestige.

The 5-step voice pipeline

Most voice setups look like this:

[wake word] -> [STT] -> [router] -> [LLM/tool] -> [TTS or action]
Enter fullscreen mode Exit fullscreen mode

A lot of teams accidentally send too much of that pipeline to the cloud.

That works in demos.

It falls apart in real use.

Here’s the version I trust now:

local:  wake word -> STT -> intent routing -> simple actions
cloud:                              -> hard reasoning -> optional response generation
Enter fullscreen mode Exit fullscreen mode

The front half is repetitive and latency-sensitive.
The back half is expensive and occasionally ambiguous.

That division matters more than people think.

Why local wake word detection beats Siri for all-day use

Wake word detection is not an intelligence problem.

It’s a speed problem.

Siri, Gemini, and other cloud-heavy assistants can feel polished when everything is ideal. But the first hop is where voice systems win or lose.

If wake word detection is slow, the whole thing feels broken before GPT, Claude, or Grok ever enters the picture.

For always-on systems, local wake word detection wins because it:

  • reacts faster
  • keeps working when the network stutters
  • avoids a remote dependency for tiny commands
  • makes the whole stack feel stable

That’s why Home Assistant Assist is more interesting than it first appears. It gets the split mostly right: keep the wake word and local control path close to the device, then escalate only when needed.

Even modest hardware can do more than people expect. A Raspberry Pi 4 handling multiple streaming Home Assistant voice satellites is already enough for a serious home or office automation setup.

Where cloud-only voice stacks actually fail

Not in the benchmark.

Not in the keynote.

They fail in the boring path:

  • the fifth repeated command that hour
  • the quick “turn on office lights” request
  • the “run the n8n backup job” action
  • the “what doors are open?” status check

That’s where cloud-only stacks feel fragile.

My opinion is pretty blunt here:

Cloud-only voice pipelines are too brittle for all-day agent workflows.

They lose on:

  • wake word latency
  • routine command handling
  • degraded network conditions
  • provider hiccups
  • API throttling and rate limits

If your automation has to run 24/7, that fragility matters more than whether a remote model is slightly better at open-ended reasoning.

The architecture split I’d recommend

This is the version I’d build today.

Keep these parts local

  • wake word detection
  • speech-to-text for short routine commands
  • command routing
  • deterministic actions
  • text-to-speech

Concrete tools:

  • Home Assistant Assist for orchestration
  • whisper.cpp or Whisper for local STT
  • Piper for local TTS
  • OpenClaw or a local automation layer for agent routing

Send these parts to the cloud

  • ambiguous requests
  • multi-step reasoning
  • summarization
  • tool selection across larger workflows
  • long-context synthesis
  • agent tasks that actually benefit from stronger models

Concrete APIs/models:

  • OpenAI-compatible endpoints
  • GPT-5.4
  • Claude Opus 4.6
  • Grok 4.20

That’s the actual hybrid that makes sense.

Not local-only.
Not cloud-only.

Local-first with cloud fallback.

A practical routing rule

If the command is short, repetitive, and deterministic, keep it local.

If the command needs judgment, synthesis, or multi-step planning, escalate it.

Here’s a simple router in Python-style pseudocode:

def route_voice_command(text: str):
    simple_commands = [
        "turn on office lights",
        "run the morning workflow",
        "start the n8n backup job",
        "what doors are open",
    ]

    normalized = text.strip().lower()

    if normalized in simple_commands:
        return {
            "mode": "local",
            "handler": "home_assistant_or_openclaw"
        }

    if len(normalized.split()) < 8 and any(word in normalized for word in ["turn", "start", "stop", "open", "close", "status"]):
        return {
            "mode": "local",
            "handler": "local_router"
        }

    return {
        "mode": "cloud",
        "handler": "openai_compatible_llm"
    }
Enter fullscreen mode Exit fullscreen mode

This does not need to be fancy.

A lot of teams overcomplicate the router and underinvest in the latency-sensitive path.

Example: local-first voice agent with cloud fallback

Here’s the shape of a real system:

Mic
 -> local wake word
 -> whisper.cpp
 -> local intent router
    -> Home Assistant action
    -> n8n webhook
    -> OpenClaw tool call
    -> cloud LLM fallback
 -> Piper TTS
Enter fullscreen mode Exit fullscreen mode

And the glue can be very simple.

Trigger an n8n workflow locally

curl -X POST "http://localhost:5678/webhook/start-backup" \
  -H "Content-Type: application/json" \
  -d '{"source":"voice","command":"start backup job"}'
Enter fullscreen mode Exit fullscreen mode

Call a cloud LLM only for hard requests

curl https://api.standardcompute.com/v1/chat/completions \
  -H "Content-Type: application/json" \
  -H "Authorization: Bearer $STANDARD_COMPUTE_API_KEY" \
  -d '{
    "model": "openai/gpt-5.4",
    "messages": [
      {"role": "system", "content": "You are a voice agent helping prioritize alerts."},
      {"role": "user", "content": "Summarize the overnight alerts, decide which ones matter, and draft a response."}
    ]
  }'
Enter fullscreen mode Exit fullscreen mode

That API shape matters.

If your cloud fallback is OpenAI-compatible, you can slot it into existing SDKs and agent frameworks without rebuilding the rest of the voice stack.

Why the economics change once you route correctly

This is the part people usually ignore until the bill shows up.

If every voice interaction hits a heavyweight cloud model, you get:

  • unnecessary latency
  • unnecessary cost
  • unnecessary operational anxiety

If only the hard requests hit the cloud, the architecture gets cheaper and calmer.

And once your agents are always listening, predictable pricing starts to matter as much as model quality.

That’s why flat-rate compute is a better fit for voice-triggered automations than per-token billing in a lot of cases.

If your system is doing constant low-level listening, routing, retries, and periodic escalations to stronger models, you do not want to watch a token meter every time someone says something vague.

Standard Compute is interesting here for one reason: it gives you an OpenAI-compatible API with unlimited compute at a flat monthly price, while dynamically routing across models like GPT-5.4, Claude Opus 4.6, and Grok 4.20.

For agent builders, that means you can keep the local-first architecture and still have a predictable cloud fallback layer when requests get hard.

That’s a much better operational story than bolting a per-token cloud model onto every voice event.

A simple decision table

Request type Best place to handle it
"Turn on office lights" Local
"Run the morning workflow" Local
"Start the n8n backup job" Local
"What doors are open?" Local
"Summarize overnight alerts" Cloud
"Decide which alerts matter and draft a response" Cloud
"Compare today’s failures to last week and suggest next steps" Cloud

Minimal local components to test this yourself

If you want a practical weekend prototype, I’d start here:

# STT
brew install whisper-cpp

# TTS
brew install piper

# Home automation / local orchestration
# install Home Assistant separately

# Optional: run your own local router service
python router.py
Enter fullscreen mode Exit fullscreen mode

Then wire the pieces together like this:

  1. Wake word fires locally
  2. whisper.cpp transcribes
  3. Local router checks intent
  4. If simple: call Home Assistant, n8n, or OpenClaw
  5. If complex: send to an OpenAI-compatible cloud endpoint
  6. Return response through Piper

That gets you most of the benefit without building a giant framework.

My take after mapping the pipeline

Siri seemed good enough until I looked at where the delays actually came from.

The winner was not local-only.
The winner was not cloud-only.

It was a hybrid:

  • local-first for speed
  • local-first for reliability
  • cloud fallback for the small percentage of requests that actually need deep reasoning

If you’re building voice-triggered automations that need to work all day, this tradeoff matters a lot more than whichever assistant sounds smartest in a demo.

And if those automations escalate to cloud models regularly, the pricing model matters too.

That’s where a flat-rate, OpenAI-compatible fallback like Standard Compute fits cleanly: local where speed matters, cloud where reasoning matters, and no per-token stress in the middle.

If I were building this stack again from scratch, that’s the architecture I’d choose first.

Top comments (0)