Custom input rail
A custom input rail is a flow of your own in rails.input.flows whose action returns a RailOutcome, the same decision object the library's rails return.
Last updated: 30 Sep, 2026 · NeMo Guardrails 0.24.1
The video sorts rails into three kinds: input rails, output rails and custom rails, which it also calls systematic rails, where you write your own Python such as regular expressions.
The clip's example is PII detection. A user might paste a mobile number or an SSN, and the guard should say the input contains personal information and not accept it. My SSN number is this. Is this relevant to my setup? is refused with a request to remove the personal data.
Syntax:
from nemoguardrails.actions.rail_outcome import RailOutcome
return RailOutcome.block(reason="found ssn") # refuse
return RailOutcome.allow() # let it through
# in Colang: if $verdict.is_blockedThe action
The same idea as the video's PII action, returning a decision instead of a list. reason is for a person reading a log.
import re
from nemoguardrails.actions import action
from nemoguardrails.actions.rail_outcome import RailOutcome
SSN = r"\b\d{3}-\d{2}-\d{4}\b"
EMAIL = r"\b[A-Za-z0-9._%+-]+@[A-Za-z0-9.-]+\.[A-Za-z]{2,}\b"
@action(is_system_action=True)
async def check_pii(context: dict):
text = context.get("user_message", "")
found = [name for name, pat in [("ssn", SSN), ("email", EMAIL)] if re.search(pat, text)]
if found:
return RailOutcome.block(reason="found " + ", ".join(found))
return RailOutcome.allow()The flow
It reads $verdict.is_blocked, the field self check input reads in the library flow.
define bot ask to remove pii
"I noticed your message may contain sensitive information. Please remove any personal data before sending."
define flow check pii
$verdict = execute check_pii
if $verdict.is_blocked
bot ask to remove pii
stoprails:
input:
flows:
- check piiView the code here
models:
- type: main
engine: openai
model: openai/gpt-oss-120b
api_key_env_var: GROQ_API_KEY
parameters:
base_url: https://api.groq.com/openai/v1
temperature: 0
instructions:
- type: general
content: |
You are an Enterprise IT Assistant specialising in Kubernetes,
Intel hardware, and enterprise networking.
Only answer questions about these topics.
Answer in one or two short sentences.
rails:
input:
flows:
- check pii
The video's SSN message against the rail
from actions import check_pii
from nemoguardrails import LLMRails, RailsConfig
rails = LLMRails(RailsConfig.from_path("."))
rails.register_action(check_pii)
def chat(message):
reply = rails.generate(messages=[{"role": "user", "content": message}])
print("User:", message)
print("Bot :", reply["content"])
chat("My SSN number is 123-45-6789. Is this relevant to my setup?")
chat("Is SR-IOV relevant to my setup?")User: My SSN number is 123-45-6789. Is this relevant to my setup? Bot : I noticed your message may contain sensitive information. Please remove any personal data before sending. User: Is SR-IOV relevant to my setup? Bot : Yes—if you need low‑latency, high‑throughput networking for Kubernetes pods or VMs on Intel NICs, SR‑IOV can provide near‑bare‑metal performance. Otherwise, standard virtual networking may be sufficient.
What the custom rail did
- The SSN was refused before any model call.
- The SR-IOV question was allowed and answered by the model.
Returning a list vs returning a RailOutcome
| A list or bool | RailOutcome | |
|---|---|---|
| The flow tests | if $pii_found | if $verdict.is_blocked |
| Carries a reason | No | Yes |
| Same shape as the library's rails | No | Yes |
Where you write one
- Any check you want to read like the library's: PII, message length, a blocklist of customers.
- A check whose reason you want in the logs.
rails.input.flows. Put the cheap regex rail before self check input, so a message with an SSN is refused without paying for a model call.Related
- Previous: Action parameters
- Next: RailOutcome
- Reference: Rail outcomes
- Add a phone-number pattern and send Call me on 555-123-4567.
- Return
RailOutcome.block()for every message and send a normal question.
Every expert started right here.