Custom Actions#
This section describes the actions.py file used to define custom Python actions for the NeMo Guardrails toolkit.
Custom actions enable you to execute Python code within guardrails flows, extending the toolkit with custom logic, external API integrations, and complex validation.
Overview#
A typical actions.py file contains custom action functions decorated with the @action decorator:
from typing import Optional
from nemoguardrails.actions import action
@action()
async def check_custom_policy(context: Optional[dict] = None):
"""Check if the input complies with custom policy."""
user_message = context.get("last_user_message", "")
# Custom validation logic
forbidden_words = ["spam", "phishing"]
for word in forbidden_words:
if word in user_message.lower():
return False
return True
@action(name="fetch_user_data")
async def get_user_info(user_id: str):
"""Fetch user data from external service."""
# External API call
return {"user_id": user_id, "status": "active"}
Configuration Sections#
The following sections provide detailed documentation for creating and using custom actions:
Create custom actions using the @action decorator to integrate Python logic into guardrails flows.
Reference for default actions included in the NeMo Guardrails toolkit for common operations.
Reference for special parameters like context, llm, and config automatically provided to actions.
Register custom actions via actions.py, LLMRails.register_action(), or init.py for different use cases.
File Organization#
Custom actions can be organized in two ways:
Option 1: Single actions.py file
.
├── config
│ ├── config.yml
│ ├── actions.py # All custom actions
│ └── rails/
│ └── ...
Option 2: actions/ sub-package
.
├── config
│ ├── config.yml
│ ├── actions/
│ │ ├── __init__.py
│ │ ├── validation.py
│ │ ├── external_api.py
│ │ └── ...
│ └── rails/
│ └── ...
Quick Example#
1. Define the Action#
Create config/actions.py:
from typing import Optional
from nemoguardrails.actions import action
@action(is_system_action=True)
async def check_blocked_terms(context: Optional[dict] = None):
"""Check if bot response contains blocked terms."""
bot_response = context.get("bot_message", "")
blocked_terms = ["confidential", "proprietary", "secret"]
for term in blocked_terms:
if term in bot_response.lower():
return True # Term found, block the response
return False # No blocked terms found
2. Create a Flow Using the Action#
Create config/rails/output.co:
define bot refuse to respond
"I apologize, but I cannot provide that information."
define flow check_output_terms
$contains_blocked = execute check_blocked_terms
if $contains_blocked
bot refuse to respond
stop
3. Configure the Rail#
Add to config/config.yml:
rails:
output:
flows:
- check_output_terms
For detailed information about each topic, refer to the individual pages linked above.