Production Patterns

Safety Settings and Content Filters

Configure Gemini's safety filters to control harmful content thresholds for your application's requirements.

Content Safety in Gemini

Gemini includes built-in safety filters that evaluate content across four harm categories. You can configure the threshold for each category independently based on your application's requirements.

Harm Categories

CategoryWhat It Covers
HARM_CATEGORY_HARASSMENTThreatening, bullying, or harassing language
HARM_CATEGORY_HATE_SPEECHDiscriminatory content targeting groups
HARM_CATEGORY_SEXUALLY_EXPLICITSexual content
HARM_CATEGORY_DANGEROUS_CONTENTContent that enables real-world harm

Block Thresholds

SettingBehavior
BLOCK_NONEBlock nothing in this category
BLOCK_ONLY_HIGHBlock only high-confidence violations
BLOCK_MEDIUM_AND_ABOVEBlock medium and high (default)
BLOCK_LOW_AND_ABOVEBlock even low-confidence signals

Checking Safety Ratings

Always check response.candidates[0].finishReason. If it is "SAFETY", the response was blocked. The safetyRatings array shows the reason.

Best Practices

For consumer applications, use the defaults or BLOCK_MEDIUM_AND_ABOVE. For developer tools and APIs, you may relax filters with BLOCK_ONLY_HIGH. For medical or security research (with appropriate authorization), BLOCK_NONE may be needed.

Prompt Feedback

response.promptFeedback indicates whether your input was blocked before generation even started. Check this to distinguish input blocks from output blocks.

Example

typescript
import { GoogleGenerativeAI, HarmCategory, HarmBlockThreshold } from "@google/generative-ai";

const genAI = new GoogleGenerativeAI(process.env.GEMINI_API_KEY!);

// Custom safety settings for a developer tools application
const model = genAI.getGenerativeModel({
  model: "gemini-1.5-pro",
  safetySettings: [
    {
      category: HarmCategory.HARM_CATEGORY_HARASSMENT,
      threshold: HarmBlockThreshold.BLOCK_ONLY_HIGH,
    },
    {
      category: HarmCategory.HARM_CATEGORY_HATE_SPEECH,
      threshold: HarmBlockThreshold.BLOCK_MEDIUM_AND_ABOVE,
    },
    {
      category: HarmCategory.HARM_CATEGORY_SEXUALLY_EXPLICIT,
      threshold: HarmBlockThreshold.BLOCK_MEDIUM_AND_ABOVE,
    },
    {
      category: HarmCategory.HARM_CATEGORY_DANGEROUS_CONTENT,
      threshold: HarmBlockThreshold.BLOCK_ONLY_HIGH,
    },
  ],
});

async function safeGenerate(prompt: string) {
  const result = await model.generateContent(prompt);
  const response = result.response;

  // Check if input was blocked
  if (response.promptFeedback?.blockReason) {
    console.error("Input blocked:", response.promptFeedback.blockReason);
    return null;
  }

  const candidate = response.candidates?.[0];
  if (!candidate) {
    console.error("No candidates returned");
    return null;
  }

  // Check if output was blocked
  if (candidate.finishReason === "SAFETY") {
    console.warn("Output blocked due to safety. Ratings:");
    candidate.safetyRatings?.forEach(rating => {
      if (rating.blocked) {
        console.warn(`  ${rating.category}: ${rating.probability}`);
      }
    });
    return null;
  }

  return response.text();
}

const output = await safeGenerate("Explain how SQL injection attacks work for security education.");
if (output) console.log(output);
Try it yourself — TYPESCRIPT