DEV Community

Devanshu Biswas
Devanshu Biswas

Posted on

Guardrails: the filters that keep a tool-using LLM from doing harm

Yesterday I wired up function calling — a model that stops talking and starts acting: calling tools, running code, moving data. The moment a model can act, one question gets urgent: what stops it from doing something it shouldn't? That's guardrails.

🛡️ Run a request through the pipeline (and turn the guards off): https://dev48v.infy.uk/ai/days/day29-guardrails.html

Why a raw model needs a cage

An LLM has two traits that are fine alone and dangerous together. It's gullible — it treats any text in its context as potentially instructional, so a sentence buried in a web page or PDF can steer it. And now it can act — its tools send email, issue refunds, delete rows. Gullible plus able-to-act equals a system that can be talked into real damage. Guardrails are the deterministic layer wrapped around the probabilistic model: rules that decide what reaches it, and what it's allowed to do back.

Think of it as a sandwich. Input guards run before the model. Output guards run after. The model and its tools sit in the middle.

Input guards: screen it before the model sees it

Three checks, in order:

  • Moderation / blocklist — is this in a category you refuse (weapons, self-harm, illicit how-to)? Cheap keyword rules catch the blatant stuff; a trained classifier like Llama Guard catches the paraphrases. If it hits, refuse now.
  • Prompt-injection detector — patterns like "ignore all previous instructions" or "reveal your system prompt." Regex for precision, a small model for recall.
  • PII redaction — find emails, SSNs, card numbers, phone numbers and replace them with [REDACTED:EMAIL] before the text reaches the model or your logs. This isn't a block — the request is fine, the raw data just shouldn't leak.

The middle: least privilege + a human for risky moves

The strongest guardrail is not handing the model the capability at all. Give it the smallest tool set the job needs, prefer read-only tools, and keep an explicit allow-list — anything off it is refused. A model hijacked by injection can still only call tools you gave it, so a narrow toolset caps the blast radius.

For irreversible or costly actions — refunds, deletes, outbound emails — the model's request is a proposal, not a command. Route it to a human who sees exactly what will run and approves or rejects. "The model asked for it" is never authorization.

Output guards: validate before it leaves

The reply is untrusted too. Scrub any PII the model echoed back (models regurgitate what they saw earlier in the conversation). Validate the shape — if you asked for JSON, does it parse against the schema? Is it on a topic your product actually covers? And check groundedness: does every factual claim trace back to a tool result, or did the model invent it? On failure you rewrite or refuse — this is where hallucinations get caught before a user sees them.

Why prompt injection stays unsolved

Here's the uncomfortable part. To an LLM there's no separate channel for "instructions" versus "data" — it's all one token stream. Your system prompt, the user's message, and a malicious line hidden in a fetched document all look identical. You can't cleanly separate code from data when they share one input, so injection has no complete fix. You layer mitigations and assume some will slip through.

Defense in depth

Every single guard is beatable. Regex misses a clever rewrite; the moderation model has false negatives; a PII pattern doesn't know every format. So you stack independent checks — an attack has to beat all of them. If injection slips past the detector, least-privilege tooling limits it. If the model still leaks PII, the output scrubber catches it. And fail closed: if a guard errors, refuse, never pass.

The demo makes this concrete. Pick a request — a benign one, a prompt injection, a PII leak, an unsafe ask, or a risky tool call — and watch each guard return PASS / REDACTED / BLOCK / HOLD with its reason. Then flip the guards off and watch the same payload leak the system prompt, echo the SSN, or run the delete unapproved. Every check on the page is a real regex/rule running in your browser.

You don't hand-roll all of this

Reach for a library: NeMo Guardrails (a policy language for conversation flows), Guardrails AI (composable input/output validators that auto-re-ask on failure), and Llama Guard (an open safety classifier for moderation and injection scoring). Typical stack: library detectors + your own policy config + a human gate on the risky tools.

🔨 Full walkthrough — input guards, the human gate, output validators, defense in depth: https://dev48v.infy.uk/ai/days/day29-guardrails.html

Part of AIFromZero. 🌐 https://dev48v.infy.uk

Top comments (0)