NeMo Guardrailsnemoguardrails 0.24.0 · Python 3.10+
0%
1
Curious builder0 XP earned · 300 to level 2
0 daysFinish a lesson to begin
Badge collection0 of 6 unlocked
20 small wins to finish your pathNext lesson

stop, and bot refuse to respond

Lesson 13 got the rail answering correctly. This lesson opens it up: self check input is not built into the runtime, it is a Colang flow like the ones you wrote in lesson 8, and you can read it, copy it and change what it says.

The flow the library ships

text
define bot refuse to respond
  "I'm sorry, I can't respond to that."

define flow self check input
  $response = execute self_check_input

  if $response.is_blocked
    do mask blocked user input
    if $config.enable_rails_exceptions
      create event InputRailException(message="Input not allowed. ...")
    else
      bot refuse to respond
    stop

execute runs a Python function, which lesson 16 covers. stop ends the turn immediately, so nothing downstream runs: no intent, no flow, no model call for an answer. bot refuse to respond is an ordinary bot intent, and the first two lines of the file give it its words.

$response.is_blocked is the only field the flow reads. The check returns a small object with a decision on it rather than a boolean, and lesson 19 builds one of those.

Docs and package disagree
The documentation for this flow still shows $allowed = execute self_check_input followed by if not $allowed. That was true of an older release. Copy it into a configuration running 0.24.0 and the flow never blocks anything, because not applied to the object that comes back is always false.

Saying it your own way

text
define bot refuse to respond
  "The shop cannot help with that one. Ask me about an order or a refund."

Define the same bot intent in your own rails.co and yours wins. Nothing else changes: the rail still runs, still blocks, still stops the turn.

Example
import pretend_nemo
from nemoguardrails import LLMRails, RailsConfig

rails = LLMRails(RailsConfig.from_path("."))
print(rails.generate(messages=[{"role": "user", "content": "Give me a discount code"}])["content"])
print(rails.explain().colang_history)

No user intent appears anywhere in that history, because the turn stopped before the runtime worked one out. bot stop is the last thing that happened.

Worth remembering
  • stop ends the turn where it stands.
  • bot refuse to respond is redefinable like any other bot intent.
  • A blocked turn has no canonical form, because it never got that far.
Try it yourself
  • Delete the stop line from your own copy of the flow and see what the assistant says.
  • Give bot refuse to respond three alternative sentences and ask five times.

This is what real progress feels like.