DEV Community

GX Cafe LLC
GX Cafe LLC

Posted on

Your local LLM app needs guardrails before it needs prompts

Most local-LLM tutorials start with the fun part: the prompt. After running a fleet
of autonomous agents on local models 24/7 and logging every failure — the ledger now
holds over eight thousand entries — we start somewhere else.

Here is the single most important thing that ledger taught us: the call succeeding
tells you nothing.
The majority of our contract violations were outputs that were
too short, or empty — while the API returned success. The model answered. The
dashboard was green. Nothing was produced.

So we distilled the survival kit into a scaffold you can stand up in one command:

npx create-local-llm-app my-app
Enter fullscreen mode Exit fullscreen mode

Five files, about 180 lines, plain Node and Express, no framework lock-in. What gets
wired in:

1. An output contract

A contract declares what "done" looks like — and then verifies the artifact itself.
Never a proxy. Not the exit code, not a log line, not HTTP 200. contract.js has
three kinds of clause:

  • minChars — the cheapest check, and statistically the most valuable
  • must — patterns that have to appear
  • mustNot — leftover placeholder tags, unfinished markers, refusal leakage ("as an AI, I cannot…" inside what was supposed to be a business document)

Every mustNot entry exists because it caught a real production failure.

2. Retry that feeds failures back

When the contract rejects an output, the failure reason goes into the next prompt.
Three strikes and the item is rejected outright — there is no "accept with warnings",
because accept-with-warnings is "apologize later" with extra steps.

3. An approval queue

Nothing the model writes leaves the app without a person pressing approve. No
decision means no. That rule comes from experience: an unattended script once
contacted a real company because its default was "send". The dangerous side is
never the default here.

4. Two watchdogs

A heartbeat (is the process alive?) and a silent-zero check (is anything actually
being produced?). These are different questions. Running is not the same as
producing — a fleet can be 100% "up" with zero output all day, and nothing in a
standard health check will tell you.

Why so small?

Because the guardrails are the product; the model is replaceable. Swap Ollama
models in .env, replace the prompts with your own business task, and the
contract/queue/watchdog skeleton stays exactly where it is.

If you want to go deeper, the checker we run in production is free and MIT:
honto-contract. A free snapshot of
the failure ledger behind all of this is on
Hugging Face.

Start with the scaffold, break every guard on purpose, and watch them hold. That is
the fastest way to trust your own unattended setup.

Top comments (0)