Gemini 模型旨在优先考虑安全性。不过,它们仍可能会生成有害的回答,尤其是在明确提示的情况下。为了进一步提高安全性并尽量减少滥用情况,您可以配置安全过滤器来屏蔽可能有害的回答。
提供两层安全保护:
内置核心保护功能:
- 所有 Gemini 模型都具有内置保护措施,可防范严重危害(例如剥削儿童、网络攻击和危险武器)。
- 这些保护措施始终有效,会自动应用于所有提示和回答,并且无法修改或停用。
可配置的安全过滤器:
- Gemini API 提供了额外的可配置安全过滤器,您可以使用应用中的安全设置进行定义。
- 通过这些设置,您可以控制在四个主要有害类别(骚扰、仇恨言论、露骨色情内容和危险内容)中屏蔽内容的阈值。
重要安全概念
在处理 Gemini 模型的安全问题时,请务必了解以下重要概念:
安全过滤器:服务器端分类器,用于根据 Google 的安全维度评估提示和模型回答。这些过滤器会根据您配置的安全设置 屏蔽内容
安全评分:模型在响应对象中返回的评估元数据。这些评级表示针对每个危害类别检测到的潜在危害的概率和严重程度。
支持的模型
gemini-4-argongemini-3.8-flash(以及旧版gemini-3.7-flash、gemini-3.6-flash和gemini-3.5-flash)gemini-3.5-flash-lite(以及旧版gemini-3.1-flash-lite)gemini-nano-banana-2.1(Nano Banana 2.1)gemini-3.1-flash-image(Nano Banana 2)gemini-3.1-flash-lite-image(Nano Banana 2 Lite)gemini-3-pro-image(Nano Banana Pro)
gemini-3.1-pro-preview 模型以及通用和图片生成 Gemini 2.5 模型(已弃用)也支持此功能。
在应用中配置安全设置
|
点击您的 Gemini API 提供商,以查看此页面上特定于提供商的内容和代码。 |
您可以在初始化 GenerativeModel 实例时配置安全设置。该配置会在该模型实例的生命周期内保持不变。
请参阅本页下文,了解可用的危害类别以及您可以为每个类别设置的阈值。
Swift
在创建 GenerativeModel 实例时配置 SafetySetting:
import FirebaseAILogic
let safetySettings = [
SafetySetting(harmCategory: .harassment, threshold: .blockOnlyHigh),
SafetySetting(harmCategory: .hateSpeech, threshold: .blockMediumAndAbove)
]
// Specify the safety settings as part of creating the `GenerativeModel` instance.
let model = FirebaseAI.firebaseAI(backend: .googleAI()).generativeModel(
modelName: "GEMINI_MODEL_NAME",
safetySettings: safetySettings
)
// ...
Kotlin
在创建 GenerativeModel 实例时配置 SafetySetting:
// ...
val safetySettings = listOf(
SafetySetting(HarmCategory.HARASSMENT, HarmBlockThreshold.ONLY_HIGH),
SafetySetting(HarmCategory.HATE_SPEECH, HarmBlockThreshold.MEDIUM_AND_ABOVE)
)
// Specify the safety settings as part of creating the `GenerativeModel` instance.
val model = Firebase.ai(backend = GenerativeBackend.googleAI()).generativeModel(
modelName = "GEMINI_MODEL_NAME",
safetySettings = safetySettings
)
// ...
Java
在创建 GenerativeModel 实例时配置 SafetySetting:
// ...
List safetySettings = List.of(
new SafetySetting(HarmCategory.HARASSMENT, HarmBlockThreshold.ONLY_HIGH),
new SafetySetting(HarmCategory.HATE_SPEECH, HarmBlockThreshold.MEDIUM_AND_ABOVE)
);
// Specify the safety settings as part of creating the `GenerativeModel` instance.
GenerativeModelFutures model = GenerativeModelFutures.from(
FirebaseAI.getInstance(GenerativeBackend.googleAI())
.generativeModel(
/* modelName */ "GEMINI_MODEL_NAME",
/* generationConfig is optional */ null,
safetySettings
)
);
// ...
Web
在创建 GenerativeModel 实例时配置 SafetySetting:
import { HarmBlockThreshold, HarmCategory, getAI, getGenerativeModel, GoogleAIBackend } from "firebase/ai";
// ...
const ai = getAI(firebaseApp, { backend: new GoogleAIBackend() });
const safetySettings = [
{
category: HarmCategory.HARM_CATEGORY_HARASSMENT,
threshold: HarmBlockThreshold.BLOCK_ONLY_HIGH,
},
{
category: HarmCategory.HARM_CATEGORY_HATE_SPEECH,
threshold: HarmBlockThreshold.BLOCK_MEDIUM_AND_ABOVE,
},
];
// Specify the safety settings as part of creating the `GenerativeModel` instance.
const model = getGenerativeModel(ai, {
model: "GEMINI_MODEL_NAME",
safetySettings,
});
// ...
Dart
在创建 GenerativeModel 实例时配置 SafetySetting:
import 'package:firebase_ai/firebase_ai.dart';
final safetySettings = [
SafetySetting(HarmCategory.harassment, HarmBlockThreshold.high),
SafetySetting(HarmCategory.hateSpeech, HarmBlockThreshold.medium),
];
// Specify the safety settings as part of creating the `GenerativeModel` instance.
final model = FirebaseAI.googleAI().generativeModel(
model: 'GEMINI_MODEL_NAME',
safetySettings: safetySettings,
);
// ...
Unity
在创建 GenerativeModel 实例时配置 SafetySetting:
// ...
var safetySettings = new SafetySetting[] {
new SafetySetting(HarmCategory.Harassment, SafetySetting.HarmBlockThreshold.OnlyHigh),
new SafetySetting(HarmCategory.HateSpeech, SafetySetting.HarmBlockThreshold.MediumAndAbove)
};
// Specify the safety settings as part of creating the `GenerativeModel` instance.
var ai = FirebaseAI.GetInstance(FirebaseAI.Backend.GoogleAI());
var model = ai.GetGenerativeModel(
modelName: "GEMINI_MODEL_NAME",
safetySettings: safetySettings
);
// ...
可用的危害类别
安全过滤器会根据以下可配置的危害类别评估提示和模型回答:
| 危害类别 | 说明 |
|---|---|
HARM_CATEGORY_HARASSMENT |
针对个人或身份的负面、威胁、恐吓、霸凌或辱骂性评论。 |
HARM_CATEGORY_HATE_SPEECH |
基于受保护的特征(例如种族、族裔、宗教、残障、年龄、国籍、退伍军人身份、性取向或性别认同)攻击、贬低、宣扬仇恨或煽动针对个人或群体的暴力的内容。 |
HARM_CATEGORY_SEXUALLY_EXPLICIT |
包含对性行为、色情内容或其他淫秽和色情内容的引用。 |
HARM_CATEGORY_DANGEROUS_CONTENT |
宣传、协助、鼓励或指导有害行为、非法商品和服务、武器、自残或危险活动。 |
HARM_CATEGORY_CIVIC_INTEGRITY |
可能用于误导选民或破坏公民和选举程序的内容。(在部分型号和地区受支持)。 |
不可配置的安全过滤条件
除了可配置的类别之外,所有请求都会通过无法调整的系统级过滤器:
儿童性虐待内容 (CSAM) / 禁止的内容:被标记为包含禁止内容的提示或回答会立即被屏蔽 (
PROHIBITED_CONTENT)。敏感的个人身份信息 (SPII):系统会屏蔽可能泄露敏感个人数据(例如金融账号或身份证件号码)的回答 (
SPII)。
设置阈值
对于您要在应用中控制的每个危害类别,您都需要设置一个阈值。如果评估的内容达到或超过该阈值,则内容会被屏蔽。
安全评估的工作原理:概率与严重程度
安全过滤器会从两个不同的维度评估内容:
概率:模型对内容属于给定危害类别的置信度。
严重程度:如果内容有害,则表示潜在危害的严重程度。
每个维度都会被分配以下级别之一:NEGLIGIBLE、LOW、MEDIUM 或 HIGH。
内容可能具有高概率和低严重级别(例如,温和的喜剧玩笑或友好的侮辱),也可能具有低概率和高严重级别(例如,提及暴力的医学或历史讨论)。
可用的有害内容屏蔽阈值
您可以为要在应用中控制的危害类别设置以下任一阈值:
| 阈值 | 说明 | 允许的级别 |
|---|---|---|
BLOCK_LOW_AND_ABOVE |
限制性最高。 当概率(或严重程度)为 LOW、MEDIUM 或 HIGH 时屏蔽内容。
|
仅允许 NEGLIGIBLE
|
BLOCK_MEDIUM_AND_ABOVE |
中等限制。 当概率(或严重程度)为 MEDIUM 或 HIGH 时屏蔽内容。
|
允许 NEGLIGIBLE 和 LOW |
BLOCK_ONLY_HIGH |
限制性最低的有效过滤条件。 仅在概率(或严重程度)为 HIGH 时屏蔽内容。
|
允许 NEGLIGIBLE、LOW 和 MEDIUM
|
BLOCK_NONE |
此类别已停用自动屏蔽回复功能。系统仍会计算安全评级元数据,并将其随回答一起返回,以便您的应用可以执行自定义审核。 | 允许所有内容 |
OFF |
完全关闭此类别的内容安全过滤器。不会发生自动屏蔽,也不会返回安全评级元数据。 | 允许所有内容 |
检查安全评级并处理被屏蔽的内容
在请求期间,内容可能会在两个阶段被屏蔽:
提示被屏蔽 (
PromptFeedback):在模型生成任何输出之前,输入提示违反了安全过滤器。未返回任何回答候选。回答候选内容被屏蔽 (
finishReason == SAFETY):模型评估或生成的候选回答超出了您配置的阈值。生成的候选文本会被清除或隐去。
SafetyRating 对象
每个经过评估的提示或回答候选对象都包含一个 SafetyRating 对象数组。每个分级都提供以下信息:
Gemini Developer API 和 Agent Platform Gemini API (formerly Vertex AI) 均可用的属性:
category:评估的HarmCategory。probability:离散评分(NEGLIGIBLE、LOW、MEDIUM或HIGH)。blocked:如果此特定评分导致内容被屏蔽,则为true。
Agent Platform Gemini API (formerly Vertex AI) 提供的其他属性:
probabilityScore:一个介于0.0到1.0之间的浮点置信度分数。severity:离散严重级别(NEGLIGIBLE、LOW、MEDIUM或HIGH)。severityScore:一个介于0.0到1.0之间的浮点严重程度分数。
SafetyRating 对象示例
以下示例展示了当候选回答被安全过滤器屏蔽时的原始 JSON 响应载荷:
{
"candidates": [
{
"finishReason": "SAFETY",
"safetyRatings": [
{
"category": "HARM_CATEGORY_HARASSMENT",
"probability": "NEGLIGIBLE",
"blocked": false
},
{
"category": "HARM_CATEGORY_HATE_SPEECH",
"probability": "NEGLIGIBLE",
"blocked": false
},
{
"category": "HARM_CATEGORY_SEXUALLY_EXPLICIT",
"probability": "NEGLIGIBLE",
"blocked": false
},
{
"category": "HARM_CATEGORY_DANGEROUS_CONTENT",
"probability": "HIGH",
"blocked": true
}
]
}
],
"usageMetadata": {
"promptTokenCount": 24,
"totalTokenCount": 24
}
}
捕获代码中的安全错误
当内容被屏蔽时,客户端 SDK 会将屏蔽显示为异常或错误代码,以便您的应用可以妥善处理。
Swift
您可以捕获 GenerateContentError.promptBlocked 或 GenerateContentError.responseStoppedEarly:
do {
let response = try await model.generateContent("Your prompt here")
print(response.text ?? "No text generated.")
} catch GenerateContentError.promptBlocked(let response) {
// The input prompt was blocked
if let feedback = response.promptFeedback {
let reason = feedback.blockReason?.rawValue ?? "unknown"
print("Prompt blocked for reason: \(reason)")
for rating in feedback.safetyRatings {
let cat = rating.category.rawValue
let prob = rating.probability.rawValue
print("Category: \(cat), probability: \(prob)")
}
}
} catch GenerateContentError.responseStoppedEarly(let reason, let response) {
// Candidate response was blocked or stopped early
if reason == .safety {
print("Response blocked due to safety.")
if let candidate = response.candidates.first {
for rating in candidate.safetyRatings where rating.blocked {
print("Blocked by category: \(rating.category.rawValue)")
}
}
}
} catch {
print("Unexpected error: \(error)")
}
Kotlin
您可以捕获 PromptBlockedException 或检查 candidate.finishReason:
try {
val response = model.generateContent("Your prompt here")
val candidate = response.candidates.firstOrNull()
if (candidate?.finishReason == FinishReason.SAFETY) {
val blockedRating =
candidate.safetyRatings.firstOrNull { it.blocked }
println("Response blocked by category: ${blockedRating?.category}")
} else {
println(response.text)
}
} catch (e: PromptBlockedException) {
val reason = e.response?.promptFeedback?.blockReason
println("Prompt was blocked: $reason")
} catch (e: Exception) {
println("Error generating content: ${e.message}")
}
Java
您可以捕获 PromptBlockedException 或检查 candidate.getFinishReason():
try {
GenerateContentResponse response = model.generateContent("Your prompt here").get();
Candidate candidate = response.getCandidates().isEmpty() ? null : response.getCandidates().get(0);
if (candidate != null && candidate.getFinishReason() == FinishReason.SAFETY) {
SafetyRating blockedRating = null;
for (SafetyRating rating : candidate.getSafetyRatings()) {
if (Boolean.TRUE.equals(rating.getBlocked())) {
blockedRating = rating;
break;
}
}
System.out.println("Response blocked by category: " +
(blockedRating != null ? blockedRating.getCategory() : "unknown"));
} else {
System.out.println(response.getText());
}
} catch (ExecutionException e) {
if (e.getCause() instanceof PromptBlockedException) {
PromptBlockedException pbe = (PromptBlockedException) e.getCause();
GenerateContentResponse blockedResponse = pbe.getResponse();
String reason = (blockedResponse != null && blockedResponse.getPromptFeedback() != null)
? String.valueOf(blockedResponse.getPromptFeedback().getBlockReason())
: "unknown";
System.out.println("Prompt was blocked: " + reason);
} else {
System.out.println("Error generating content: " + e.getMessage());
}
} catch (InterruptedException e) {
System.out.println("Generation was interrupted: " + e.getMessage());
}
Web
您可以检查 promptFeedback 和 candidate.finishReason:
try {
const response = await model.generateContent("Your prompt here");
// Check if the prompt was blocked
if (response.promptFeedback?.blockReason) {
console.warn(`Prompt blocked: ${response.promptFeedback.blockReason}`);
return;
}
const candidate = response.candidates?.[0];
if (candidate?.finishReason === "SAFETY") {
const blockedRating = candidate.safetyRatings?.find((r) => r.blocked);
console.warn(`Response blocked by category: ${blockedRating?.category}`);
} else {
console.log(response.text);
}
} catch (error) {
console.error("Error generating content:", error);
}
Dart
您可以检查 promptFeedback 和 candidate.finishReason:
try {
final response = await model.generateContent([Content.text('Your prompt here')]);
// Check if the prompt was blocked
if (response.promptFeedback?.blockReason != null) {
print('Prompt blocked: ${response.promptFeedback?.blockReason}');
return;
}
final candidate = response.candidates.firstOrNull;
if (candidate?.finishReason == FinishReason.safety) {
final blockedRating =
candidate?.safetyRatings?.where((r) => r.isBlocked == true).firstOrNull;
print('Response blocked by category: ${blockedRating?.category.name}');
} else {
print(response.text);
}
} catch (e) {
print('Error generating content: $e');
}
Unity
您可以检查 PromptFeedback 和 candidate.FinishReason:
try {
var response = await model.GenerateContentAsync("Your prompt here");
// Check if the prompt was blocked
if (response.PromptFeedback?.BlockReason != null) {
Debug.LogWarning($"Prompt blocked: {response.PromptFeedback.BlockReason}");
return;
}
var candidate = response.Candidates.FirstOrDefault();
if (candidate?.FinishReason == FinishReason.Safety) {
var blockedRating = candidate.SafetyRatings?.FirstOrDefault(r => r.Blocked);
Debug.LogWarning($"Response blocked by category: {blockedRating?.Category}");
} else {
Debug.Log(response.Text);
}
} catch (Exception ex) {
Debug.LogError($"Error generating content: {ex.Message}");
}
负责任的应用设计最佳实践
优雅的用户反馈:当内容被屏蔽时,切勿崩溃或显示空白屏幕。检测
finishReason == SAFETY或PromptBlockedException,并显示一条友好的消息,告知用户根据您的内容准则,无法满足其请求。使用
BLOCK_NONE进行自定义审核:如果您已有自己的客户端或服务器端审核流水线,请将阈值设置为BLOCK_NONE,以便接收模型的safetyRatings,而无需自动屏蔽,从而让您的应用能够强制执行自定义审核政策。查看服务条款:如果您使用限制较少的设置(
BLOCK_ONLY_HIGH或BLOCK_NONE),请确保您的应用继续遵守 Google 的使用限制政策。
其他内容生成控制选项
- 详细了解提示设计,以便影响模型生成符合您特定需求的输出。
- 配置模型参数,以控制模型如何生成回答,例如输出 token 数上限、重复输出 token 的概率等。
- 设置系统指令,以引导模型的行为。此功能就像一段预置指令,在模型接收到最终用户的进一步指令之前添加。
- 将响应 schema 与提示一起传递,以指定特定的输出 schema。此功能最常用于生成 JSON 输出,但也可用于分类任务(例如,当您希望模型使用特定标签或标记时)。