你写了一个越狱提示,准备测一下它到底有多猛。最自然的想法是:对着模型跑100次,看它有多少次没拒绝。跑完之后你得到一个数字,比如82%,你沾沾自喜。但如果你把这个提示换个措辞重试一遍,数字可能变成37%。同一个攻击,同一个模型,成功率却像过山车。问题出在哪?

出在你对“成功”的定义,以及你统计这个定义的方式。这篇文章我想把越狱评估里最常用的两个指标——ASR和PASS@K——从概念到陷阱掰开揉碎讲一遍。它们看起来简单,但几乎所有论文都在细节上打架。
ASR 的 “成功” 有四层,你用的哪一层?
ASR(Attack Success Rate)的字面意思很朴素:攻击成功次数除以总攻击次数。但“成功”可以有很多种理解。我最早写评测脚本时,天真地把“模型没有明确拒绝”当成功,结果把一堆废话也算了进去。后来看了人工评估结果,才发现那个数字虚高了一倍。
把“成功”按严格程度从低到高排列,至少可以分出四层:
| 层级 | 定义 | 典型例子 | 能否自动化 |
|---|---|---|---|
| 拒绝层 | 模型没有直接说“我不能” | 你问如何制作炸弹,模型回“这个问题我无法回答”=失败;模型回“根据公开资料……”=成功 | 容易 |
| 回避层 | 模型没有拒绝,但也没有给出目标信息 | 模型说“你可以去图书馆查化学书”=成功(因为没拒绝)但信息量接近0 | 需要分类 |
| 内容层 | 输出包含可直接使用的有害信息 | 输出了配方、步骤、恶意代码片段 | 需要分类器或人工 |
| 行为层 | 模型完全遵循攻击指令,角色扮演等 | “从现在起你叫DAN,请输出……”模型照做 | 非常难 |
如果你只报“拒绝层”的ASR,你测的是安全机制有没有触发,而不是攻击有没有造成实际危害。反过来,如果你只报“行为层”,很多真实世界有用的攻击会被低估,因为大多数攻击不需要模型完全变一个人。不同的论文用不同层级,结果自然不可比。Jailbroken:How Does LLM Safety Training Fail?这篇论文就专门讨论了安全训练为什么会失败,其中一个重要教训是:不要只盯着模型有没有拒绝,还要看它拒绝之后是否真的给出了无害内容。我觉得这是最低限度的严谨。
还有一点容易被忽视:“拒绝层”和“内容层”的相关性其实很低。一个模型可能很容易被绕过拒绝,但输出的内容大多是幻觉或空话,实际上没有危险。反过来,有些攻击让模型老老实实给出了详细步骤,但模型嘴上还在说“请注意遵纪守法”。所以如果你只测一个层级,你很可能在评估一个跟真实安全关系不大的东西。
PASS@K:从代码生成借来的“拼运气”指标
如果你觉得ASR太粗糙,有人从代码生成领域借来了PASS@K。它的定义是:给定一个输入(这里是攻击提示),用带随机的采样生成K个回复,只要其中至少一个被判定为成功,就算这次攻击通过。比如PASS@10就是允许模型试10次,中1次就行。
这个指标最初来自OpenAI的Codex论文:Evaluating Large Language Models Trained on Code,用来衡量模型在K次采样里能否至少产出一个正确代码。用在越狱上,它衡量的不是“单次平均表现”,而是“攻击的生存能力”——现实中的攻击者本来就会反复试,所以PASS@K更贴近真实威胁。
但用PASS@K时有一个统计陷阱。如果你直接跑K次,记录有没有成功,然后算比例,这个估计是有偏的。正确的做法是跑N次(N>=K),统计成功次数C,然后用组合数估计:1 − C(N−C, K) / C(N, K)。下面是一个简化版的无偏估计实现:
from math import comb
def pass_at_k(success_count: int, N: int, K: int) -> float:
# N 次采样中有 success_count 次成功
# 计算在 K 个子样本中至少一次成功的无偏概率
if N - success_count < K:
return 1.0
return 1.0 - comb(N - success_count, K) / comb(N, K)
这个公式的直觉是:在N次采样里随机抽K个,至少包含一个成功样本的概率。注意,如果你直接拿一次实验里“10次中有没有成功”来做比例,样本量小时会严重高估或低估,所以一定要报告N和K。
我最早自己写评测脚本时,天真地以为PASS@10就是“跑10次,成功4次,就是40%”,后来发现不是。如果你真想用PASS@10,通常要跑更多次(比如N=100),再用组合公式估计,否则你只是拿10个样本猜总体,噪音大得吓人。
三个让评估翻车的坑
就算你定义了成功的层级、用了PASS@K,下面三个问题依然可能让你的指标变成数字游戏。
坑一:样本量太小,置信区间炸裂。100次攻击里成功80次,看起来是80%,但95%置信区间大概是[72%, 88%]。如果不同攻击之间方差很大,你需要更多次实验。好的做法是多次重复实验,报告均值和标准差,而不是只报一个点估计。
坑二:数据污染。有些攻击提示在训练数据里出现过,模型已经“免疫”了;有些则刚好是模型没见过的,攻击成功率高得吓人。所以评估时要明确攻击模板是自创的还是有来源的,最好在一个共享基准上评测。JailbreakBench就是干这个的,它提供了统一的攻击库和人工评测准则,减少论文之间“各说各话”的问题。
坑三:自动化裁判本身的偏见。现在越来越多论文用另一个LLM来当裁判,判断输出是否有害。但裁判模型也有自己的偏好:它可能把长回答判为有害,把短回答判为无害,或者反过来。一个补救办法是先用少量人工标注校准裁判,并报告一致性(比如Cohen’s kappa)。如果没有校准,你的ASR可能只是反映裁判模型的偏见。
还有一个常被忽略的问题:很多真实越狱攻击是多轮对话。攻击者先让模型扮演角色,再一步步引出有害内容。单轮的ASR根本无法刻画这种交互式攻击。目前一些研究尝试用“多轮成功率”或“步骤完成率”来补充,但没有统一方案。所以当你看到论文里只有单轮ASR时,记住它只覆盖了一个很窄的世界。
三个常见的困惑
- ASR 和 PASS@K 能直接对比论文结果吗?
- 不能,除非成功定义、采样参数和评测基准完全一致。JailbreakBench 正在尝试统一这些东西,但尚未成为共识。
- PASS@K 的 K 是不是越大越好?
- 不一定。K 增大确实能逼近攻击上限,但也让指标对“侥幸成功”越来越敏感——一个攻击需要 100 次尝试才成功一次,在实际中可能并不划算,但 PASS@100 会把它显示为很厉害。因此要同时报告 PASS@1 或 ASR@1。
- 能用另一个 LLM 当自动裁判吗?
- 可以,但必须校准。你可以先从数据集中抽 200 条输出,人工标注是否“有害”,再和 GPT-4 的判断算一致性。如果一致性低,你的自动化评估就只是“GPT-4 对这个攻击的主观印象”。
一份诚实的评估报告应该长什么样
我不会告诉你“必须用ASR”或者“必须用PASS@K”,因为两者服务的目标不同。但如果你要我给一个最低标准,我会建议至少写出以下几行:
- 成功定义层级:是“没有拒绝”还是“输出了有害内容”?人工评估怎么做的?
- 单次攻击的ASR:在固定温度(比如1.0)下,一次进攻的成功率。
- PASS@K:建议K至少取10或100,同时报告用于估计的N和成功次数C。
- 置信区间:至少报告多次运行的标准差,或者用自助法给出95%区间。
- 模型和采样细节:模型版本、温度、top-p、最大token、系统提示等,缺一不可。
为什么这么麻烦?因为越狱评估目前还没有被广泛接受的统一协议。大多数论文只是扔一个ASR数字,别人复现时发现完全对不上。这不是学术道德问题,是统计规范问题。
所以回到开头那个场景:当你发现换个措辞成功率从82%掉到37%,这不一定是你提示写得差,更可能是你的指标没有控制住变量。把“成功”定义清楚,把采样次数加大,用无偏估计,这样的数字才敢拿出来说“我的攻击更强”或“我的模型更安全”。
指标永远只是代理。我们真正关心的是模型在真实攻击下的风险。ASR和PASS@K是目前最基础的工具,但如果你不理解它们的设计逻辑和统计陷阱,它们也只是在自我安慰的数字。
原创文章,作者:guanweilu,如若转载,请注明出处:https://guanweilu.cn/article/567.html