当前位置:首页 > 文章列表 > 科技周边 > 人工智能 > Moderation 怎样组合多类别判断

Moderation 怎样组合多类别判断

来源:17golang原创 2026-10-25 12:07:00 0浏览 收藏

Moderation 返回的重点不只是 flagged。如果业务要同时关心仇恨、骚扰、自残或暴力等多个类别,比较稳妥的做法是把 categories、category_scores 和 category_applied_input_types 分开处理,再把它们汇总成自己的业务动作。这样既能知道“命中了什么”,也能为不同类别保留不同阈值。

官方文档:https://developers.openai.com/api/docs/guides/moderation

组合多类别判断的核心是:先收集类别信号,再按类别应用规则,最后统一映射为放行、人工复核或拦截。不要把所有场景都压缩成一个固定分数。
  • 用 categories 判断模型是否标记了某个类别。
  • 用 category_scores 做类别级别的置信度分层。
  • 用 category_applied_input_types 确认分数适用于文本、图片还是两者。

先分清三个结果字段

一次 Moderation 结果通常位于 response.results[0]。flagged 是整体提示,categories 是逐类别的布尔值,category_scores 是逐类别分数。三者用途不同:整体提示适合做快速分支,类别布尔值适合记录命中原因,分数适合做更细的策略分层。

另外要注意,分类项并不一定对每种输入都适用。官方返回的 category_applied_input_types 会说明某个类别的分数对应哪些输入类型。处理图片和文字混合请求时,不能只看分数高低,还要把这个适用范围带进日志或规则判断。

Moderation Response、categories、category_scores 和输入类型的静态字段关系说明图
图1:Moderation 返回字段的结构说明图,查看类别标记、分数和适用输入类型之间的关系。

把多个类别收集成稳定标签

不要在业务代码里连续写很多层 if result.categories.xxx。可以先把值为真的类别收集成列表,同时从分数表取出对应分数,后面的策略层只处理统一的数据结构。

from openai import OpenAI

client = OpenAI()

def classify_text(text: str) -> dict:
    # 使用官方的多模态审核模型,输入这里只放一段文本。
    response = client.moderations.create(
        model="omni-moderation-latest",
        input=text,
    )
    # 先取第一条结果,避免把 SDK 对象直接散落到策略层。
    result = response.results[0]
    categories = result.categories
    scores = result.category_scores

    # 只收集被标记的类别,保留原始类别名以便记录和追踪。
    hits = [name for name, marked in categories.model_dump().items() if marked]
    score_map = scores.model_dump()
    return {
        "flagged": result.flagged,
        "hits": hits,
        "scores": {name: score_map.get(name, 0.0) for name in hits},
    }

这里的 hits 是“模型已经标记的类别”,不是业务最终结论。比如一个输入同时命中两个类别,列表会保留两个原因;即使整体 flagged 为真,也不应该丢掉类别信息。

为不同类别配置不同阈值

多类别判断的难点在于:类别的风险含义和业务处置不一样。可以把类别阈值放在配置里,而不是写死在函数分支中。高风险类别可以直接进入拦截,普通类别在中间区间交给人工复核,低于阈值再放行。阈值只是应用策略,不能把某个示例数字当成所有产品的通用标准。

POLICY = {
    # 高风险类别的分数达到阈值时,直接交给拦截策略。
    "violence": {"review": 0.35, "block": 0.75},
    # 普通类别保留更宽的人工复核区间。
    "harassment": {"review": 0.55, "block": 0.90},
    "hate": {"review": 0.55, "block": 0.90},
}

def decide(result: dict) -> dict:
    # 没有命中类别时,不需要进入逐类别阈值判断。
    if not result["hits"]:
        return {"action": "allow", "reasons": []}

    reasons = []
    action = "allow"
    for category in result["hits"]:
        # 未配置的类别保留为人工复核,避免静默放行未知信号。
        rule = POLICY.get(category)
        if rule is None:
            return {"action": "review", "reasons": [category]}
        score = result["scores"].get(category, 0.0)
        reasons.append({"category": category, "score": score})
        if score >= rule["block"]:
            action = "block"
        elif score >= rule["review"] and action == "allow":
            action = "review"
    return {"action": action, "reasons": reasons}

示例采用“拦截优先于复核,复核优先于放行”的组合规则。实际产品还可以按用户年龄、内容类型、地区或人工队列容量做二次分层,但这些因素应作为单独的业务字段,不要混进模型分数。

命中类别、分数表、类别阈值和放行人工复核拦截之间的静态策略关系说明图
图2:多类别策略映射结构图,查看类别命中、阈值与三类处理动作的边界。

把组合结果接到小项目的验收点

从零接入时可以把流程拆成三个模块:请求模块只负责调用 Moderation,归一化模块负责生成 hits 和 scores,策略模块负责输出 allow、review 或 block。这样换模型或调整类别阈值时,不会影响调用代码。

验收时至少准备四种输入:没有命中的文本、只命中一个类别的文本、同时命中多个类别的文本,以及命中类别但分数处于复核区间的文本。每条记录应包含类别名、分数、输入类型和最终动作;不要只记录一个无法解释原因的 flagged=true。

如果请求返回错误,策略层不能把“没有结果”当成“安全”。应把错误交给重试或人工处理分支,并明确记录请求失败原因。官方文档也提示,生成式请求中的 moderation 结果可能是错误对象,读取分数前要先判断结果类型。

相关问题

只看 flagged 可以吗?可以作为最简单的总开关,但无法说明命中了哪个类别,也不适合做差异化处置。

category_scores 能直接当风险概率吗?不建议这样理解。它是模型对类别的置信度,具体阈值应结合业务样本和处置成本校准。

多个类别同时命中时先处理哪个?先定义优先级,通常让拦截优先于人工复核,再优先于放行,同时保留全部命中原因。

版本声明
本文转载于:17golang原创 如有侵犯,请联系study_golang@163.com删除
Batch API 怎样提交离线任务Batch API 怎样提交离线任务
上一篇
Batch API 怎样提交离线任务
Datasets streaming 怎样流式读取大数据集
下一篇
Datasets streaming 怎样流式读取大数据集
查看更多
最新文章
查看更多
课程推荐
  • 前端进阶之JavaScript设计模式
    前端进阶之JavaScript设计模式
    设计模式是开发人员在软件开发过程中面临一般问题时的解决方案,代表了最佳的实践。本课程的主打内容包括JS常见设计模式以及具体应用场景,打造一站式知识长龙服务,适合有JS基础的同学学习。
    543次学习
  • GO语言核心编程课程
    GO语言核心编程课程
    本课程采用真实案例,全面具体可落地,从理论到实践,一步一步将GO核心编程技术、编程思想、底层实现融会贯通,使学习者贴近时代脉搏,做IT互联网时代的弄潮儿。
    516次学习
  • 简单聊聊mysql8与网络通信
    简单聊聊mysql8与网络通信
    如有问题加微信:Le-studyg;在课程中,我们将首先介绍MySQL8的新特性,包括性能优化、安全增强、新数据类型等,帮助学生快速熟悉MySQL8的最新功能。接着,我们将深入解析MySQL的网络通信机制,包括协议、连接管理、数据传输等,让
    500次学习
  • JavaScript正则表达式基础与实战
    JavaScript正则表达式基础与实战
    在任何一门编程语言中,正则表达式,都是一项重要的知识,它提供了高效的字符串匹配与捕获机制,可以极大的简化程序设计。
    487次学习
  • 从零制作响应式网站—Grid布局
    从零制作响应式网站—Grid布局
    本系列教程将展示从零制作一个假想的网络科技公司官网,分为导航,轮播,关于我们,成功案例,服务流程,团队介绍,数据部分,公司动态,底部信息等内容区块。网站整体采用CSSGrid布局,支持响应式,有流畅过渡和展现动画。
    485次学习
查看更多
AI推荐
  • PubMedQA数据集详解:生物医学问答基准、功能与应用指南
    PubMedQA
    深入了解PubMedQA生物医学问答数据集,涵盖其核心功能、使用方法及在临床决策、药物研发等场景的应用,助力提升NLP模型性能。
    685次使用
  • H2O EvalGPT:开源LLM大模型评估与排行榜工具
    H2O EvalGPT
    H2O EvalGPT是H2O.ai推出的开源LLM评估平台,提供详细的大模型性能排行榜、行业特定基准测试及A/B测试功能,助您快速选择最适合项目的高性能大语言模型。
    699次使用
  • LMArena是什么?伯克利AI模型评估平台使用指南与功能解析
    LMArena
    LMArena是加州大学伯克利分校推出的AI模型匿名评测平台。通过盲测投票机制,用户可对比不同大模型回答并生成实时排行榜,助力开发者优化模型及用户选择最佳AI工具。
    753次使用
  • 斯坦福HELM:大语言模型Holistic Evaluation整体评估框架详解
    HELM
    深入了解斯坦福推出的HELM(Holistic Evaluation of Language Models)大模型评测体系。本文解析其核心功能、安装配置步骤及应用场景,涵盖准确性、公平性、鲁棒性等多维度指标,助力开发者全面优化语言模型性能。
    717次使用
  • MMBench详解:多模态大模型基准测试、功能特点与使用指南
    MMBench
    MMBench是由上海人工智能实验室等机构联合推出的多模态基准测试平台,提供细粒度能力评估、大规模数据集及VLMEvalKit工具。本文详细介绍其核心功能、安装使用方法及应用场景,助力开发者全面评估多模态模型性能。
    552次使用
微信登录更方便
  • 密码登录
  • 注册账号
登录即同意 用户协议 和 隐私政策
返回登录
  • 重置密码