Skip to lesson

NVIDIANVIDIA-Certified Professional: Agentic AI2026-107.1 Integrate NVIDIA NeMo Guardrails for compliance and safety enforcement.

Wire Guardrails from YAML to Colang

Completed by the knowledge check

Learning objective

Configure rails with config.yml, prompts, and Colang flows.

Core idea

A policy sentence, a rail activation, and a flow implementation are different configuration objects. The policy tells a model what to judge. The activation list tells the runtime when to run a check. The flow interprets the check’s result and determines whether processing continues, changes, or stops.

Keep those connections explicit. A detailed policy in a prompt does not activate a rail, and activating the self-check rail without its required prompt raises an exception when the configuration loads. See 7.1.1 for choosing the enforcement stage; here the decision is how to turn that choice into a coherent executable configuration.

How it works

Give each file one responsibility

The configuration directory contains a required config.yml. Its models section identifies model roles and providers; its rails section activates checks and supplies their settings. General instructions and sample conversations can also live there. Optional .co files implement Colang behavior and are loaded recursively from the configuration directory.

Task prompts can live under prompts in config.yml or in a separate prompts.yml. Optional actions.py or an actions/ package supplies Python functions decorated with @action(). Optional config.py performs startup registration and initializes shared resources. These files form one configuration, rather than independently deployed policy fragments.

Load a directory with RailsConfig.from_path("./config"), then pass the result to LLMRails. That explicit runtime is useful when the configuration needs Colang behavior. Keep the model’s actual provider configuration alongside the policy files so that a test exercises the intended checking model rather than a remembered default.

Connect the flow name to the prompt task

The following excerpts illustrate input self-check wiring; they supplement a configuration that already declares its main model. In config.yml, activate the built-in flow:

rails:
  input:
    flows:
      - self check input

In prompts.yml, supply the task-specific decision prompt:

prompts:
  - task: self_check_input
    content: |
      Policy: block requests to impersonate another employee.
      User message: "{{ user_input }}"
      Should the message be blocked? Answer yes or no.

The spaces and underscores distinguish two identifiers. self check input is a flow name; self_check_input is the prompt task and action name. The prompt’s answer is yes when the message should be blocked, but the action returns True when it should be allowed. Do not invert that polarity when implementing custom behavior.

The documented Colang 1.0 built-in flow makes the control decision explicit:

define flow self check input
  $allowed = execute self_check_input
  if not $allowed
    bot refuse to respond
    stop

This is the built-in behavior to understand, not a second definition to copy over it. You can customize the refusal by defining bot refuse to respond in a .co file. That changes the refusal text; it does not alter what the checking action considers safe.

Keep prompt selection and language selection deliberate

Prompt templates support Jinja2 variables. {{ user_input }} supplies the incoming user message, while {{ bot_response }} supplies the proposed response for output checking. A prompt can use content or chat-style messages; these are mutually exclusive. A models selector restricts a prompt to an engine or an engine/model pair.

The top-level prompting_mode selects prompt variants whose mode matches it. If no matching mode exists, selection falls back to standard. Therefore, changing prompting_mode to compact does not establish that a compact prompt actually ran. Verify the selected task and behavior, especially when reducing context to meet latency targets.

The prompt’s max_length limits prompt characters; max_tokens controls completion tokens. These are different budgets. Self-check actions fall back to 1,024 completion tokens when max_tokens is unset. With a reasoning checker, internal reasoning can consume that budget before a visible verdict appears. The documented default input/output self-check parser treats an empty verdict as unsafe; the remedy is an explicit task max_tokens sufficient for reasoning plus the verdict, followed by measurement.

Set the language with colang_version in config.yml; LLMRails selects its runtime from config.colang_version. The Colang Guide describes 1.0 as the default while 2.0 completes beta. The 1.0 forms used here include define flow and execute. Colang 2.0 changes syntax and mechanics, including an explicit main entry flow and explicit activation, while keeping the same event-driven interaction model.

Engine Feature Support limits IORails to Colang 1.0 configurations; Colang 2.x configurations route to LLMRails. The Colang Guide also lists incomplete usability of the Guardrails Library from Colang 2.0 as a 2.0-beta limitation. Treat migration as a tested configuration change: support for the language runtime does not establish complete built-in-library compatibility.

Key distinctions and trade-offs

Choose the configuration object according to the change you need:

Desired changeObject to editConsequence to verify
Run an input policy checkrails.input.flowsThe check executes before main generation
Change what the checker rejectsprompts task self_check_inputBenign and prohibited examples retain the intended verdict polarity
Change refusal wordingColang define bot refuse to respondA rejected request returns the intended message
Change permitted conversation behaviorColang define flowThe next interaction follows the intended sequence
Reduce checking prompt sizeMatching prompting_mode and prompt modeThe intended variant runs without losing needed policy detail

A longer self-check prompt can encode more precise distinctions but consumes more tokens and adds latency. A shorter prompt can omit the exception that allows a legitimate request. Choose from observed behavior on your policy examples, not from file length. Purpose-built detector integration is the separate decision in 7.1.3.

Architecture / decision scenario

An insurance company builds a claims-drafting assistant for employees. Its application target allows 400 ms of checking overhead. In a scenario replay of 600 requests, a broad self-check prompt rejects 42 legitimate drafting requests because they quote impersonation attempts as incident material. A revised prompt distinguishes reporting an attempt from requesting one and rejects 6 legitimate requests, while still blocking all 60 labeled impersonation requests in that replay.

The tempting alternative edits only the bot’s general instructions: “Never impersonate an employee.” The application owner rejects that proposal because the required behavior is a separate input decision before drafting. The team keeps self check input activated and edits the self_check_input task, preserving its yes-means-block convention. A .co bot definition supplies a refusal that tells employees how to reformulate a prohibited request.

The revised configuration adds 310 ms at the measured tail, while a more verbose variant adds 470 ms. The owner chooses the revised prompt provisionally because it meets the 400 ms budget and reduces observed overblocking. These numbers are scenario measurements, not NVIDIA guarantees. A held-out set must confirm that the clearer exception does not also permit disguised impersonation requests.

Before promotion, the team loads the complete directory with RailsConfig.from_path, checks that missing required prompts fail visibly, and exercises benign, prohibited, and quoted-incident cases. It also verifies the refusal path and the runtime selected by colang_version. Editing the prompt without testing the activated flow would miss a naming mismatch that leaves the intended task unused.

Common exam traps

  • Treating general instructions as activation of a self-check rail.
  • Confusing the flow self check input with the task self_check_input.
  • Interpreting an action’s allowed Boolean as the prompt’s blocked answer.
  • Supplying both content and messages for one prompt.
  • Treating max_length characters as completion tokens.
  • Assuming Colang 1.0 and 2.0 examples are interchangeable.

What to remember

Connect three objects: activation in config.yml, a prompt for the checking task, and flow behavior that interprets the result. Load and test them together. Preserve verdict polarity, verify prompt selection, and budget completion tokens separately from prompt length.

Knowledge check

References