SAFETY SETTINGS · PER-CATEGORY THRESHOLDS

Gemini-style safety thresholds: inspect category decisions

Set a threshold for each harm category on a security-awareness tutor and see which legitimate lessons get blocked, which harmful replies get through, and what the learner sees.

Computed experiment · sixty inspection seconds

Your experiment

A security-awareness tutor must be allowed to explain ransomware and quote abusive phishing messages, and must never insult a learner, demean a group or supply working attack code. With every category at BLOCK_MEDIUM_AND_ABOVE, two legitimate lessons are blocked. Adjust each category until all nine synthetic responses are handled as intended, then switch the handling to text only.

Play replays the computed run over sixty inspection seconds; Next event steps, Restart rewinds, and Inspection time scrubs. Any input change recomputes the run and rewinds it without autoplay.

Event trace

    Computed data

    Final metrics

    Ratings are synthetic probability levels (NEGLIGIBLE, LOW, MEDIUM, HIGH); a response is blocked when any category reaches its threshold. Real Gemini ratings vary per call and some blocks (for example PROHIBITED_CONTENT or SPII) ignore thresholds. ADK Java surfaces a response block as errorCode SAFETY with no content parts, and LlmResponse does not carry the per-category ratings.

    Categories, thresholds and what a block looks like

    Each safety setting pairs a harm category with a threshold. Harassment threshold, Hate speech threshold, Sexually explicit threshold and Dangerous content threshold each choose BLOCK_LOW_AND_ABOVE, BLOCK_MEDIUM_AND_ABOVE, BLOCK_ONLY_HIGH or BLOCK_NONE. The tutor’s nine synthetic responses carry a probability level per category, and a response is blocked when any category reaches its threshold. In ADK Java a response block arrives as an LlmResponse with errorCode SAFETY and no content parts; the per-category ratings are not copied into it.

    The opening run: a standard profile blocks lessons

    With every category at BLOCK_MEDIUM_AND_ABOVE, five responses are blocked. Three are right: working code that disables antivirus (dangerous HIGH), an insult to the learner (harassment HIGH) and a joke demeaning a nationality (hate MEDIUM). Two are wrong for this tutor: a conceptual explanation of ransomware (dangerous MEDIUM) and a quoted abusive phishing message from a case study (harassment MEDIUM). 2 wrongly blocked, 0 wrongly delivered.

    Tuning per category

    Set Dangerous content threshold and Harassment threshold to BLOCK_ONLY_HIGH: the ransomware explanation and the case study are delivered, the attack code and the insult are still blocked, and the verdict is CALIBRATED. The categories are independent, so loosening one does not loosen the others: the demeaning joke is still blocked by hate speech at MEDIUM. Set Hate speech threshold to BLOCK_ONLY_HIGH as well and that joke is delivered, 1 wrongly delivered.

    Failure boundary: too loose, too strict, silent

    Set Dangerous content threshold to BLOCK_NONE and the antivirus-disabling code is delivered. Set it to BLOCK_LOW_AND_ABOVE and the phishing-urgency lesson and the scam-awareness list are blocked too, 4 wrongly blocked. Set Sexually explicit threshold to BLOCK_LOW_AND_ABOVE and the sextortion-awareness explanation (sexual LOW) is blocked. Set Blocked-response handling to Read the response text only: the same five responses are blocked, but each learner sees an empty reply instead of a refusal, because a blocked response has no text to read. Check errorCode, not the text.

    Reading the run and its limits

    Play reveals the responses three at a time, the category counts and the outcome over sixty inspection seconds; the table lists each response’s non-negligible ratings, the intended decision and what the learner sees. Next event, Restart, Speed and Inspection time control the replay, and any input change recomputes it. Real ratings come from the model on every call and vary; some block reasons ignore thresholds; and because LlmResponse carries no per-category ratings, an ADK callback cannot log which category fired. Set every category explicitly rather than relying on defaults.

    Views are my own and do not represent any employer, past or present.

    Search