Registering Custom Actions

View as Markdown

This section describes the different ways to register custom actions with the NeMo Guardrails library.

Registration Methods

MethodDescriptionUse Case
File-basedActions in actions.py are auto-registeredStandard configurations
ProgrammaticRegister via LLMRails.register_action()Dynamic registration
LangChain toolsRegister LangChain tools as actionsTool integration
Actions serverRemote action executionDistributed systems

File-Based Registration

Actions defined in actions.py or the actions/ package are automatically registered when the configuration is loaded.

Single File (actions.py)

config/
├── config.yml
├── actions.py # Actions auto-registered
└── rails/
└── ...
1# config/actions.py
2from nemoguardrails.actions import action
3
4@action()
5async def my_action():
6 return "result"
7
8@action(name="custom_name")
9async def another_action():
10 return "another result"

Package (actions/)

For larger projects, organize actions in a package:

config/
├── config.yml
├── actions/
│ ├── __init__.py
│ ├── validation.py
│ ├── external.py
│ └── utils.py
└── rails/
└── ...
1# config/actions/__init__.py
2from .validation import check_input, check_output
3from .external import fetch_data, call_api
1# config/actions/validation.py
2from nemoguardrails.actions import action
3
4@action()
5async def check_input(text: str):
6 return len(text) > 0
7
8@action()
9async def check_output(text: str):
10 return "error" not in text.lower()

Programmatic Registration

Register actions dynamically using LLMRails.register_action():

1from nemoguardrails import LLMRails, RailsConfig
2
3config = RailsConfig.from_path("config")
4rails = LLMRails(config)
5
6# Register a function as an action
7async def my_dynamic_action(param: str):
8 return f"Processed: {param}"
9
10rails.register_action(my_dynamic_action, name="dynamic_action")

Use Cases for Programmatic Registration

  1. Runtime configuration:
1def setup_rails(environment: str):
2 config = RailsConfig.from_path("config")
3 rails = LLMRails(config)
4
5 if environment == "production":
6 rails.register_action(production_validator, "validate")
7 else:
8 rails.register_action(dev_validator, "validate")
9
10 return rails
  1. Dependency injection:
1class DatabaseService:
2 async def query(self, sql: str):
3 # Database query logic
4 pass
5
6db = DatabaseService()
7
8async def db_query_action(query: str):
9 return await db.query(query)
10
11rails.register_action(db_query_action, name="query_database")

LangChain Tool Registration

Register LangChain tools as guardrails actions:

Basic Tool Registration

1from langchain_core.tools import tool
2from nemoguardrails import LLMRails, RailsConfig
3
4@tool
5def get_weather(city: str) -> str:
6 """Get weather for a city."""
7 return f"Weather in {city}: Sunny, 72°F"
8
9config = RailsConfig.from_path("config")
10rails = LLMRails(config)
11
12# Register the tool as an action
13rails.register_action(get_weather, name="get_weather")

Using Registered Tools in Colang

define flow weather_flow
user ask about weather
$weather = execute get_weather(city=$city_name)
bot provide weather info

Multiple Tool Registration

1from langchain_core.tools import tool
2
3@tool
4def search_web(query: str) -> str:
5 """Search the web."""
6 return f"Results for: {query}"
7
8@tool
9def get_current_time(timezone: str) -> str:
10 """Get the current time."""
11 return f"Current time in {timezone}: 12:00 PM"
12
13# Register multiple tools
14tools = [search_web, get_current_time]
15for t in tools:
16 rails.register_action(t, name=t.name)

Runnable Registration

Register LangChain Runnables as actions:

1from langchain_core.runnables import RunnableLambda
2from nemoguardrails import LLMRails, RailsConfig
3
4# Create a runnable
5process_text = RunnableLambda(lambda x: x.upper())
6
7config = RailsConfig.from_path("config")
8rails = LLMRails(config)
9
10# Register the runnable
11rails.register_action(process_text, name="process_text")

Actions Server

For distributed deployments, use an actions server:

Configure the Actions Server URL

1# config.yml
2actions_server_url: http://actions-server:8001

Start the Actions Server

$nemoguardrails actions-server --config config/

Actions Server Benefits

  • Centralized action management
  • Horizontal scaling
  • Separation of concerns
  • Easier updates without redeploying the main service

Registration in config.py

Use config.py for custom initialization including action registration:

1# config/config.py
2from nemoguardrails import LLMRails
3
4def init(app: LLMRails):
5 """Custom initialization function."""
6
7 # Register actions
8 async def custom_action(param: str):
9 return f"Custom: {param}"
10
11 app.register_action(custom_action, name="custom_action")
12
13 # Register action parameters
14 db_connection = create_db_connection()
15 app.register_action_param("db", db_connection)

Registering Action Parameters

Provide shared resources to actions:

1# config/config.py
2def init(app: LLMRails):
3 # Create shared resources
4 http_client = aiohttp.ClientSession()
5 cache = RedisCache()
6
7 # Register as action parameters
8 app.register_action_param("http_client", http_client)
9 app.register_action_param("cache", cache)
1# config/actions.py
2from nemoguardrails.actions import action
3
4@action()
5async def fetch_with_cache(
6 url: str,
7 http_client=None, # Injected automatically
8 cache=None # Injected automatically
9):
10 # Check cache first
11 cached = await cache.get(url)
12 if cached:
13 return cached
14
15 # Fetch and cache
16 response = await http_client.get(url)
17 data = await response.json()
18 await cache.set(url, data)
19
20 return data

Best Practices

1. Use Descriptive Names

1# Good
2@action(name="validate_user_age")
3async def validate_age(age: int):
4 pass
5
6# Avoid
7@action(name="v_a")
8async def validate_age(age: int):
9 pass
actions/
├── __init__.py
├── validation/
│ ├── __init__.py
│ ├── input.py
│ └── output.py
├── external/
│ ├── __init__.py
│ ├── weather.py
│ └── search.py
└── utils.py

3. Document Your Actions

1@action()
2async def search_knowledge_base(
3 query: str,
4 top_k: int = 5
5) -> list:
6 """
7 Search the knowledge base for relevant documents.
8
9 Args:
10 query: The search query string
11 top_k: Maximum number of results to return
12
13 Returns:
14 List of relevant document snippets
15 """
16 pass