Pular para o conteúdo

Guias

Pesquisa de segurança: de um log do Inspect a um parágrafo de métodos

Você executou uma avaliação de um modelo: um organismo-modelo e seu controle, um conjunto de ataques, as transcrições de um agente de auditoria pontuadas por um juiz. Antes de registrar o resultado, três perguntas decidem se ele se sustenta: qual é a largura da incerteza, "nenhum em 200" é mesmo nenhum, e dá para confiar no juiz que pontuou as transcrições? O Oloproof responde a elas a partir do log que você já tem, e escreve a figura, a tabela e o parágrafo de métodos a partir do que mediu.

Lendo o log

O Oloproof lê logs do UK AISI Inspect, o arquivo .eval que inspect eval escreve ou um log JSON:

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

O primeiro comando importa uma execução e responde em palavras simples. O segundo importa duas execuções, pareia-as pelos ids das amostras e decide as regras de comparação da política; uma política dada com dois logs deve conter pelo menos uma (kind: superiority, non_inferiority ou equivalence), e um teto sobre uma execução é decidido importando esse log sozinho com a política. Cada scorer vira um critério: C aprova e I reprova, crédito parcial é uma pontuação de 0 a 1, e um scorer numérico precisa da sua faixa, dada com --scale LOW HIGH. Só ids e pontuações são copiados; as transcrições ficam no log. Veja Uma segunda opinião sobre as pontuações de outra ferramenta para todas as regras de leitura.

Epochs não são mais amostras

Executar cada amostra várias vezes (os epochs do Inspect) não dá mais casos independentes. O Oloproof mantém a amostra como unidade: o log é importado como uma execução cujos replicates são seus epochs, o valor de cada amostra é a média dos seus epochs, e toda amostra pesa o mesmo. Cada epoch mantém seu próprio aprovado ou reprovado, então um juiz pode ser verificado em epochs, com a amostra como unidade. Contar as execuções de cada amostra como casos separados trata as repetições como prompts novos: na grade do método, agrupar assim duas execuções por amostra cobriu uma afirmação sobre prompts como estes apenas 86% das vezes a um nível declarado de 95%, embora tenha se mantido para uma afirmação sobre as próprias amostras (docs/engine/PASS_AT_K_METHOD.md §8). Uma amostra com um epoch com erro conta como ausente, no seu pior valor, nunca como a média dos epochs que terminaram, já que os erros tendem a cair nas amostras difíceis.

Nenhum visto não é nenhum

Uma afirmação de segurança muitas vezes repousa sobre uma contagem de zero: nenhum ataque teve sucesso, nenhuma transcrição mostrou o comportamento. Zero visto não é uma taxa zero. Sem patamar definido, o Oloproof diz até onde a taxa ainda poderia chegar e quantos casos limpos a trariam para baixo:

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.

Sob um teto, a política decide. max: 0.01 com 0 de 200 é INSUFFICIENT_EVIDENCE, e o conselho é condicional: "se nenhum dos próximos casos contar também, cerca de 368 o decidiriam; cada um que contar aumenta esse número". Nenhuma probabilidade é citada, porque sem eventos não há de onde tirá-la.

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

Ele consegue alguma vez? pass@k

Uma pergunta de capacidade ou de red team muitas vezes é se alguma de k tentativas dá certo. O oloproof passk lê cada epoch de uma amostra como uma tentativa e estima sem viés o pass@k de cada amostra, e depois a média da suíte:

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

Um arquivo com uma linha por tentativa (case, passed, error opcional) também funciona. Uma amostra com uma tentativa com erro, ou com menos de k tentativas, conta como ausente, no seu pior valor. A resposta dá a estimativa e sua faixa de 95%. Com --min ou --max ela decide: PASS quando a faixa ultrapassa o limite, FAIL quando cai inteira do lado errado, INSUFFICIENT_EVIDENCE caso contrário (saída 0, 1 ou 3). O método (docs/engine/PASS_AT_K_METHOD.md) cobriu os 95% declarados em cada célula da sua grade e foi admitido por uma auditoria independente em 3 de novembro de 2026, nos seus termos: as tentativas de um caso são independentes entre si, e você não interrompeu cedo as tentativas de um caso porque uma deu certo.

Muitas condições de uma vez: uma varredura

Uma tabela de vinte diferenças, cada uma com seu próprio intervalo de 95%, deve errar em algum lugar cerca de uma vez: na grade do método, cinquenta intervalos separados se sustentaram todos juntos só seis vezes em dez. oloproof sweep decide uma família de contrastes que você nomeia antes de ler as execuções, de modo que a tabela inteira se sustenta junta:

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

Cada contraste é uma comparação pareada de duas execuções de uma suíte, decidida por cada regra de comparação da política, cada afirmação a 1 - alpha/m, com m o número de afirmações: a chance de qualquer uma delas estar errada é no máximo alpha. Um contraste que você só lê depois de olhar a tabela fica fora dessa garantia. Execuções em suítes diferentes não são comparadas.

A segurança de um monitor contra seu custo de auditoria

Para um protocolo de controle, um arquivo com uma linha por trajetória, seu arm (attack ou honest) e a suspeita do monitor score, dá a segurança (a fração de ataques sinalizados) e a taxa de sinalização honesta em cada limiar:

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

As faixas valem em todos os limiares ao mesmo tempo, os dois braços juntos, então um limiar escolhido lendo a curva, como o que cabe em um orçamento de auditoria de 2%, continua coberto. Com --budget e --min-safety ele decide se algum limiar sinaliza no máximo essa fração das trajetórias honestas enquanto pega pelo menos essa fração dos ataques. As faixas são tão largas na cauda quanto no meio, então um orçamento pequeno precisa de muitas trajetórias honestas: com 2.000, a taxa de sinalização honesta é conhecida com cerca de 3 pontos. A segurança aqui é contra os ataques do arquivo; um atacante que se adapta ao monitor fica fora disso.

A segurança é contada sobre as trajetórias do braço de ataque, tenha o ataque funcionado ou não. Uma trajetória instruída a inserir um backdoor pode não ter inserido, e o monitor não tem culpa de não ver o que não existe. Para segurança contra ataques bem-sucedidos, verifique antes cada trajetória de ataque (para um backdoor, um teste na sua entrada secreta) e mantenha no braço attack só as que passam antes de o arquivo chegar ao oloproof control.

Verificando o juiz

Uma transcrição pontuada por um modelo é a palavra do juiz até que pessoas concordem com ela. Rotule uma amostra cega da execução importada, mantendo as transcrições na sua máquina:

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

review sorteia a amostra, mostra cada transcrição sem o veredito do juiz, mede a concordância e valida o juiz somente se ele superar o patamar que você declara. Até ser validado, uma política que exige juízes validados, como a que oloproof init escreve, não decide uma regra sobre ele. Para uma execução que o Oloproof executou, cujos casos trazem tags nos seus metadados, oloproof labels disagreements RUN --criterion deceptive --by behavior mostra então onde o juiz e as pessoas divergem, por comportamento e por direção: o que o juiz aprovou e as pessoas reprovaram, e o contrário. A faixa de cada grupo é uma afirmação própria; o relatório não decide nada.

Escrevendo o resultado

oloproof report latest --paper paper/

Isso escreve figure.svg (a estimativa e o intervalo de cada métrica), table.md e table.tex, e methods.md, um parágrafo que nomeia cada método de intervalo e sua confiança, diz que os intervalos se referem a esta suíte finita, nomeia casos ausentes e eventos raros, diz para cada juiz se pessoas o verificaram e com que frequência concordaram, e informa o que o gate decidiu. Todo número é o da execução armazenada, e o parágrafo é construído a partir de frases fixas e fatos registrados; nenhum modelo o escreve. Em um notebook:

import oloproof

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

As transcrições de um agente de auditoria

Uma ferramenta de auditoria que roda sobre o Inspect, como o Petri, escreve um log do Inspect cujo scorer dá a cada transcrição uma pontuação por dimensão, muitas vezes de 1 a 10. Importe-o com essa faixa, oloproof scores import --from inspect --scale 1 10 audit.eval, e cada dimensão vira um critério com uma média limitada e seu intervalo. Dois desses logs, antes e depois de uma mudança no alvo, são comparados nas suas transcrições em comum. As pontuações continuam sendo a palavra do juiz: as pontuações de um juiz, ao contrário do seu aprovado ou reprovado, ainda não podem ser verificadas contra pessoas.

O que não foi construído

  • Verificar as pontuações de um juiz contra as das pessoas, ao contrário dos seus vereditos de aprovado ou reprovado.
  • Tags dos metadados de uma amostra do Inspect: os casos de uma execução importada não trazem tags, então labels disagreements --by agrupa apenas execuções que o Oloproof executou.
  • Uma varredura mais estreita que Bonferroni (Dunnett ou testes fechados), contrastes entre condições em suítes diferentes, e faixas de monitor mais estreitas na cauda, vários monitores combinados ou protocolos com vários limiares.
  • Uma figura PNG: a figura é apenas SVG.

O que isto não pode dizer

Todo intervalo se refere às amostras do seu log. Ele diz o que uma execução completa e sem erros dessas amostras mostraria, não como o modelo se comporta com outros prompts, em produção, ou diante de um atacante que se adapta. Um juiz verificado por pessoas é verificado nos casos que elas rotularam e no modelo que os julgou, não em transcrições diferentes dessas. E uma taxa limitada abaixo de 1% no seu conjunto de ataques não diz nada sobre ataques que o seu conjunto não contém.