Back to blog
Engineering14 min read

AI Safety Settings and Content Filters: Gemini and Others (2026)

AI safety settings compared: Gemini thresholds, Vertex AI filters, OpenAI moderation, Azure content filters and Claude refusals, with defaults and code, checked Sep 2026.

NH
Nafiul Hasan
Founder, Prompt Architects

TL;DR: AI safety settings differ sharply by vendor. Gemini lets you set a block threshold per harm category, and its default is Off on current models. OpenAI gives you a free moderation classifier instead of a threshold. Azure uses severity filters that need approval to switch off. Claude has no threshold and returns a documented refusal you handle in code.

What are AI safety settings, and which vendors offer them?

AI safety settings are the controls that decide what a model API blocks, flags or lets through. The phrase suggests one standard dial. In practice, each major vendor built something different, and the differences matter more than the names.

Here is the landscape as we found it on September 16, 2026, reading each vendor's own documentation:

Vendor / surfaceWhat you controlDefaultWhat you can't change
Gemini API (Google AI Studio)Threshold per category, per requestOff for Gemini 2.5 and 3Core harms, e.g. child safety
Gemini on Google Cloud (Enterprise Agent Platform)Threshold plus a probability or severity methodOff for gemini-3.5-flash and laterCSAM and PII filters
OpenAI APIA separate moderation classifier; the policy is yoursNo threshold to setThe model's own refusal behaviour
Azure OpenAI in Microsoft FoundrySeverity threshold per category, prompts and completions separatelyDefault filter applied to all deploymentsTurning filters off, unless approved
Amazon BedrockGuardrails you create and attachNone until you attach oneThe underlying model's own behaviour
Anthropic Claude APINo threshold; handle refusals, optionally fall backClassifiers on Fable 5.1, Fable 5 and Opus 5The classifier decision itself

Two ideas run through all of them. First, every vendor keeps a floor you cannot configure away. Second, a filter is not the same as the model's own judgment. Google says this directly on its Cloud page: filters act as a barrier, "but they don't directly influence the model's behavior." Changing a threshold won't make a model willing to write something it declines to write. It only changes what gets blocked after the fact.

How do Gemini API safety settings work?

The Gemini API lets you set a block threshold for each of four harm categories on every request. Google's safety settings page (last updated September 4, 2026) lists the adjustable categories as harassment, hate speech, sexually explicit and dangerous content, and states that core harms "are always blocked and cannot be adjusted."

The thresholds map between the AI Studio sliders and the API enum like this:

AI Studio labelAPI valueWhat it blocks
OffOFFTurns the filter off
Block noneBLOCK_NONENothing, regardless of probability
Block fewBLOCK_ONLY_HIGHHigh probability only
Block someBLOCK_MEDIUM_AND_ABOVEMedium or high
Block mostBLOCK_LOW_AND_ABOVELow, medium or high

The detail most tutorials miss is the default. Google's page says: "If the threshold is not set, the default block threshold is Off for Gemini 2.5 and 3 models." If you learned a different default on an older model, re-check it. On current Gemini models, if you want filtering, you have to switch it on.

The second detail is what the filter measures. The developer page says Gemini "blocks content based on the probability of content being unsafe and not the severity." Google's own example makes the point: "The robot punched me." might score as more likely unsafe than "The robot slashed me up.", even though the second is more violent. A threshold tunes your tolerance for likelihood, not for harm.

Setting a threshold in Python looks like this, following Google's own sample:

from google import genai
from google.genai import types

client = genai.Client()

response = client.models.generate_content(
    model="gemini-3.8-flash",
    contents="Summarise this incident report for the safety team.",
    config=types.GenerateContentConfig(
        safety_settings=[
            types.SafetySetting(
                category=types.HarmCategory.HARM_CATEGORY_DANGEROUS_CONTENT,
                threshold=types.HarmBlockThreshold.BLOCK_ONLY_HIGH,
            ),
            types.SafetySetting(
                category=types.HarmCategory.HARM_CATEGORY_HARASSMENT,
                threshold=types.HarmBlockThreshold.BLOCK_MEDIUM_AND_ABOVE,
            ),
        ]
    ),
)

When something is blocked, where it shows up depends on which side tripped. A blocked prompt sets promptFeedback.blockReason. A blocked response sets the candidate's finishReason to SAFETY, and Google notes that "The content that was blocked is not returned." Your code needs to check both.

Google also attaches a condition to loosening things: its page warns that "Applications that use less restrictive safety settings may be subject to review." Lower thresholds are allowed for legitimate needs, such as the page's own example of video game dialogue, but the terms of service still apply.

How is Gemini on Google Cloud different?

Google Cloud's version of the same feature has more options and, in places, different wording. The page now lives under the Gemini Enterprise Agent Platform name (the old Vertex AI URL redirects there), and it was last updated September 15, 2026.

Three differences are worth knowing before you copy settings between the two:

  • Severity is available, and it is the default method. The Cloud API offers two "harm block" methods, SEVERITY and PROBABILITY, and names SEVERITY as the default method. The developer API page describes probability-only blocking. The Cloud console, meanwhile, uses probability scores only.
  • OFF and BLOCK_NONE are not the same. Cloud describes OFF as "No automated response blocking and no metadata is returned." BLOCK_NONE also stops automated blocking, but the scores still come back so you can apply your own rules.
  • The default is stated per model. The Cloud page says that for gemini-3.5-flash "and subsequent models, OFF is the default value."

There is also a documentation inconsistency you should know about. The two Google pages define the categories differently. The developer page describes Hate speech as "Content that is rude, disrespectful, or profane." and gives Harassment the definition "Negative or harmful comments targeting identity and/or protected attributes." The Cloud page gives that same "targeting identity" definition to Hate Speech, and defines Harassment as "Threatening, intimidating, bullying, or abusive comments targeting another individual." We can't tell from the pages which one reflects the classifier. If category choice matters to you, test with your own examples rather than trusting either table.

Finally, Cloud adds non-configurable filters the developer page doesn't list in the same way, including one for sensitive personal information (SPII as a finish reason) and a citation filter that can stop output with RECITATION.

What does OpenAI offer instead of safety thresholds?

OpenAI doesn't publish a per-category block threshold on its models. It offers a separate classifier, the moderation endpoint, and leaves the policy decision to you. Its moderation guide (checked September 16, 2026) says "The moderation endpoint is free to use," and that omni-moderation-latest accepts text and images but "doesn't classify audio."

The endpoint returns three things per input: a flagged boolean, a true or false per category, and a category_scores value between 0 and 1. The categories include harassment, hate, illicit, self-harm, sexual and violence, several with sub-categories such as violence/graphic. Some categories are text-only; if you send an image without text, OpenAI says those return a score of 0.

There is also a newer, simpler route. You can pass a top-level moderation object in a Responses API request and get scores for both the input and the generated output in one call. OpenAI is clear about what that does and doesn't do: "The model still generates normally." It is a signal for your code, not a filter.

from openai import OpenAI

client = OpenAI()

response = client.responses.create(
    model="gpt-6-astra",
    input="Draft a reply to this customer complaint: ...",
    moderation={"model": "omni-moderation-latest"},
)

out = response.moderation.output
if out.type == "error":
    raise RuntimeError(out.message)
if out.flagged:
    send_to_review_queue(response)   # your policy, your code
else:
    show_to_user(response.output_text)

The model name in that sample comes from OpenAI's own guide. One warning from the same page is worth building around: OpenAI plans to keep upgrading the moderation model, so "custom policies that rely on category_scores may need recalibration over time." If you set a cut-off of 0.4 today, re-check it after an upgrade.

How do Azure OpenAI content filters work?

Azure applies a content filter to every model deployment by default, and you adjust it by severity rather than probability. Microsoft's content filtering page (the "classic" Foundry docs, checked September 16, 2026) describes four categories, hate, sexual, violence and self-harm, each scored at four severity levels: safe, low, medium and high.

You can set the threshold separately for prompts and for completions:

SettingFiltersPromptsCompletions
Low, medium, highEverything above safeYesYes
Medium, highMedium and highYesYes
HighHigh onlyYesYes
No filtersNothingYesIf approved
Annotate onlyNothing, but scores returnedYesIf approved

The approval line matters. Microsoft says "only customers who have been approved for modified content filtering have full content filtering control and can turn off content filters."

Azure also bundles optional filters most other vendors sell separately or don't offer: Prompt Shields for jailbreak and indirect prompt injection attempts, protected material detection for text and code, groundedness detection, and a PII filter. For indirect attacks, Microsoft notes you need to use document delimiters when building the prompt.

Handling is different again. A filtered prompt returns an HTTP 400 error. A filtered completion returns finish_reason: content_filter, and Microsoft warns that in rare cases a partial result can come back.

Can you change Claude's safety settings?

No, not with a threshold. We checked Anthropic's API documentation index on September 16, 2026 and found no per-category safety setting comparable to Gemini's. What Anthropic does document is how its classifiers decline requests and what you can do next.

Anthropic's refusals page says "Claude Fable 5.1, Claude Fable 5, and Claude Opus 5 include safety classifiers that can decline a request." A decline is not an error. It is an HTTP 200 with stop_reason: "refusal" and a stop_details object whose category can be cyber, bio, frontier_llm, reasoning_extraction or general_harms. For several of those, Anthropic's table notes that benign work "can also trigger this category."

Three documented behaviours make refusals easier to live with:

  1. Pre-output refusals aren't billed. Anthropic says you are not billed for a refusal that arrives before any output, though it still counts against rate limits.
  2. You can fall back to another model. In beta on the Claude API, setting fallbacks to "default" with the server-side-fallback-2026-07-01 header retries a declined request on a model Anthropic recommends for that category. It isn't available on Bedrock, Google Cloud or Foundry, where Anthropic points you to its SDK middleware instead.
  3. Monitoring needs its own signal. Because a refusal is a 200, Anthropic warns that monitoring built on error rates "never sees it." Count refusals explicitly.

For moderating your own users' content, Anthropic's documented approach is a content moderation guide that uses Claude itself as the classifier, rather than a built-in filter. Our post on what to do when Claude refuses covers the prompt side.

What about Amazon Bedrock and xAI?

Amazon Bedrock takes the most modular approach. Bedrock Guardrails is a separate object you create, version and attach at inference time, or call on its own through the ApplyGuardrail API. AWS lists content filters for Hate, Insults, Sexual, Violence, Misconduct and Prompt Attack with configurable strength, plus denied topics, word filters, sensitive information filters with custom regex, contextual grounding checks and Automated Reasoning checks. AWS notes guardrails evaluate inputs and responses "excluding reasoning content blocks".

xAI is harder to describe. We read the documentation index at docs.x.ai/llms.txt on September 16, 2026 and found no page about safety settings, content filters or moderation. That is not proof that no control exists, and xAI's hosted models may behave differently on third-party clouds. If you build on Grok and need a moderation layer, plan to add one yourself, such as a separate classifier, and confirm the current position with xAI.

How should you choose settings for a legitimate use case?

Start from your use case, not from the loosest setting that works. A medical triage tool, a game studio and a children's homework app need different thresholds, and every vendor above frames its controls that way.

A process that holds up:

  1. Write down what your product must allow and must never show. Be specific: "clinical descriptions of self-harm injuries for triage nurses" is a policy; "medical stuff" is not.
  2. Build a test set of 50 to 100 real examples, split into should-pass and should-block. Include borderline cases.
  3. Run the set at each threshold and log the category and score, not just pass or fail. Google recommends exactly this kind of testing, noting that filters "might occasionally block benign content or miss harmful content."
  4. Pick the strictest setting that passes your should-pass set. Loosen one category at a time.
  5. Decide what happens on a block: a friendly message, a retry with more context, a fallback model, or a human review queue.
  6. Re-run the set when the vendor ships a new model. Google says its configurable filters aren't versioned independently of models, and OpenAI warns its moderation model will change.

How do you handle a block in code?

Check the vendor's specific signal, log it, and route it. Here is a single dispatcher that covers the four signals documented above:

def classify_block(vendor: str, resp: dict) -> str | None:
    """Return a block label, or None if the response is usable."""
    if vendor == "gemini":
        if resp.get("promptFeedback", {}).get("blockReason"):
            return "gemini:prompt:" + resp["promptFeedback"]["blockReason"]
        cand = (resp.get("candidates") or [{}])[0]
        if cand.get("finishReason") in {"SAFETY", "PROHIBITED_CONTENT", "SPII", "RECITATION"}:
            return "gemini:response:" + cand["finishReason"]
    elif vendor == "azure":
        if resp.get("_http_status") == 400:
            return "azure:prompt:filtered"
        if any(c.get("finish_reason") == "content_filter" for c in resp.get("choices", [])):
            return "azure:response:content_filter"
    elif vendor == "anthropic":
        if resp.get("stop_reason") == "refusal":
            cat = (resp.get("stop_details") or {}).get("category")
            return f"anthropic:refusal:{cat}"
    elif vendor == "openai_moderation":
        if resp.get("flagged"):
            return "openai:flagged"
    return None

Treat this as a starting shape. Field names follow each vendor's documentation as of September 16, 2026, and they do move.

How do you prompt around false positives legitimately?

Give the model and the classifier the context a human reviewer would need. Most false positives come from text that looks like a harmful request with the purpose stripped out.

Things that help, and that no vendor treats as evasion:

  • State the role and the audience. "You are drafting guidance for hospital pharmacists" changes how a dosage question reads.
  • State the purpose. "This summary goes to our trust and safety team" explains why an abusive message is being quoted.
  • Quote rather than paraphrase. When you must process harmful user content, put it in clearly marked delimiters so it reads as material, not instruction. Our guide to system prompts across providers shows where that context belongs.
  • Ask for the safe version of the task. Summarise, classify or respond to the content rather than reproducing it.

What doesn't belong here is rewording a prohibited request until it slips through. That is not configuration. For more on why harmless requests get refused in the first place, see why AI refuses harmless requests and designing for refusals.

Where does Prompt Architects fit?

Prompt Architects isn't a moderation tool, and it doesn't change any vendor's safety settings. If you need a classifier, use one of the services above.

What we do help with is the context half of the problem. Clear roles, stated purposes and delimited source material are exactly what our prompt generator adds when it rewrites a rough request, and a saved prompt keeps that context consistent across a team, so the same legitimate task isn't phrased five different ways by five people. The free plan includes 5 prompt enhancements per day, according to our FAQ page.

Free Chrome Extension

Stop rewriting prompts. Start shipping.

Works with ChatGPT, Claude, Gemini, Grok, Midjourney, Ideogram, Veo3 & Kling. 4.8★ on the Chrome Web Store.

Create An Account

Frequently asked questions

Free Chrome Extension

Stop rewriting prompts. Start shipping.

Works with ChatGPT, Claude, Gemini, Grok, Midjourney, Ideogram, Veo3 & Kling. 4.8★ on the Chrome Web Store.

Create An Account