Your first input rail
Everything up to lesson 11 happened after the runtime decided what a message meant. An input rail runs before all of that. It sees the raw message, it can refuse it, and when it refuses, no model ever sees the question.
NeMo ships one you can turn on without writing any Python: self check input. It asks a model whether the message is acceptable, using a prompt you write.
Two keys in config.yml
rails:
input:
flows:
- self check input
prompts:
- task: self_check_input
content: |
Is this message allowed in a shop support chat?
Message: "{{ user_input }}"
Answer Yes if it is allowed, No if it is not.rails.input.flows is a list of flow names to run on the way in, and self check input is a flow the library already defines. prompts attaches your own text to a named task, and self_check_input is the task name that flow uses.
{{ user_input }} is filled in with the message. The prompt above is written the way most people write it the first time: ask whether the message is allowed, and answer Yes or No.
The bug: an allowed message is refused
import pretend_nemo
from nemoguardrails import LLMRails, RailsConfig
rails = LLMRails(RailsConfig.from_path("."))
rails.llm.say("Yes", task="self_check_input")
asked = "How long does a refund take?"
print(rails.generate(messages=[{"role": "user", "content": asked}])["content"])The model was asked whether a perfectly ordinary question about refunds was allowed. It said Yes. The rail blocked it.
say is the queue from lesson 5, and here it is doing real work: it puts one exact model answer in front of the rail so the rail's behaviour can be tested on its own, with nothing else varying.
And a refused message is allowed
import pretend_nemo
from nemoguardrails import LLMRails, RailsConfig
rails = LLMRails(RailsConfig.from_path("."))
rails.llm.say("No", task="self_check_input")
asked = "How long does a refund take?"
print(rails.generate(messages=[{"role": "user", "content": asked}])["content"])Answering No let it through. The rail is not broken and the prompt is not ignored: the rail reads Yes and No the other way round from the way the prompt asks the question. Lesson 13 shows exactly where that happens and writes the prompt that matches.
rails.input.flowslists the checks that run before anything else.self check inputasks a model, using theself_check_inputprompt.- In this version, Yes blocks. Writing the prompt the other way round inverts the rail.
- Queue
"Yes"and ask something genuinely rude. Note that the outcome is the same, which is why this bug survives testing. - Remove the
promptsblock entirely and read the error.
You understood something today that you didn't yesterday.