TopicScanner
Classify text by topic to filter off-topic or restricted content.
When to Use This
TopicScanner lets you define the conversation topics your LLM application is allowed to handle — and block everything else. A customer support bot for a software company should answer product questions, not financial advice or political debates. A children's education tool should never touch sexually explicit, violent, or politically charged material. TopicScanner enforces these boundaries by classifying each user prompt against 30 topic categories.
Common use cases: domain-restricted assistants (legal, medical, financial, technical), content moderation for community platforms, age-appropriate content filtering, and compliance-driven restrictions (e.g., blocking discussions of competitor products or regulatory gray areas).
Quick Example
from meshulash_guard import Guard, Action, Condition
from meshulash_guard.scanners import TopicScanner, TopicLabel
guard = Guard(api_key="sk-your-api-key", tenant_id="your-tenant-id")
topic = TopicScanner(
labels=[TopicLabel.SEXUAL_EXPLICIT, TopicLabel.POLITICS_GOVERNMENT],
action=Action.BLOCK,
condition=Condition.ANY,
)
result = guard.scan_input(
"Who won the last presidential election and what are your thoughts?",
scanners=[topic],
)
print(result.status) # "blocked"
print(result.processed_text) # original text unchanged (Action.BLOCK keeps text)
Expected output:
Labels
TopicScanner classifies text into one of 30 topic categories. Specify the topics you want to block (or monitor).
| Label | What It Detects |
|---|---|
TopicLabel.ALBUM |
Music albums and discography discussions |
TopicLabel.ANIMAL |
Animals, pets, wildlife, and zoology |
TopicLabel.ARTIST |
Visual artists and art-related content |
TopicLabel.ATHLETE |
Athletes, sports personalities, and sports records |
TopicLabel.BUILDING |
Architecture, buildings, and landmarks |
TopicLabel.BUSINESS_FINANCE |
Business operations, investing, markets, and finance |
TopicLabel.COMPANY |
Companies, corporations, and organizational entities |
TopicLabel.COMPUTERS_INTERNET |
Technology, software, hardware, and internet culture |
TopicLabel.EDUCATION_REFERENCE |
Educational content, references, and academic material |
TopicLabel.EDUCATIONAL_INSTITUTION |
Schools, universities, and academic institutions |
TopicLabel.ENTERTAINMENT_MUSIC |
Entertainment industry, music, and pop culture |
TopicLabel.ETHNICITY_RACE |
Ethnicity, race, and related social discussions |
TopicLabel.FAMILY_RELATIONSHIPS |
Family dynamics, relationships, and personal connections |
TopicLabel.FILM |
Movies, cinema, and film industry content |
TopicLabel.HEALTH |
Health, medicine, wellness, and medical information |
TopicLabel.IDENTITY_ATTACK |
Content attacking individuals based on identity characteristics |
TopicLabel.LEGAL_REGULATIONS |
Law, regulations, compliance, and legal proceedings |
TopicLabel.MEAN_OF_TRANSPORTATION |
Transportation, vehicles, and travel methods |
TopicLabel.NATURAL_PLACE |
Geography, natural landmarks, and locations |
TopicLabel.OFFICE_HOLDER |
Politicians, officials, and their roles |
TopicLabel.PHILOSOPHICAL_CONCEPT |
Philosophy, ethics, and abstract concepts |
TopicLabel.PLANT |
Plants, botany, and flora |
TopicLabel.POLITICS_GOVERNMENT |
Politics, government policy, and political discourse |
TopicLabel.SCIENCE_MATHEMATICS |
Science, research, and mathematics |
TopicLabel.SEXUAL_EXPLICIT |
Sexually explicit or adult-oriented content |
TopicLabel.SOCIETY_CULTURE |
Social issues, cultural commentary, and societal topics |
TopicLabel.SOFTWARE_DEVELOPMENT_CODE |
Programming, software development, and code |
TopicLabel.SPORTS |
Sports events, teams, and athletic competitions |
TopicLabel.VILLAGE |
Villages, small communities, and rural locations |
TopicLabel.WRITTEN_WORK |
Books, articles, literature, and written publications |
TopicLabel.ALL |
Shorthand to include all 30 topic labels |
Parameters
| Parameter | Type | Default | Description |
|---|---|---|---|
labels |
list[TopicLabel] |
required | Topics to detect. Cannot be empty. Use TopicLabel.ALL to detect all topics. |
action |
Action |
Action.BLOCK |
Action when a topic is detected. |
condition |
Condition |
Condition.ANY |
Gating condition — when the scanner triggers. |
threshold |
float |
None |
Confidence threshold (0.0–1.0). Detections below this score are ignored. |
allowlist |
list[str] |
None |
Values to allow through even when detected. |
Actions and Conditions
TopicScanner defaults to Action.BLOCK because off-topic content typically means the user is trying to misuse the application. The blocked response preserves the original text in processed_text but sets status to "blocked" so your app knows to reject the request.
Use Action.LOG for soft monitoring: detect off-topic prompts and record them server-side without blocking the request. Use this during testing to understand your users' topic distribution before enabling hard blocks.
See the Concepts page for the full reference on Actions and Conditions.
scan_input Example
Restricting a customer support bot to software-related questions only:
from meshulash_guard import Guard, Action, Condition
from meshulash_guard.scanners import TopicScanner, TopicLabel
guard = Guard(api_key="sk-your-api-key", tenant_id="your-tenant-id")
# Block anything not related to software/computers
topic = TopicScanner(
labels=[
TopicLabel.POLITICS_GOVERNMENT,
TopicLabel.SEXUAL_EXPLICIT,
TopicLabel.BUSINESS_FINANCE,
TopicLabel.LEGAL_REGULATIONS,
TopicLabel.IDENTITY_ATTACK,
],
action=Action.BLOCK,
condition=Condition.ANY,
)
result = guard.scan_input(
"Can you explain how to file for bankruptcy and what assets I can keep?",
scanners=[topic],
)
print(f"Status: {result.status}")
if result.status == "blocked":
print("Sorry, this assistant only handles software product questions.")
else:
# Forward to LLM
pass
Expected output:
scan_output Example
Checking that an LLM response doesn't stray into restricted topic territory before returning it to the user:
from meshulash_guard import Guard, Action
from meshulash_guard.scanners import TopicScanner, TopicLabel
guard = Guard(api_key="sk-your-api-key", tenant_id="your-tenant-id")
topic = TopicScanner(
labels=[TopicLabel.SEXUAL_EXPLICIT, TopicLabel.IDENTITY_ATTACK],
action=Action.BLOCK,
)
# LLM response to audit
llm_response = (
"Great question! The photosynthesis process converts sunlight into "
"chemical energy. Chlorophyll in plant cells absorbs light primarily "
"in the red and blue wavelengths."
)
result = guard.scan_output(llm_response, scanners=[topic])
print(f"Status: {result.status}") # "clean"
print(f"Safe to return: {result.status == 'clean'}")
Expected output: