GEMINI LABJP
NANOLITE — Nano Banana 2 Lite is here: Google's fastest and most cost-efficient Gemini Image model, made for running lightweight image generation cheaplyOMNIFLASH — Gemini Omni Flash is in public preview, a natively multimodal model that lets enterprises and developers build custom, dynamic video workflowsAGENTS — Managed Agents expand with background: true for async server-side runs and polling, remote MCP server integration, and refreshing credentials across interactionsMEMORY — The Memory Bank IngestEvents API is generally available, decoupling event ingestion from memory generation so you can stream content continuouslyTHROUGHPUT — Provisioned Throughput now lets you submit up to seven pending orders for the same model and regionDEPRECATE — Image generation models shut down on August 17, and the Grok 4.1 family on the Gemini Enterprise Agent Platform on August 20NANOLITE — Nano Banana 2 Lite is here: Google's fastest and most cost-efficient Gemini Image model, made for running lightweight image generation cheaplyOMNIFLASH — Gemini Omni Flash is in public preview, a natively multimodal model that lets enterprises and developers build custom, dynamic video workflowsAGENTS — Managed Agents expand with background: true for async server-side runs and polling, remote MCP server integration, and refreshing credentials across interactionsMEMORY — The Memory Bank IngestEvents API is generally available, decoupling event ingestion from memory generation so you can stream content continuouslyTHROUGHPUT — Provisioned Throughput now lets you submit up to seven pending orders for the same model and regionDEPRECATE — Image generation models shut down on August 17, and the Grok 4.1 family on the Gemini Enterprise Agent Platform on August 20
Articles/API / SDK
API / SDK/2026-04-11Advanced

Building a Production Content Moderation System with Gemini API: A

A complete guide to building a production-grade content moderation system with the Gemini API. Covers custom safety criteria, multimodal inspection of text and images, async batch processing, Human-in-the-Loop workflows, and cost optimization.

gemini-api277content-moderation2production140multimodal44safety2python104

Premium Article

A phrase like "knife techniques" means one thing inside a cooking recipe and something else entirely inside a threatening post. For any service handling user-generated content, that kind of judgment is exactly what keyword matching and image classifiers keep missing.

Gemini 2.5 Pro and Flash close that gap with multimodal input and genuine contextual understanding — which is why building a custom moderation layer on Gemini has become a credible alternative to dedicated services like Amazon Rekognition or Azure Content Moderator.

The built-in safety filters (safety_settings), though, stop short of requirements like these:

  • Industry-specific prohibited content: Compliance requirements unique to healthcare, finance, or education platforms
  • Custom severity scoring: Weighted word lists or tiered response flows
  • Multimodal compound decisions: Evaluating text and images together as a unit
  • Audit logs and explainability: Recording why a particular decision was made

System Architecture

Core Components

A robust production moderation system is organized into four layers.

Layer 1: Ingest Layer Receives incoming user content and writes it to an async buffer (Redis or Cloud Tasks).

Layer 2: Moderation Processing Layer Worker processes that call the Gemini API to analyze content. Designed for horizontal scaling.

Layer 3: Decision and Action Layer A rules engine that routes analysis results to automatic approval, automatic rejection, or human review.

Layer 4: Human-in-the-Loop Layer Sends borderline cases to human moderators and feeds their decisions back as a training signal.

Choosing Your Gemini Model

To balance cost and accuracy, adopt a two-stage moderation strategy. Run Gemini 2.5 Flash for the initial screen -- it is optimized for high throughput and low cost -- and escalate to Gemini 2.5 Pro only when the confidence score falls near the boundary. Pro delivers higher accuracy for complex contextual decisions but at greater cost per token.


Moderating Text Content

Defining Custom Safety Criteria

One of Gemini API's biggest advantages for moderation is the ability to define business-specific judgment criteria in plain language via System Instructions.

import google.generativeai as genai
import json
from enum import Enum
from dataclasses import dataclass
from typing import Optional
 
genai.configure(api_key="YOUR_GEMINI_API_KEY")
 
class ModerationDecision(Enum):
    APPROVED = "approved"
    REJECTED = "rejected"
    REVIEW = "review"
 
@dataclass
class ModerationResult:
    decision: ModerationDecision
    confidence: float          # 0.0 to 1.0
    categories: list[str]      # Detected categories
    reason: str                # Decision rationale (for audit logs)
    escalate_to_human: bool    # Whether human review is needed
 
MODERATION_SYSTEM_PROMPT = """
You are a content moderator for a community platform.
Review each piece of content against the criteria below and respond ONLY in the specified JSON format.
 
## Criteria
 
### REJECTED (immediate removal)
- Threats or harassment targeting real individuals
- Exposure of personal information (home address, phone numbers, credit card numbers)
- Promotion of illegal goods or services
- Content inappropriate for minors
 
### REVIEW (send to human review)
- Inflammatory content related to politics or religion
- Medical or legal advice (requires expert verification)
- Borderline cases where confidence is below 0.7
 
### APPROVED
- General user posts that do not fall into the above categories
 
## Response format (return this JSON and nothing else)
{
  "decision": "approved|rejected|review",
  "confidence": numeric value between 0.0 and 1.0,
  "categories": ["list", "of", "detected", "categories"],
  "reason": "Decision rationale in 1 to 2 sentences"
}
"""
 
def moderate_text(content: str, model_name: str = "gemini-2.5-flash") -> ModerationResult:
    """Moderate a text content item."""
    model = genai.GenerativeModel(
        model_name=model_name,
        system_instruction=MODERATION_SYSTEM_PROMPT
    )
    
    try:
        response = model.generate_content(
            f"Please review the following content:\n\n{content}",
            generation_config=genai.GenerationConfig(
                response_mime_type="application/json",
                temperature=0.1,
                max_output_tokens=512
            )
        )
        
        result_data = json.loads(response.text)
        decision = ModerationDecision(result_data["decision"])
        confidence = float(result_data.get("confidence", 0.5))
        
        return ModerationResult(
            decision=decision,
            confidence=confidence,
            categories=result_data.get("categories", []),
            reason=result_data.get("reason", ""),
            escalate_to_human=(
                decision == ModerationDecision.REVIEW or
                confidence < 0.7
            )
        )
    except (json.JSONDecodeError, KeyError, ValueError) as e:
        return ModerationResult(
            decision=ModerationDecision.REVIEW,
            confidence=0.0,
            categories=["parse_error"],
            reason=f"API response parse error: {str(e)}",
            escalate_to_human=True
        )

The critical detail here is response_mime_type="application/json". Gemini API's JSON mode guarantees structured responses every time, dramatically reducing parse errors in production. Setting temperature=0.1 ensures consistent, repeatable decisions across similar inputs.

Expected output for a benign post:

{
  "decision": "approved",
  "confidence": 0.95,
  "categories": [],
  "reason": "General user inquiry with no harmful content detected."
}

Thank you for reading this far.

Continue Reading

What follows includes implementation code, benchmarks, and practical content we hope you'll find useful. This site runs without ads — server and development costs are supported entirely by members like you. If it's been helpful, we'd be truly grateful for your support.

WHAT YOU'LL LEARN
Developers frustrated by built-in safety filters can now implement a custom harmful-content detection system tailored to their business rules -- and have it running today
You will get a complete, production-ready architecture and working code for processing multimodal content (text and images) through an async batch pipeline
You will be able to apply a practical tuning strategy that optimizes detection accuracy, processing throughput, and cost simultaneously -- plus wire in a Human-in-the-Loop review flow
Secure payment via Stripe · Cancel anytime

Unlock This Article

Get full access to the rest of this article. Buy once, read anytime. This site is ad-free — your support goes directly toward keeping it running.

or
Unlock all articles with Membership →
Share

Thank You for Reading

Gemini Lab is ad-free, supported entirely by members like you. We publish practical guides daily with implementation code, benchmarks, and production-ready patterns. If you've found it useful, we'd love to have you on board.

  • Copy-paste ready implementation code
  • New advanced guides published daily
  • $5/mo or $10 for lifetime access
View Membership →

Related Articles

API / SDK2026-06-28
Mixing Text and Images in One File Search Skewed My Results Toward Images — Rebalancing by Modality After Retrieval
When you put text and images in a single File Search store with gemini-embedding-2, results can quietly skew toward one modality. Here is how to measure that skew and even it out after retrieval, using per-modality normalization and quota-based merging — with working code.
API / SDK2026-06-15
Defending Against Prompt Injection When You Pass External Text to the Gemini API
User reviews, scraped articles, and other untrusted text are the entry point for indirect prompt injection when you feed them to the Gemini API. Here is a prioritized, code-backed defense you can drop into a production pipeline: trust-boundary isolation, schema constraints, a two-stage screening pass, and output sanitization.
API / SDK2026-07-15
Sample what you already accepted — an audit budget that catches silent quality drift
A confidence gate only ever looks at output the model hesitated on. Silent drift sinks into the batch that sailed through. Working from a fixed 30-minutes-a-day review budget, this walks through deriving detection time from the binomial, reallocating the same budget across risk strata, and catching slow decay with a cumulative monitor.
📚RECOMMENDED BOOKS
Build a Large Language Model (From Scratch)
Sebastian Raschka
LLM Dev
Prompt Engineering for LLMs
Berryman & Ziegler
Prompting
AI Engineering
Chip Huyen
AI Eng
* Contains affiliate links
See all →