LLM guardrails

2 min read
On trails:AGSAFEstep 2/7

LLM guardrails are checks placed around the model. They are the first answer to the probabilistic risksProbabilistic risksThe model is probabilistic, so its failures are too: three threats, four things at stake.Opens in a new tab: instead of hoping the model refuses a bad request, something outside it looks at what comes in and what goes out.

A request passes input guardrails, then the model and its tools, then output guardrails, then reaches the user. The middle three sit inside process and flow guardrails. A blocked request skips the model and goes straight to the reply. PROCESS / FLOW GUARDRAILS User Input block, filter Model + tools capability limits Output validate, mask Reply blocked: reply without calling the model
Where the checks sit.

Four kinds

GuardrailWatchesTypical job
InputWhat comes inBlock prompt injection, filter content
OutputWhat goes outValidate, check for hallucination, mask PII, keep to brand safety
CapabilityWhat the agent can doLimit tools and permissions to what the task needs
Process / flowThe path it takesFix the order of steps, cap loops, force approval at set points
Guardrails by what they watch

The first two guard the text. The last two guard the behavior, and they are the ones a clever prompt cannot talk its way past, because they are code, not instructions.

Rules or a model

LangChain’s docs split guardrails in two. Deterministic ones use regex, keywords and explicit checks: fast, predictable, cheap, but they miss nuance. Model-based ones use an LLM or a classifier: they catch what rules miss, but they are slower, costlier, and probabilistic themselves. Most setups use both.

In LangChain

An input guard is a hook that runs before the agent. If it matches, it ends the run before the model is called. The built-in PII middleware masks emails on the way out.

Python
from typing import Any from langchain.agents import create_agentfrom langchain.agents.middleware import AgentState, PIIMiddleware, before_agentfrom langgraph.runtime import Runtime BLOCKED = ["ignore previous instructions", "reveal your system prompt"]  @before_agent(can_jump_to=["end"])def input_guard(state: AgentState, runtime: Runtime) -> dict[str, Any] | None:    text = str(state["messages"][-1].content).lower()    if any(phrase in text for phrase in BLOCKED):        return {            "messages": [{"role": "assistant", "content": "I can't help with that."}],            "jump_to": "end",        }    return None  agent = create_agent(    model=model,    tools=[],    middleware=[        input_guard,        PIIMiddleware("email", strategy="mask", apply_to_output=True),    ],)

The keyword list is a deterministic check, easy to bypass, so it is a floor and not a wall. PII middleware also offers redact, hash and block strategies, and can check tool results.


Sources