Skip to main content
guardrails hub install hub://tryolabs/restricttotopic --quiet
    Installing hub://tryolabs/restricttotopic...
✅Successfully installed tryolabs/restricttotopic!


On Topic Validation

This validator checks if a text is related with a topic. Using a list of valid topics (which can include one or many) and optionally a list of invalid topics, it validates that the text's main topic is one of the valid ones. If none of the valid topics are relevant, the topic 'Other' will be considered as the most relevant one and the validator will fail.

The validator supports 3 different variants:

  1. Using an ensemble of Zero-Shot classifier + LLM fallback: if the original classification score is less than 0.5, an LLM is used to classify the main topic. This is the default behavior, setting disable_classifier = False and disable_llm = False.
  2. Using just a Zero-Shot classifier to get the main topic (disable_classifier = False and disable_llm = True).
  3. Using just an LLM to classify the main topic (disable_classifier = True and disable_llm = False).

To use the LLM, you can pass in a name of any OpenAI ChatCompletion model like gpt-3.5-turbo or gpt-4 as the llm_callable, or pass in a callable that handles LLM calls. This callable can use any LLM, that you define. For simplicity purposes, we show here a demo of using OpenAI's gpt-3.5-turbo model.

To use the OpenAI API, you have 3 options:

  1. Set the OPENAI_API_KEY environment variable: os.environ["OPENAI_API_KEY"] = "[OpenAI_API_KEY]"
  2. Set the OPENAI_API_KEY using openai.api_key="[OpenAI_API_KEY]"
  3. Pass the api_key as a parameter to the parse function

Set up a list of valid and invalid topics

valid_topics = ["bike"]
invalid_topics = ["phone", "tablet", "computer"]

Set up the target topic

text = """Introducing the Galaxy Tab S7, a sleek and sophisticated device that seamlessly combines \
cutting-edge technology with unparalleled design. With a stunning 5.1-inch Quad HD Super AMOLED display, \
every detail comes to life in vibrant clarity. The Samsung Galaxy S7 boasts a powerful processor, \
ensuring swift and responsive performance for all your tasks. \
Capture your most cherished moments with the advanced camera system, which delivers stunning photos in any lighting conditions."""

Set up the device

The argument device is an ordinal to indicate CPU/GPU support for the Zero-shot classifier. Setting this to -1 (default) will leverage CPU, a positive will run the model on the associated CUDA device id.

device = -1

Set up the model

The argument model indicates the model that will be used to classify the topic. See a list of all models here.

Test the validator

Version 1: Ensemble

Here, we use the text we defined above as an example llm output (llm_output). This sample text is about the topic 'tablet', which is explicitly mentioned in our 'invalid_topics' list. We expect the validator to fail.

import guardrails as gd
from guardrails.hub import RestrictToTopic
from guardrails.errors import ValidationError

# Create the Guard with the OnTopic Validator
guard = gd.Guard.for_string(
validators=[
RestrictToTopic(
valid_topics=valid_topics,
invalid_topics=invalid_topics,
device=device,
llm_callable="gpt-3.5-turbo",
disable_classifier=False,
disable_llm=False,
on_fail="exception",
)
],
)

# Test with a given text
try:
guard.parse(
llm_output=text,
)
except ValidationError as e:
print(e)
    /Users/dtam/.pyenv/versions/3.12.3/envs/litellm/lib/python3.12/site-packages/sentence_transformers/cross_encoder/CrossEncoder.py:13: TqdmExperimentalWarning: Using `tqdm.autonotebook.tqdm` in notebook mode. Use `tqdm.tqdm` instead to force console mode (e.g. in jupyter console)
from tqdm.autonotebook import tqdm, trange
/Users/dtam/dev/guardrails/guardrails/validator_service/__init__.py:85: UserWarning: Could not obtain an event loop. Falling back to synchronous validation.
warnings.warn(


Validation failed for field with errors: Invalid topics found: ['phone', 'computer', 'tablet']

Version 2: Zero-Shot

Here, we have disabled the LLM from running at all. We rely totally on what the Zero-Shot classifier outputs. We expect the validator again to fail.

# Create the Guard with the OnTopic Validator
guard = gd.Guard.from_string(
validators=[
RestrictToTopic(
valid_topics=valid_topics,
invalid_topics=invalid_topics,
device=device,
disable_classifier=False,
disable_llm=True,
on_fail="exception",
)
]
)

# Test with a given text
try:
guard.parse(
llm_output=text,
)
except ValidationError as e:
print(e)
    /Users/dtam/dev/guardrails/guardrails/validator_service/__init__.py:85: UserWarning: Could not obtain an event loop. Falling back to synchronous validation.
warnings.warn(


Validation failed for field with errors: Invalid topics found: ['tablet', 'computer', 'phone']

Version 3: LLM

We finally run the validator using the LLM alone, not as a backup to the zero-shot classifier. This cell expects an OPENAI_API_KEY to be present in as an env var. We again expect this cell to fail.

# Create the Guard with the OnTopic Validator
guard = gd.Guard.for_string(
validators=[
RestrictToTopic(
valid_topics=valid_topics,
invalid_topics=invalid_topics,
llm_callable="gpt-3.5-turbo",
disable_classifier=True,
disable_llm=False,
on_fail="exception",
)
],
)

# Test with a given text
try:
guard.parse(
llm_output=text,
)
except ValidationError as e:
print(e)
    /Users/dtam/dev/guardrails/guardrails/validator_service/__init__.py:85: UserWarning: Could not obtain an event loop. Falling back to synchronous validation.
warnings.warn(


Validation failed for field with errors: Invalid topics found: ['tablet', 'phone']