Skip to content

SentimentScanner

Detect hostile, aggressive, or strongly negative text in user input or LLM responses.

When to Use This

SentimentScanner measures the emotional tone of text and flags content that crosses a negativity threshold. Use it to protect your support team from abusive messages, enforce a civil tone in public-facing interfaces, or monitor whether an LLM is generating responses with an unexpectedly negative or dismissive tone.

This scanner is particularly effective in customer service pipelines where hostile messages should be escalated before reaching an agent, and in chatbot applications where you want to deflect conversations that have turned abusive rather than continuing to serve the user. Use Action.LOG to surface trends in user sentiment without hard-blocking, then tighten threshold as needed once you have baseline data.

Quick Example

from meshulash_guard import Guard, Action
from meshulash_guard.scanners import SentimentScanner

guard = Guard(api_key="sk-your-api-key", tenant_id="your-tenant-id")

sentiment = SentimentScanner(
    threshold=-0.5,
    action=Action.BLOCK,
)

result = guard.scan_input(
    "This is absolutely terrible service. I hate this product and everyone involved!",
    scanners=[sentiment],
)

print(result.status)          # "blocked"
print(result.processed_text)  # original text unchanged (Action.BLOCK keeps text)

Expected output:

blocked
This is absolutely terrible service. I hate this product and everyone involved!

How Sentiment Scoring Works

Sentiment is scored on a continuous scale from -1.0 (most negative) to +1.0 (most positive). Neutral text scores near 0.0. The threshold parameter marks the upper bound for triggering: text with a score below the threshold is flagged.

The default threshold of -0.5 targets clearly hostile or aggressive text. Adjustments:

  • Set threshold to -0.3 to catch moderately negative messages (e.g., frustrated but not abusive).
  • Set threshold to -0.7 to only flag strongly hostile content, allowing complaints through.

This scanner is designed for English text. Non-English input is not scored and passes through without triggering.

Parameters

Parameter Type Default Description
threshold float -0.5 Sentiment score upper bound for triggering (-1.0 to 0.0). Text scoring below this value is flagged. More negative values = stricter (fewer flags); less negative values = more permissive (more flags).
action Action Action.BLOCK Action when strongly negative sentiment is detected.

Actions and Conditions

SentimentScanner defaults to Action.BLOCK for applications with zero tolerance for hostile input. For moderation queues or analytics use cases, Action.LOG is more appropriate — it flags the content for human review without blocking the user.

Tune threshold based on your use case: -0.5 is a good starting point for customer support (catches clearly abusive messages), while -0.3 works better for community moderation (catches a wider range of negativity).

See the Concepts page for the full reference on Actions and Conditions.

scan_input Example

Moderating customer support messages with a threshold tuned to catch frustration as well as hostility:

from meshulash_guard import Guard, Action
from meshulash_guard.scanners import SentimentScanner

guard = Guard(api_key="sk-your-api-key", tenant_id="your-tenant-id")

sentiment = SentimentScanner(
    threshold=-0.3,
    action=Action.LOG,
)

messages = [
    "I'm frustrated that my order hasn't arrived yet.",
    "Your support team is completely useless and I want a refund NOW.",
    "Can you help me track my package?",
]

for message in messages:
    result = guard.scan_input(message, scanners=[sentiment])
    print(f"[{result.status}] {message[:50]}...")

Expected output:

[passed] I'm frustrated that my order hasn't arrived yet....
[logged] Your support team is completely useless and I w...
[passed] Can you help me track my package?...

scan_output Example

Auditing LLM responses to catch cases where the model generates dismissive or passive-aggressive replies:

from meshulash_guard import Guard, Action
from meshulash_guard.scanners import SentimentScanner

guard = Guard(api_key="sk-your-api-key", tenant_id="your-tenant-id")

sentiment = SentimentScanner(
    threshold=-0.4,
    action=Action.BLOCK,
)

llm_response = (
    "I really don't understand why you keep asking the same question. "
    "This has been answered multiple times already."
)

result = guard.scan_output(llm_response, scanners=[sentiment])

if result.status == "blocked":
    print("LLM response blocked — model replied with negative or dismissive tone.")
else:
    print(result.processed_text)

Expected output:

LLM response blocked — model replied with negative or dismissive tone.