Configuring Custom Actions

View as Markdown

This section guides you through how to create the actions.py file to define custom Python actions and integrate them into the NeMo Guardrails library. By configuring custom actions, you can execute Python code within guardrails flows, extending the library with custom logic, external API integrations, and complex validation.

An actions.py file defines custom action functions using the @action decorator. A decorator is a callable that takes a function and returns a new function, usually adding behavior or attaching metadata.

1from typing import Optional
2from nemoguardrails.actions import action
3
4@action()
5async def check_custom_policy(context: Optional[dict] = None):
6 """Check if the input complies with custom policy."""
7 user_message = context.get("last_user_message", "")
8
9 # Custom validation logic
10 forbidden_words = ["spam", "phishing"]
11 for word in forbidden_words:
12 if word in user_message.lower():
13 return False
14
15 return True
16
17@action(name="fetch_user_data")
18async def get_user_info(user_id: str):
19 """Fetch user data from external service."""
20 # External API call
21 return {"user_id": user_id, "status": "active"}

Configuration Sections

The following sections provide detailed documentation for creating and using custom actions:

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:

1from typing import Optional
2from nemoguardrails.actions import action
3
4@action(is_system_action=True)
5async def check_blocked_terms(context: Optional[dict] = None):
6 """Check if bot response contains blocked terms."""
7 bot_response = context.get("bot_message", "")
8
9 blocked_terms = ["confidential", "proprietary", "secret"]
10
11 for term in blocked_terms:
12 if term in bot_response.lower():
13 return True # Term found, block the response
14
15 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:

1rails:
2 output:
3 flows:
4 - check_output_terms

For detailed information about each topic, refer to the individual pages linked above.