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

One model call, or three

Lesson 10 ended with a message that matched no flow. This lesson counts what that costs, because the gap between a matched message and an unmatched one is one model call against three, and it explains most of the surprises still to come.

Matched, unmatched, and nothing defined

Example
import pretend_nemo
from nemoguardrails import LLMRails, RailsConfig

rails = LLMRails(RailsConfig.from_path("."))
for ask in ["When do I get my money back?", "Is the shop open on Sunday?"]:
    rails.generate(messages=[{"role": "user", "content": ask}])
    print(ask, [call.task for call in rails.explain().llm_calls])

A matched message costs one call. The runtime works out the canonical form and stops asking, because the flow says what the bot does next and define bot already holds the words.

An unmatched message costs three. After generate_user_intent comes generate_next_steps, which asks the model what the bot should do, and then generate_bot_message, which asks for the actual sentence.

Example
import pretend_nemo
from nemoguardrails import LLMRails, RailsConfig

rails = LLMRails(RailsConfig.from_path("."))
rails.generate(messages=[{"role": "user", "content": "When do I get my money back?"}])
print([call.task for call in rails.explain().llm_calls])

A configuration with no define user blocks costs one call, named general. With nothing to recognise there are no dialog rails at all, so the runtime hands the question over and hands the answer back. That folder has a config.yml and no rails.co.

The three steps, drawn

What an unmatched message costs
generate_user_intent. What does this message mean? Answered with a canonical form.Step 1 of 3

Each step is skipped when the configuration already answers it. A flow answers step two. A define bot block answers step three.

A trap worth knowing

If step two returns a bot intent that some define bot block already defines, step three never runs and the canned sentence comes back instead. NeMo ships several of these of its own, including inform answer unknown, so a model that happens to answer with that name sounds like it gave up when it was about to answer properly.

Worth remembering
  • Matched: one call. Unmatched: three. No intents defined: one, named general.
  • Every flow you write removes a model call and a chance to say the wrong thing.
  • explain().llm_calls is how you check rather than guess.
Try it yourself
  • Add a define bot answer the question block and watch the third call disappear.
  • Ask something that matches two define user blocks equally well and see which wins.

Little by little, you're building something great.