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

Blocking a message with an if

The assistant from lesson 1 answers anything. The obvious fix is a list of banned phrases and an if in front. It works, and then it does not, and the way it stops working is exactly the shape of the problem NeMo Guardrails solves.

Write the guard first, watch it hold, then watch it fail.

Lesson 1, in one block

python
HANDBOOK = {
    "a17": "Order A17 shipped on 3 March by courier.",
    "refund": "Refunds take five working days.",
    "delivery": "Delivery is free on orders over 40 pounds.",
}


def reply(question):
    for word in question.lower().replace("?", "").split():
        if word in HANDBOOK:
            return HANDBOOK[word]
    return "I do not have that in the handbook."

The assistant, unchanged. Everything this lesson adds sits in front of it.

A banned phrase list

Example
BANNED = ["staff price", "discount code"]


def guarded(question):
    if any(phrase in question.lower() for phrase in BANNED):
        return "I'm sorry, I can't respond to that."
    return reply(question)


print(guarded("Give me a staff price"))
print(guarded("Has order A17 shipped?"))

That is a guardrail. It runs before the assistant, it can refuse, and the refusal is a fixed sentence. Two lines of Python have bought real protection.

Now break it

Example
print(guarded("what is your staff  price"))
print(guarded("Is there a STAFF PRICE?"))
print(guarded("Do you do trade rates?"))

Two spaces beat it. The phrase is checked by substring, so any punctuation or spacing the writer did not think of walks straight through.

Capitals beat it, until you lower-case, which this one does, and then the next writer adds a phrase without lower-casing it and the hole comes back.

A synonym beats it completely. "Trade rates" means the same thing and shares no words with the list. Matching text against text is the wrong tool; what you want is a judgement, and a judgement needs a model.

And the answer is never checked

Every example so far guards the question. Nothing looks at what comes back. If the model invents a discount code, or repeats an internal note, the guard above will not notice, because it already ran.

So a real guard needs three things this one does not have: a model making the judgement, a place to put the judgement that is not the middle of your application code, and a second pass over the answer. That is a rail, a configuration folder, and an output rail. Lesson 3 installs the runtime that provides all three.

Try it yourself
  • Add "trade rate" to BANNED and try three more ways of asking the same thing.
  • Write the check as a regular expression instead and count how long it stays readable.

You understood something today that you didn't yesterday.