内容审核模型
约 1644 字大约 5 分钟
2026-09-15
合集说明
本篇合并自参考文档「Models / Moderation Models」章节,按官方文档顺序排列:(各篇之间以 --- 分隔)
- Moderation Models(内容审核模型)
- OpenAI Moderation(OpenAI 内容审核)
- Mistral AI Moderation(Mistral AI 内容审核)
Moderation Models(内容审核模型)
📌 原文地址:https://docs.spring.io/java-ai/reference/api/moderation.html 📌 原文版本:Java AI 2.0.1
Moderation(内容审核)就是给一段文本判个"安不安全"。在生成式 AI 场景里特别重要——你不希望用户输入诱导出违禁内容,也不希望模型输出直接喷用户一脸脏话。
白话解读
简单说就是"内容防火墙"。模型吐字前先过一遍审核模型,挂了就拦截。Spring 把这件事封装成 ModerationModel 接口,跟 Chat、Embedding 平级。
1. Java AI 的支持
Java AI 通过 ModerationModel 接口统一屏蔽各家差异。目前官方接入两家:
- OpenAI Moderation ——
omni-moderation-latest模型,覆盖 13 类违规维度(见02_OpenAI-Moderation.md) - Mistral AI Moderation ——
mistral-moderation-latest模型,覆盖 14 类维度(多出Law/Financial/PII,见03_Mistral-AI-Moderation.md)
关于 Azure OpenAI
2.0 起,Azure OpenAI 的审核也复用 OpenAI 客户端,把 endpoint 改成 Azure 资源地址即可。
2. 通用接口(ModerationModel / ModerationPrompt / ModerationResponse)
接口形态和 Chat/Embedding 几乎一致:
ModerationPrompt prompt = new ModerationPrompt("需要审核的文本");
ModerationResponse response = moderationModel.call(prompt);
Moderation moderation = response.getResult().getOutput();
boolean flagged = moderation.getResults().get(0).isFlagged();
Map<String, Boolean> categories = moderation.getResults().get(0).getCategories().asMap(); // 不同厂商字段名略有差异
Map<String, Double> scores = moderation.getResults().get(0).getCategoryScores().asMap();flagged:是否命中违规。categories:每类是否违规(布尔)。categoryScores:每类置信分数(0~1)。
注意差异
OpenAI 和 Mistral 两家的 Categories 字段集合不完全一样。直接调用 getCategories() 拿到的字段名不同厂商不同,需要按厂商分别处理。生产代码建议封装一层统一服务做归一化。
3. 启用 / 禁用
spring:
ai:
model:
moderation: openai # 或 mistral;none 表示禁用4. 下一步
- OpenAI 实现:
02_OpenAI-Moderation.md - Mistral AI 实现:
03_Mistral-AI-Moderation.md
OpenAI Moderation(OpenAI 内容审核)
📌 原文地址:https://docs.spring.io/java-ai/reference/api/moderation/openai-moderation.html 📌 原文版本:Java AI 2.0.1
OpenAI 的审核模型从 2024 年起统一为 omni-moderation-latest,多模态、覆盖 13 类违规维度。
白话解读
老版本的 text-moderation-stable 已经被淘汰,新版本 omni-moderation-latest 同时支持文本和图像,输出更稳定。
1. 准备工作
- 申请 OpenAI API Key。
- 配置:
spring:
ai:
openai:
api-key: ${OPENAI_API_KEY}
moderation:
options:
model: omni-moderation-latest- 引入依赖:
<dependency>
<groupId>org.springframework.ai</groupId>
<artifactId>spring-ai-starter-model-openai</artifactId>
</dependency>2. 连接属性(前缀 spring.ai.openai)
| 属性 | 说明 | 默认 |
|---|---|---|
base-url | API 地址 | api.openai.com |
api-key | API Key | - |
organization-id | 可选,指定组织 | - |
project-id | 可选,指定项目 | - |
timeout | 请求超时 | 60s |
max-retries | 重试次数 | 3 |
proxy | 代理 | - |
custom-headers | 自定义 HTTP 头 | - |
connection-pool-metrics-enabled | OkHttp 连接池指标 | false |
3. 审核属性(前缀 spring.ai.openai.moderation)
| 属性 | 说明 | 默认 |
|---|---|---|
base-url | 覆盖通用 base-url | api.openai.com |
api-key | 覆盖通用 api-key | - |
organization-id | 覆盖通用 organization-id | - |
project-id | 覆盖通用 project-id | - |
model | 审核模型 ID | omni-moderation-latest |
4. 启用 / 禁用
spring:
ai:
model:
moderation: openai # 默认
# moderation: none # 禁用5. 运行时选项(OpenAiModerationOptions)
OpenAiModerationOptions options = OpenAiModerationOptions.builder()
.model("omni-moderation-latest")
.build();
ModerationPrompt prompt = new ModerationPrompt("需要审核的文本", options);
ModerationResponse response = moderationModel.call(prompt);
Moderation moderation = response.getResult().getOutput();
System.out.println("id=" + moderation.getId());
System.out.println("model=" + moderation.getModel());
for (ModerationResult r : moderation.getResults()) {
System.out.println("flagged=" + r.isFlagged());
Categories cats = r.getCategories();
System.out.println("sexual=" + cats.isSexual());
System.out.println("hate=" + cats.isHate());
System.out.println("harassment=" + cats.isHarassment());
System.out.println("self-harm=" + cats.isSelfHarm());
// ... 13 个类别见下表
CategoryScores scores = r.getCategoryScores();
System.out.println("sexual_score=" + scores.getSexual());
// ...
}6. 13 个违规类别(OpenAI)
| 类别 | 中文释义 |
|---|---|
sexual | 性相关内容 |
hate | 仇恨言论 |
harassment | 骚扰 |
self-harm | 自残 |
sexual/minors | 涉及未成年人的性内容 |
hate/threatening | 带威胁性的仇恨 |
violence/graphic | 血腥暴力 |
self-harm/intent | 自残意图 |
self-harm/instructions | 自残指导 |
harassment/threatening | 带威胁性的骚扰 |
violence | 暴力 |
7. 手动配置(不依赖 starter)
<dependency>
<groupId>org.springframework.ai</groupId>
<artifactId>spring-ai-openai</artifactId>
</dependency>OpenAiModerationApi api = new OpenAiModerationApi(System.getenv("OPENAI_API_KEY"));
OpenAiModerationModel model = new OpenAiModerationModel(api);
ModerationResponse resp = model.call(new ModerationPrompt("需要审核的文本"));8. 自定义 HTTP 客户端
OpenAI 系列(Chat/Embedding/Image/Audio/Moderation)共用一个 OkHttp builder,通过 OpenAiHttpClientBuilderCustomizer 拦截:
@Bean
OpenAiHttpClientBuilderCustomizer loggerCustomizer() {
return builder -> builder.addInterceptor(new LoggingInterceptor());
}多 customizer 按 @Order / Ordered 顺序生效,Java AI 的默认设置先应用,用户 customizer 在后。
9. 示例代码
参考测试类 OpenAiModerationModelIT(仓库 spring-ai-integration-tests 模块)。
Mistral AI Moderation(Mistral AI 内容审核)
📌 原文地址:https://docs.spring.io/java-ai/reference/api/moderation/mistral-ai-moderation.html 📌 原文版本:Java AI 2.0.1
Mistral AI 在 2024 年底推出了自己的 Moderation 服务,由 mistral-moderation-latest 模型驱动。它在 OpenAI 那套类别基础上多了 3 个法务/合规维度:Law、Financial、PII。
白话解读
Mistral 的审核类别更"企业级"——除了仇恨/色情这些通用维度,还专门加了"违规违法"、"金融建议"、"个人隐私泄露"三条线。对 ToB、合规敏感场景特别有用。
1. 准备工作
- 申请 Mistral AI API Key。
- 配置:
spring:
ai:
mistralai:
api-key: ${MISTRAL_AI_API_KEY}
moderation:
options:
model: mistral-moderation-latest- 引入依赖:
<dependency>
<groupId>org.springframework.ai</groupId>
<artifactId>spring-ai-starter-model-mistral-ai</artifactId>
</dependency>2. 连接属性(前缀 spring.ai.mistralai)
| 属性 | 说明 | 默认 |
|---|---|---|
base-url | API 地址 | api.mistral.ai |
api-key | API Key | - |
3. 审核属性(前缀 spring.ai.mistralai.moderation)
| 属性 | 说明 | 默认 |
|---|---|---|
base-url | 覆盖通用 base-url | api.mistral.ai |
api-key | 覆盖通用 api-key | - |
model | 审核模型 ID | mistral-moderation-latest |
4. 启用 / 禁用
spring:
ai:
model:
moderation: mistral # 默认
# moderation: none # 禁用5. 运行时选项(MistralAiModerationOptions)
MistralAiModerationOptions options = MistralAiModerationOptions.builder()
.model("mistral-moderation-latest")
.build();
ModerationPrompt prompt = new ModerationPrompt("需要审核的文本", options);
ModerationResponse response = moderationModel.call(prompt);
Moderation moderation = response.getResult().getOutput();
System.out.println("id=" + moderation.getId());
System.out.println("model=" + moderation.getModel());
for (ModerationResult r : moderation.getResults()) {
System.out.println("flagged=" + r.isFlagged());
Categories cats = r.getCategories();
// 通用 11 类(与 OpenAI 同)
System.out.println("sexual=" + cats.isSexual());
System.out.println("hate=" + cats.isHate());
// Mistral 特有 3 类
System.out.println("law=" + cats.isLaw());
System.out.println("financial=" + cats.isFinancial());
System.out.println("pii=" + cats.isPii());
// 分数同理
}6. 14 个违规类别(Mistral)
| 类别 | 中文释义 |
|---|---|
sexual | 性相关内容 |
hate | 仇恨言论 |
harassment | 骚扰 |
self-harm | 自残 |
sexual/minors | 涉及未成年人的性内容 |
hate/threatening | 带威胁性的仇恨 |
violence/graphic | 血腥暴力 |
self-harm/intent | 自残意图 |
self-harm/instructions | 自残指导 |
harassment/threatening | 带威胁性的骚扰 |
violence | 暴力 |
law | 违法违规建议 |
financial | 金融/投资建议 |
pii | 个人隐私信息 |
三类企业维度
law:是否包含违法教唆、犯罪方法等。financial:是否包含具体投资/税务/洗钱建议。pii:是否包含 SSN、银行卡号、身份证号等隐私字段。
7. 手动配置
<dependency>
<groupId>org.springframework.ai</groupId>
<artifactId>spring-ai-mistral-ai</artifactId>
</dependency>MistralAiModerationApi api = new MistralAiModerationApi(System.getenv("MISTRAL_AI_API_KEY"));
MistralAiModerationModel model = new MistralAiModerationModel(api);
ModerationResponse resp = model.call(new ModerationPrompt("需要审核的文本"));8. 示例代码
参考测试类 MistralAiModerationModelIT。