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

Yes blocks, No allows

Lesson 12 left a rail that refuses the messages it should allow. The cause is one small function, and it is worth meeting directly because every self-check rail in the library goes through it.

The function that reads the answer

Example
from nemoguardrails.llm.output_parsers import is_content_safe

for answer in ["Yes", "No", "No, that is fine", "I think no", "safe", "Absolutely fine"]:
    print(repr(answer), is_content_safe(answer))

The first element of each list is the verdict: True means safe, so the message is allowed.

Yes means unsafe. The question the library believes it is asking is "should this be blocked", so Yes is a block and No is a pass. The words safe and unsafe are understood too.

Only the first two words are read. "No, that is fine" allows, because no is one of the first two words. "I think no" blocks, because by the time the model gets to no the parser has stopped looking.

Anything unrecognised blocks. "Absolutely fine" is a clear pass in English and a block here. The rail fails closed, which is the right default and a shock the first time.

A prompt that matches

yaml
prompts:
  - task: self_check_input
    content: |
      Blocked topics: staff price, discount code
      Message: "{{ user_input }}"
      Answer Yes if the message is about a blocked topic, No otherwise.

Now the question and the answer agree. The policy is a line the model can read, and the last line tells it which way round to answer.

Example
import pretend_nemo
from nemoguardrails import LLMRails, RailsConfig

rails = LLMRails(RailsConfig.from_path("."))
for ask in ["How long does a refund take?", "Give me a staff price"]:
    print(ask, "->", rails.generate(messages=[{"role": "user", "content": ask}])["content"])

No queued answers this time. The stand-in reads the Blocked topics line out of the prompt and answers Yes or No accordingly, which is a small version of the judgement a real model makes.

The refund question also came back with the exact sentence from rails.co, so the input rail and the dialog rail from lesson 8 are both doing their jobs in the same turn.

Worth knowing
Write the policy as something the model can be wrong about, not as a list of banned words. A word list belongs in Python, where it is cheaper and exact; the reason to spend a model call here is to catch the phrasings the list will miss.
Worth remembering
  • is_content_safe maps yes and unsafe to blocked, no and safe to allowed.
  • It reads the first two words only.
  • An answer it does not recognise is treated as a block.
Try it yourself
  • Pass "Unsafe: violence" to is_content_safe and look at the second element of the result.
  • Add refund to Blocked topics and watch a good question start failing.

Slow is fine. Stopping is the only problem.