把 Jev 当护栏:noul 判断与低置信度兜底的内容风控实践
先说结论
- noul 是最轻量的判断 primitive:请求里一个
{"type":"noul","instructions":"..."},响应里只有一个 0~1 的noul值,官方示例中不含confidence字段,因此“置信度兜底”需要自己在代码里定义阈值或改用 choice 拿概率分布。 - 内容风控如果只问“是否违规”,noul 单值够用;如果要做多档风险分流,choice 多档加概率分布更合适,取舍取决于可解释性、分流粒度和下游复杂度。
- Jev 只吃文本(字符串/JSON/文本数组),不生成解释、不给理由;可审计的风控判定必须由业务方补规则和日志,这是基于官方边界的工程判断。
- 第三方 60 例基准显示清晰题很稳、模糊题容易错:整体准确率 91.7%,模糊题只有 71.4%,且 0.9~1.0 分箱装下 50/60 例,高风险场景必须留人工兜底。
- 最小骨架是:noul 值 → 阈值分档 → 高自动/中转人工/低拒绝并记录,日志至少记 state 摘要、noul 值、阈值、模型版本。
证据与过程
noul 的形状:一个 0~1 值,没有 confidence
官方 Primitives 文档把 TypeSafe 的三个 primitive 分成三类:Choice 回答“哪一个选项”,返回 choice、probabilities、confidence;Score 回答“哪一档”,返回 score、legend、probabilities、confidence;Noul 回答“这是不是真的”,返回 noul(0 到 1)。注意 Noul 的返回列表里没有 confidence,也没有 probabilities——这一点官方写在两个地方:Primitives 页的字段表明确写 “Noul has no separate confidence”,专门的 Confidence 文档页 也写 “All Score and Choice answers from TypeSafe include a probabilities property”,并补一句 “(Noul answers don’t carry one.)”。这与 Quick start 的 SDK 示例一致:response.answers["is_urgent"].noul 直接打印出 1.0,代码里没有去取 confidence 字段。因此,如果把 noul 当作内容风控的“护栏”,不能指望响应自带一个置信度来帮你分流。所谓低置信度兜底,必须在代码侧定义:要么把 noul 值本身当作连续分数,用阈值切出高中低;要么改用 Choice 多档,拿 probabilities 和 confidence 做更细的不确定度判断。这条结论来自我们对官方形状的比对,属于我的判断:noul 的设计适合“快判断”,不适合“自带不确定度”的场景。
两种护栏设计的对比:noul 单值与 choice 多档
内容风控里常见两种设计。第一种是用 noul 做单维判断,例如“这段文本是否包含辱骂”,返回一个 0~1 值,业务侧设置阈值。第二种是用 Choice 分多档,例如“这段文本的风险等级是低、中、高”,返回 choice 和一个概率分布。两种设计都能拿到官方支持,但取舍不同。
| 维度 | noul 单值 + 阈值 | choice 多档 + 概率分布 |
|---|---|---|
| 可解释性 | 只有一个连续分,需要业务侧解释分数含义 | 标签本身即可解释,概率分布能反映模型犹豫 |
| 分流粒度 | 依赖阈值划分,粒度由代码控制 | 多档天然支持多路分流,可结合概率差 |
| 下游处理复杂度 | 简单,但需要自己定义和验证阈值 | 稍复杂,需要处理概率分布和边缘情况 |
| 不确定度表达 | 只能把 noul 值当作代理分数 | 有 confidence,且可看其他类概率 |
| 适合场景 | 单一真/假判断,追求轻量 | 需要分级、审计、人工复核路径 |
这个表格基于官方 Primitives 能力,取舍判断是我的工程经验,不是官方推荐。对于内容风控这种高风险场景,如果只有“违不违规”一个判断,noul 足够;但若审计人员需要理解模型为什么犹豫,choice 多档更有优势。
Jev 的边界:只吃文本,不解释
官方 System One 概念页写明 Jev 目前只接受文本输入:字符串、JSON 对象和文本数组,图像、音频、视频不支持。System One 模型也不写回复、不生成代码、不解释推理。这意味着 Jev 作为护栏时,它只能告诉你“noul=0.87”,不会说明理由。对于内容风控这类要求可审计的场景,模型沉默是明显的边界:你必须自己在代码里补规则和日志。这里需要标清楚:Jev 只吃文本、不生成解释是官方边界;因此补审计日志和规则是我的判断。没有审计日志的 noul 判定很难回查,因为模型不会帮你写理由。
第三方基准:模糊题是短板,高置信度很稳
第三方 60 例基准报告(社区二手,非官方)用 60 个手工标注案例测试 Jev 对 agent 工具调用风险的分类,任务不是内容风控,但它的结论对高风险判断有参考价值。该基准显示整体准确率 91.7%(55/60);其中清晰题(n=34)准确率 100%,模糊题(n=14)只有 71.4%,对抗题(n=12)91.7%。分箱数据更直观:0.9~1.0 分箱容纳了 50/60 例预测,且该分箱准确率 98.0%。这说明模型在自认为有把握时很可靠,但模糊输入容易错;而真实内容风控里,模糊边界文本恰恰是常态。该报告作者还提醒 n=60 样本量小,不能过度解读,且该基准面向工具调用风险,不等于内容风控准确率。因此风控场景必须保留人工兜底,不能因为整体准确率高就把全自动策略铺满。
最小实现骨架:分档 + 审计日志
下面是一个最小实现骨架,展示 noul 风控的完整链路。注意响应中 model 字段可用于记录模型版本(例如 官方 Quick start 响应示例 里的 "model": "jev-1.13.0",属官方数据,但版本号会随时间变化),审计日志一定要带上。
def content_guard(state_text, threshold_high=0.9, threshold_low=0.5):
# 假设 client 已初始化,response 是一次 noul 调用
response = client.system_one(
state=state_text,
questions={
"is_violative": Noul(
instructions="Does this text contain hate speech, threats, or explicit violence?"
)
}
)
noul_value = response.answers["is_violative"].noul
model_version = getattr(response, "model", "unknown") # 官方示例中含 model 字段,如 jev-1.13.0
# 置信度兜底:noul 没有 confidence,只能用 noul 值分档
if noul_value >= threshold_high:
decision = "auto_pass" # 高分自动放行
elif noul_value >= threshold_low:
decision = "manual_review" # 中分转人工
else:
decision = "auto_reject" # 低分拒绝
log_entry = {
"state_digest": hash_text(state_text), # state 摘要,不存全文明文
"noul": noul_value,
"threshold_high": threshold_high,
"threshold_low": threshold_low,
"model": model_version,
"decision": decision,
"timestamp": utc_now(),
}
append_audit_log(log_entry)
return decision, noul_value
这个骨架的关键不是阈值具体是多少,而是:判定 → 分档 → 人工/自动 → 审计日志。阈值 0.9 和 0.5 只是示例,不属于官方建议,需要根据业务数据自己标定。日志里的 state_digest 用摘要而非原文,是隐私与审计的折中,也属于我的工程判断。
自己的判断:内容风控落地清单
- 先判断问题形状:如果风控问题可以缩成一个真/假判断,用 noul;如果需要风险等级或人工复核时要看概率分布,用 Choice 多档。
- 阈值必须业务侧验证:官方没有给出风控阈值建议,任何固定阈值都要用自己的标注集回测,第三方基准的准确率不能直接搬到内容风控。
- 审计日志是底线:Jev 不解释推理,所以日志必须记录 state 摘要、noul 值、阈值档位、模型版本、时间戳、最终决定。缺少任何一环,追溯链都会断。
- 模糊题单独压测:第三方基准显示模糊题准确率明显低于清晰题,内容风控里模棱两可的文本很多,要在评测集里提高模糊样本的比例。
- 人工兜底不要省:即使第三方基准里 0.9~1.0 那个置信度分箱的准确率是 98.0%(n=50),也意味着这一档里仍有错判——高置信不等于百分百;高风险决策必须保留人工或二次校验通道。(注意口径:这里说的是
confidence分箱,不是 noul 值本身,两者不是一回事。)
这次没核实的
- 官方有一篇专门的 Guardrails for LLMs cookbook(How-to 分类),讲的是用 TypeSafe 给 LLM 输出加护栏的做法;它给的是做法而不是统一阈值,因此具体阈值仍需按你的业务风险标定(本文代码里的 0.9 / 0.5 两档是我的示例设计,不是官方推荐值)。
- Noul 响应在未来版本是否会补上
confidence字段:未能核实,当前以 官方 Primitives 文档 的形状为准。 - 第三方基准准确率在内容风控任务上的迁移表现:未能核实,基准任务为 agent 工具调用风险分类,不是内容风控。
- 响应中
model字段是否始终返回以及版本号格式:官方 Quick start 示例中看到过jev-1.13.0,但 API 响应字段的完整稳定性未逐项核实。
参考来源
评论区
登录后可评论。