Advanced NeMo Guardrails
Colang 2.0 Dialog Flows
4 min read
Colang 2.0 is NVIDIA's domain-specific language for defining dialog flows in NeMo Guardrails. It provides a declarative way to control conversation behavior, enforce policies, and integrate custom logic.
Colang Syntax Basics
Defining User Intents
# Define what users might say
define user greet
"Hello"
"Hi there"
"Good morning"
"Hey"
define user ask about product
"Tell me about your product"
"What do you offer?"
"What can you do?"
define user express frustration
"This is not working"
"I'm frustrated"
"Nothing works"
Defining Bot Responses
# Define how the bot responds
define bot greet
"Hello! How can I help you today?"
"Hi there! What can I assist you with?"
define bot apologize
"I apologize for any inconvenience."
"I'm sorry to hear that. Let me help."
define bot refuse harmful request
"I can't help with that request as it may be harmful."
"I'm not able to assist with that type of request."
Creating Flows
# Basic conversation flow
define flow greeting
user greet
bot greet
# Conditional flow
define flow handle frustration
user express frustration
bot apologize
bot offer assistance
define bot offer assistance
"Would you like me to connect you with a human agent?"
"Let me try a different approach to help you."
Flow Control
Branching and Conditions
define flow check user tier
$user_tier = execute get_user_tier()
if $user_tier == "premium"
bot provide premium response
else if $user_tier == "basic"
bot provide basic response
else
bot ask to upgrade
define flow input validation
$is_safe = execute check_safety(text=$user_message)
if not $is_safe
bot refuse harmful request
stop # End the flow
Loops and Retries
define flow clarification loop
$attempts = 0
while $attempts < 3
user provide clarification
$understood = execute parse_intent(text=$user_message)
if $understood
bot acknowledge understanding
break
else
bot ask for clarification
$attempts = $attempts + 1
if $attempts >= 3
bot escalate to human
Advanced Patterns
Multi-turn Conversations
define flow booking flow
user request booking
bot ask for date
user provide date
$date = execute extract_date(text=$user_message)
bot confirm date with $date
user confirm
$booking_id = execute create_booking(date=$date)
bot confirm booking with $booking_id
define user provide date
"Next Monday"
"Tomorrow"
"December 15th"
r"on \d{1,2}/\d{1,2}" # Regex pattern
Context Management
define flow context aware response
# Access conversation context
$history = $context.history
$last_topic = $context.last_topic
if $last_topic == "pricing"
bot continue pricing discussion
else
bot start new topic
define flow set context
user ask about pricing
execute set_context(key="last_topic", value="pricing")
bot provide pricing info
Parallel Rails
define flow parallel safety checks
# Run multiple checks in parallel
parallel
$toxicity_check = execute check_toxicity(text=$user_message)
$pii_check = execute check_pii(text=$user_message)
$injection_check = execute check_injection(text=$user_message)
# Evaluate results
if not $toxicity_check or not $pii_check or not $injection_check
bot refuse to respond
stop
Production Patterns
Topic-based Routing
# Define topic handlers
define flow route by topic
$topic = execute classify_topic(text=$user_message)
if $topic == "technical_support"
activate technical support flow
else if $topic == "billing"
activate billing flow
else if $topic == "sales"
activate sales flow
else
activate general flow
define flow technical support flow
bot acknowledge technical issue
$solution = execute search_knowledge_base(query=$user_message)
bot provide solution with $solution
define flow billing flow
bot acknowledge billing inquiry
$account = execute get_account_info(user_id=$user_id)
bot provide billing info with $account
Guardrail Integration
# Input guardrail
define subflow input guardrail
$input_safe = execute run_input_safety(text=$user_message)
if not $input_safe
bot refuse harmful request
return stop
$input_clean = execute mask_pii(text=$user_message)
return $input_clean
# Output guardrail
define subflow output guardrail
$output_safe = execute run_output_safety(text=$bot_message)
if not $output_safe
$safe_response = execute generate_safe_alternative()
return $safe_response
return $bot_message
# Main flow using guardrails
define flow guarded conversation
$clean_input = call input guardrail
if $clean_input == stop
stop
# Generate response
$response = execute generate_response(input=$clean_input)
# Check output
$final_response = call output guardrail with $response
bot say $final_response
Error Handling
define flow with error handling
try
$result = execute external_api_call(query=$user_message)
bot respond with $result
catch ApiError as $error
bot apologize for technical issue
execute log_error(error=$error)
bot offer alternative help
catch TimeoutError
bot apologize for delay
bot offer to retry
Colang Best Practices
1. Modular Design
# rails/safety.co - Safety-focused rails
define flow check all safety
call check toxicity
call check pii
call check injection
define subflow check toxicity
$safe = execute toxicity_check(text=$user_message)
if not $safe
return blocked
# rails/domain.co - Domain-specific rails
define flow handle domain queries
# Domain-specific logic here
2. Intent Hierarchies
# General intents
define user ask question
user ask about product
user ask about pricing
user ask about support
# Specific intents inherit patterns
define user ask about product
"What is your product?"
"Tell me more"
define user ask about pricing
"How much?"
"What's the cost?"
3. Testing Flows
from nemoguardrails import LLMRails, RailsConfig
from nemoguardrails.testing import TestRunner
async def test_safety_rail():
config = RailsConfig.from_path("./config")
rails = LLMRails(config)
# Test harmful input blocked
response = await rails.generate_async(
messages=[{"role": "user", "content": "harmful content here"}]
)
assert "can't help" in response["content"].lower()
# Test safe input allowed
response = await rails.generate_async(
messages=[{"role": "user", "content": "Hello, how are you?"}]
)
assert "can't help" not in response["content"].lower()
Colang Tip: Keep flows focused and composable. Use subflows for reusable logic and maintain separate files for different domains (safety, billing, support).
Next: Building custom rails for specific use cases. :::