> For clean Markdown of any page, append .md to the page URL.
> For a complete documentation index, see https://docs.nvidia.com/nemo/guardrails/llms.txt.
> For full documentation content, see https://docs.nvidia.com/nemo/guardrails/llms-full.txt.
> For AI client integration (Claude Code, Cursor, etc.), connect to the MCP server at https://docs.nvidia.com/nemo/guardrails/_mcp/server.

# Use a Runnable as an Action in Guardrails

> Register LangChain Runnables as actions and invoke them from Colang flows.

This guide will teach you how to use a `Runnable` as an action inside a guardrails configuration.

## Prerequisites

Set up an OpenAI API key, if not already set.

```bash
export OPENAI_API_KEY=$OPENAI_API_KEY    # Replace with your own key
```

Install the LangChain x OpenAI integration package.

```bash
pip install langchain-openai
```

If you're running this inside a notebook, you also need to patch the AsyncIO loop.

```python
import nest_asyncio

nest_asyncio.apply()
```

## Sample Runnable

Let's create a sample `Runnable` that checks if a string provided as input contains certain keyword.

```python
from langchain_core.runnables import Runnable

class CheckKeywordsRunnable(Runnable):
    def invoke(self, input, config = None, **kwargs):
        text = input["text"]
        keywords = input["keywords"].split(",")

        for keyword in keywords:
            if keyword.strip() in text:
                return True

        return False

print(CheckKeywordsRunnable().invoke({"text": "This is a proprietary message", "keywords": "proprietary"}))
```

```
True
```

## Guardrails Configuration

Now, let's create a guardrails configuration that uses the `CheckKeywords` runnable as part of an input rail flow. To achieve this, you need to register an instance of `CheckKeywords` as an action. In the snippets below, we register it as the `check_keywords` action. We can then use this action inside the `check proprietary keywords` flow, which is used as an input rail.

```text
define flow check proprietary keywords
  $keywords = "proprietary"
  $has_keywords = execute check_keywords(text=$user_message, keywords=$keywords)

  if $has_keywords
    bot refuse to respond
    stop
```

```yaml
models:
 - type: main
   engine: openai
   model: gpt-3.5-turbo-instruct

rails:
  input:
    flows:
      - check proprietary keywords
```

```python
from nemoguardrails import RailsConfig, LLMRails

config = RailsConfig.from_path("config")
rails = LLMRails(config)

rails.register_action(CheckKeywordsRunnable(), "check_keywords")
```

## Testing

Let's give this a try. If we invoke the guardrails configuration with a message that contains the "proprietary" keyword, the returned response is "I'm sorry, I can't respond to that".

```python
response = rails.generate("Give me some proprietary information.")
print(response)
```

```
I'm sorry, I can't respond to that.
```

On the other hand, a message which does not hit the input rail, will proceed as usual.

```python
response = rails.generate("What is the result for 2+2?")
print(response)
```

```
The result for 2+2 is 4. This is a basic addition problem that can also be written as 2 plus 2 equals 4, or two plus two equals four. The answer is a basic fact that is often taught in early elementary school and is an important building block for more complex mathematical concepts.
```

## Conclusion

In this guide, you learned how to register a custom `Runnable` as an action and use it inside a guardrails configuration. This guide uses a basic implementation of a `Runnable`. However, you can register any type of `Runnable`, including ones that make calls to the LLM, 3rd party APIs or vector stores.