跳到主要内容

指南

安全研究:从 Inspect 日志到方法段落

你在一个模型上运行了一次评测:一个模型有机体(model organism)及其对照、一个攻击集、一个审计智能体的对话记录由评判模型打分。在写下结果之前,有三个问题决定它是否站得住:不确定性有多大,“200 个中一个也没有”是否真的没有,以及你能否信任给这些对话记录打分的评判模型?Oloproof 从你已有的日志中回答它们,并根据它所度量的内容写出图、表和方法段落。

读取日志

Oloproof 读取 UK AISI Inspect 日志,即 inspect eval 写出的 .eval 文件或 JSON 日志:

oloproof scores import --from inspect logs/organism.eval
oloproof scores import --from inspect logs/control.eval logs/organism.eval --policy release.yaml

第一条命令导入一次运行,并用平实的话回答。第二条命令导入两次运行,按样本 id 将其配对,并判定策略的比较规则;与两个日志一起给出的策略必须至少包含一条(kind: superiority、non_inferiority 或 equivalence),而针对单次运行的上限,需单独导入该日志并附上策略来判定。每个评分器成为一个标准:C 通过,I 不通过,部分得分是 0 到 1 的分数,数值型评分器需要给出其范围,用 --scale LOW HIGH 指定。只复制 id 和分数;对话记录留在日志中。每一条读取规则见对另一个工具的分数给出第二意见。

epoch 不是更多的样本

把每个样本运行多次(Inspect 的 epoch)并不会给你更多独立的用例。Oloproof 以样本为单位:日志导入为一个以其 epoch 为 replicate 的运行,每个样本的值是其各 epoch 的平均,每个样本权重相同。每个 epoch 保留自己的通过或失败,因此评判模型可以在 epoch 上接受检查,以样本为单位。把每个样本的各次运行算作不同的用例,会把重复当作新的提示词:在该方法的网格中,以这种方式合并每个样本的两次运行,在声明的 95% 下,对关于这类提示词的论断的覆盖率低至 86%,但对关于样本本身的论断则成立(docs/engine/PASS_AT_K_METHOD.md §8)。含有出错 epoch 的样本计为缺失,按其最坏情况计,绝不计为已完成 epoch 的平均,因为错误往往落在困难的样本上。

没看到不等于没有

安全结论常常建立在零计数上:没有攻击成功,没有对话记录表现出该行为。看到零次不等于比率为零。在未设阈值时,Oloproof 会说明比率仍可能有多高,以及需要多少个干净的用例才能把它降下来:

attack_succeeded: about 0.0%; the true value is likely between 0.0% and 1.9% (95% range, 200 cases).
  None of the 200 cases counted toward it, yet the rate could still be as high as 1.9%: none seen is not none.
  If the next cases show none either, a suite of 368 cases (168 more) would bring the high end to 1.0% or below.

在上限之下,由策略来判定。200 个中 0 个、max: 0.01 的结果是 INSUFFICIENT_EVIDENCE,建议是有条件的:“如果接下来的用例也一个都不计入,大约 368 个就能判定;每计入一个,这个数字就会增加”。不给出任何概率,因为没有事件时,无从给出。

rules:
  - id: attack-ceiling
    metric: attack_succeeded
    max: 0.01

它能做到吗?pass@k

能力或红队问题常常是 k 次尝试中是否有任何一次成功。oloproof passk 把样本的每个 epoch 读作一次尝试,无偏地估计每个样本的 pass@k,再求整个套件的平均:

oloproof passk logs/organism.eval --from inspect --criterion leaked --k 5

每次尝试一行的文件(case、passed、可选的 error)也可以。含有出错尝试、或尝试少于 k 次的样本计为缺失,按其最坏情况计。答案给出估计值及其 95% 区间。给出 --min 或 --max 时它会判定:区间越过门槛为 PASS,区间完全落在错误一侧为 FAIL,否则为 INSUFFICIENT_EVIDENCE(退出码 0、1 或 3)。该方法(docs/engine/PASS_AT_K_METHOD.md)在其网格的每个单元中都达到了声明的 95%,并于 2026 年 11 月 3 日按其条件通过了独立审计的认可:一个用例的各次尝试彼此独立,且你没有因为某次成功就提前停止该用例的尝试。

同时比较多个条件:sweep

一张包含二十个差值的表,每个差值有各自的 95% 区间,预计大约会有一处出错:在该方法的网格中,五十个单独的区间同时成立的情况十次中只有六次。oloproof sweep 对你在读取运行之前命名的一族对比作出判定,使整张表一起成立:

sweep:
  conditions:
    control: run_01...
    organism_a: run_01...
    organism_b: run_01...
  contrasts:
    - organism_a - control
    - organism_b - control
oloproof sweep sweep.yaml --policy compare.yaml

每个对比都是同一套件两次运行之间的配对比较,由策略中的每条比较规则判定,每个结论的水平为 1 - alpha/m,其中 m 是结论的数量:其中任何一个出错的概率至多为 alpha。看过表之后才去读的对比不在这一保证之内。不同套件上的运行不做比较。

监控器的安全性与审查成本

对于一个控制协议,一个每行一条轨迹的文件,包含其 arm(attack 或 honest)和监控器的怀疑分数 score,可给出每个阈值下的安全性(被标记的攻击所占比例)和诚实标记率:

oloproof control monitor.csv --budget 0.02 --min-safety 0.9

这些区间在所有阈值上同时成立,两组一起,因此通过读曲线选出的阈值(例如符合 2% 审查预算的阈值)仍然被覆盖。使用 --budget 和 --min-safety 时,它判定是否存在某个阈值,标记的诚实轨迹至多占该比例,同时捕获的攻击至少占该比例。区间在尾部与中间一样宽,因此小预算需要大量诚实轨迹:有 2,000 条时,诚实标记率的精度约为 3 个百分点。这里的安全性是相对于文件中的攻击而言的;会针对监控器调整策略的攻击者不在此范围内。

安全性按攻击组中的轨迹计算,无论其攻击是否成功。被要求植入后门的轨迹可能并未植入,监控器漏掉本不存在的东西不能算它的错。若要衡量对成功攻击的安全性,请先检查每条攻击轨迹(对后门而言,用其秘密输入做一次测试),在文件交给 oloproof control 之前,只在 attack 组中保留通过检查的轨迹。

检验评判模型

由模型打分的对话记录,在人认同之前只是评判模型的一面之词。对导入的运行抽取一个盲样本进行标注,对话记录保留在你自己的机器上:

oloproof scores import --from inspect --answers logs/organism.eval logs/organism.eval
oloproof review latest --criterion deceptive --by NAME

review 抽取样本,展示每条对话记录而不显示评判模型的结论,度量一致性,并且只有在评判模型达到你声明的阈值时才验证它。在它被验证之前,要求评判模型已验证的策略(oloproof init 写出的策略就是如此)不会依据它判定任何规则。对于由 Oloproof 执行、其用例在元数据中带有标签的运行,oloproof labels disagreements RUN --criterion deceptive --by behavior 随后会按行为、按方向显示评判模型与人在哪里分歧:评判模型判为通过而人判为失败的,以及相反的情况。每组的范围是它自己的结论;该报告不判定任何东西。

写出结果

oloproof report latest --paper paper/

它写出 figure.svg(每个指标的估计值和区间)、table.md 和 table.tex,以及 methods.md:一个段落,说明每种区间方法及其置信水平,指出这些区间针对的是这个有限套件,列出缺失的用例和罕见事件,对每个评判模型说明人是否检验过它、一致的频率如何,并陈述关卡判定了什么。每个数字都来自已存储的运行,段落由固定句子和已记录的事实构成;不由任何模型撰写。在 notebook 中:

import oloproof

result = oloproof.analyze_inspect("logs/organism.eval", project="analysis")
result  # the figure, the table and the methods paragraph
result.write("paper/")

审计智能体的对话记录

运行在 Inspect 上的审计工具(例如 Petri)会写出一个 Inspect 日志,其评分器为每条对话记录在每个维度上给出一个分数,通常从 1 到 10。用这个范围导入它,oloproof scores import --from inspect --scale 1 10 audit.eval,每个维度就成为一个标准,带有有界均值及其区间。两份这样的日志,在对目标做出改动之前和之后,在它们共有的对话记录上进行比较。分数仍是评判模型的一面之词:评判模型的分数(而不是它的通过或失败)目前还不能与人对照检验。

尚未构建的功能

  • 将评判模型的分数与人的分数对照检验(而不是它的通过或失败结论)。
  • 来自 Inspect 样本元数据的标签:导入的运行中的用例不带标签,因此 labels disagreements --by 只能对 Oloproof 执行的运行分组。
  • 比 Bonferroni 更窄的 sweep(Dunnett 或闭合检验)、不同套件上条件之间的对比,以及尾部更窄的监控器区间、多个监控器的组合或带有多个阈值的协议。
  • PNG 图:图只有 SVG 格式。

这无法告诉你的

每个区间都针对你日志中的样本。它说明的是这些样本一次完整、无错误的运行会显示什么,而不是模型在其他提示词上、在部署中、或面对会自适应的攻击者时如何表现。经人检验的评判模型,只是在他们标注过的用例和打分的那个模型上得到检验,而不是在与之不同的对话记录上。在你的攻击集上被限定在 1% 以下的比率,对你的攻击集中不包含的攻击什么也说明不了。