Runnable as Action

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.

export OPENAI_API_KEY=$OPENAI_API_KEY    # Replace with your own key

Install the LangChain x OpenAI integration package.

pip install langchain-openai

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

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.

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.

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
models:
 - type: main
   engine: openai
   model: gpt-3.5-turbo-instruct

rails:
  input:
    flows:
      - check proprietary keywords
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”.

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.

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.