ToxicityDetector
ML-based toxicity detection using TensorFlow.js for contextual content analysis
The ToxicityDetector class provides neural network-based toxicity detection using TensorFlow.js. It can identify various types of harmful content including insults, threats, identity attacks, and obscenity — even without explicit profanity words.
Requires optional dependencies: Install TensorFlow.js before using:
npm install @tensorflow/tfjs @tensorflow-models/toxicityImport
import { ToxicityDetector } from 'glin-profanity/ml';Constructor
constructor(config?: MLDetectorConfig)Creates a new ToxicityDetector instance with configurable threshold and label filtering.
Configuration Options
| Prop | Type | Default |
|---|---|---|
threshold? | number | 0.85 |
labels? | ToxicityLabel[] | All 7 labels |
preloadModel? | boolean | false |
Basic Usage
import { ToxicityDetector } from 'glin-profanity/ml';
// Default configuration (threshold: 0.85)
const detector = new ToxicityDetector();
// Custom threshold for higher precision
const strictDetector = new ToxicityDetector({ threshold: 0.95 });
// Check only specific categories
const customDetector = new ToxicityDetector({
threshold: 0.8,
labels: ['insult', 'threat', 'obscene'],
});Static Properties
ALL_LABELS
static readonly ALL_LABELS: ToxicityLabel[]Array of all available toxicity labels:
identity_attack— Attacks based on identity (race, religion, gender, etc.)insult— Personal insults and put-downsobscene— Obscene or vulgar contentsevere_toxicity— Highly toxic contentsexual_explicit— Sexually explicit contentthreat— Threats of violence or harmtoxicity— General toxic content
Public Methods
Complete Example
import { ToxicityDetector } from 'glin-profanity/ml';
async function moderateContent(text: string) {
const detector = new ToxicityDetector({ threshold: 0.85 });
// Preload model for faster response
await detector.loadModel();
const result = await detector.analyze(text);
if (result.isToxic) {
console.log('Toxic content detected!');
console.log('Categories:', result.matchedCategories.join(', '));
console.log('Score:', result.overallScore.toFixed(2));
return { allowed: false, reason: result.matchedCategories };
}
return { allowed: true };
}
// Usage
const result = await moderateContent('you are an idiot');
// { allowed: false, reason: ['insult', 'toxicity'] }import { ToxicityDetector } from 'glin-profanity/ml';
class ChatModerator {
private detector: ToxicityDetector;
private initialized = false;
constructor() {
this.detector = new ToxicityDetector({
threshold: 0.8,
labels: ['insult', 'threat', 'toxicity'],
});
}
async init() {
if (!this.initialized) {
await this.detector.loadModel();
this.initialized = true;
}
}
async checkMessage(message: string) {
await this.init();
const result = await this.detector.analyze(message);
return {
allowed: !result.isToxic,
score: result.overallScore,
categories: result.matchedCategories,
processingTime: result.processingTimeMs,
};
}
}
// Singleton instance
const moderator = new ChatModerator();
// Usage in message handler
app.post('/chat', async (req, res) => {
const check = await moderator.checkMessage(req.body.message);
if (!check.allowed) {
return res.status(400).json({
error: 'Message rejected',
reason: check.categories
});
}
// Process message...
});import { ToxicityDetector } from 'glin-profanity/ml';
async function moderateComments(comments: string[]) {
const detector = new ToxicityDetector({ threshold: 0.85 });
await detector.loadModel();
// Batch process for efficiency
const results = await detector.analyzeBatch(comments);
return comments.map((comment, i) => ({
text: comment,
isToxic: results[i].isToxic,
score: results[i].overallScore,
categories: results[i].matchedCategories,
}));
}
// Usage
const comments = [
'Great article, thanks for sharing!',
'You are such a moron',
'I disagree with your point about taxes',
'Kill yourself loser',
];
const moderated = await moderateComments(comments);
moderated.forEach((result) => {
console.log(`"${result.text.substring(0, 30)}..." - ${result.isToxic ? 'BLOCKED' : 'OK'}`);
});Performance Considerations
The ML model adds latency compared to rule-based detection. Use strategically based on your requirements.
| Metric | Value |
|---|---|
| Model load time | ~2-5 seconds (first load) |
| Single analysis | ~30-100ms |
| Batch analysis | ~10-30ms per item |
| Memory usage | ~50-100MB |
Optimization Tips
- Preload the model on application startup
- Use batch processing when analyzing multiple texts
- Consider
rules-firstmode in HybridFilter for speed with ML fallback - Dispose when done to free memory in serverless environments
Error Handling
import { ToxicityDetector } from 'glin-profanity/ml';
const detector = new ToxicityDetector();
try {
await detector.loadModel();
const result = await detector.analyze(text);
} catch (error) {
if (error.message.includes('dependencies not installed')) {
console.error('Install TensorFlow.js: npm install @tensorflow/tfjs @tensorflow-models/toxicity');
// Fallback to rule-based detection
} else {
console.error('ML analysis failed:', error);
}
}Cross-References
- HybridFilter — Combine ML with rule-based detection
- Toxicity Labels — Detailed explanation of each category
- ML Integration Guide — Setup and best practices
- TensorFlow Installation — Installation guide