O que agentic-evals faz?
Use esta habilidade quando um teste de fumaça único for muito fraco e a tarefa precisar de uma avaliação repetível e baseada em evidências de uma habilidade ou fluxo de trabalho de agente.
Escopo Atual
Este pacote inicial fornece um executor de fixture determinístico para casos baseados em comando. Ele executa cada caso várias vezes, registra stdout/stderr/status de saída e duração, verifica expectativas explícitas e emite um resumo de prontidão legível por máquina.
Isso prova apenas o comportamento da fixture declarada. Não prova correção semântica, integração real de serviço, qualidade de LLM-juiz ou prontidão para lançamento, a menos que os próprios comandos da fixture exercitem esses caminhos ativos.
Uso
./run.sh run fixtures/agentic_eval.json
./run.sh run fixtures/agentic_eval.json --output /tmp/agentic-evals-report.json
./run.sh audit-skills ../ --output /tmp/agentic-evals-baseline-gap-report.json
./run.sh scaffold-fixture ../some-skill --output ../some-skill/fixtures/agentic_eval.json
./run.sh apply-scaffolds ../ --write --output /tmp/agentic-evals-apply-scaffolds.json
# planejamento de requisitos-para-jornada sobre descoberta ativa (issue #1629)
./run.sh plan-journeys --fixture fixtures/agentic_eval.json \
--requirements requirements.json \
--interaction-inventory discovery/discovery-inventory.json \
--state-graph discovery/state-graph.json \
--output journey-plan.json [--scaffold-output fragment.json] [--report-only]
# reivindicação / evidência / regressão / cobertura (issues #1445-#1448)
./run.sh regressions audit ../ --output /tmp/agentic-evals-regressions.json
./run.sh regressions show . && ./run.sh regressions verify .
./run.sh coverage audit ../ --output /tmp/agentic-evals-coverage.json
./run.sh coverage show .
Prontidão Baseada em Reivindicação (#1445)
Testes determinísticos provam mecanismos; E2Es reais provam capacidades. Uma pilha de casos determinísticos aprovados nunca deve se parecer com prontidão para uma capacidade ativa que nunca foi exercitada. A prontidão é, portanto, calculada por reivindicação de capacidade declarada, depois agregada — não a partir de uma contagem de casos.
Declare capability_claims (mantidas separadas da prosa de escopo de prova claims
para que fixtures v2 permaneçam válidas). Cada caso que suporta uma reivindicação se auto-etiqueta:
{
"capability_claims": [
{"id": "ask.roundtable.mixed_provider", "description": "...",
"criticality": "critical",
"evidence_required": {"deterministic": true, "live_e2e": true}}
],
"cases": [
{"name": "roundtable-live", "type": "positive", "evidence_class": "live_e2e",
"supports_claims": ["ask.roundtable.mixed_provider"],
"command": ["bash", "run.sh", "..."],
"expected": {"exit_code": 0, "artifacts": [{"path": "out/join.json", "json_pointer": "/settled", "equals": true}]}}
]
}
Classes de evidência: deterministic, property_or_fuzz,
fault_injected_deterministic, live_e2e, adversarial_live_e2e,
human_evaluation. Verdictos por reivindicação: PROVEN, PARTIALLY_PROVEN,
BLOCKED_EXTERNAL, FAILED, NOT_ESTABLISHED. Uma habilidade está READY apenas quando
toda reivindicação crítica obrigatória está PROVEN sob seus próprios requisitos de
evidência. Quando reivindicações são declaradas, a comporta de run é o pior da
prontidão baseada em caso e baseada em reivindicação, então vinte casos determinísticos verdes com
um slot live_e2e obrigatório não atendido não podem alcançar READY. Um caso ativo suportando
mais de uma reivindicação deve carregar artefatos independentes por reivindicação, caso contrário, não conta
para nenhuma delas. report["capability_readiness"] contém o detalhamento por reivindicação.
Reivindicações Derivadas de Invariantes (nunca faça stub de uma resposta) — operador 2026-09-11
O oai-trial foi perdido por uma omissão: o requisito "nenhum PII atinge a saída" foi silenciosamente restrito a "nenhuma string de PII atinge a saída." Cada avaliação, verificador e execução de qualificação provou a reivindicação restrita como verde enquanto números de telefone do tipo inteiro passavam despercebidos. O cliente leu o invariante no escopo do domínio; nós o provamos no escopo do mecanismo. REGRAS:
- Reivindicações são derivadas do invariante do domínio, não do que o código já
faz. Antes de declarar
capability_claims, escreva o invariante nas palavras do cliente ("nenhum X atinge a saída em QUALQUER representação"), então declare isso — literalmente — como a reivindicação crítica. Uma reivindicação que descreve o comportamento atual é um stub. - Matriz de representação é obrigatória para reivindicações que carregam valor. Qualquer reivindicação sobre valores de dados (PII, dinheiro, identificadores, segredos) deve enumerar as representações que o formato de entrada admite — JSON string/int/float/notação científica, citação CSV, tipos SQL — e carregar pelo menos um caso adversarial por representação, cada um capaz de falhar. Uma reivindicação de valor sem uma matriz de representação não pode ser PROVEN.
- Uma costura de cobertura chamada
value-representation(criticalidade: critical) é obrigatória para qualquer pipeline que transforme, filtre ou redacione valores de dados. A auditoria deve mostrar uma proteção capaz nessa costura. - Verificadores independentes não devem compartilhar o gerador de dados do produtor. As fixtures do verificador devem incluir representações que as próprias fixtures da transformação não incluem, ou a independência é nominal.
- Quando uma lacuna de representação é enviada, registre-a em
fixtures/regressions.json(incidente → proteção retida) e na costuravalue-representation— a mesma classe de omissão deve ser detectável para sempre.
O contrato anti-slop rejeita encanamento auto-serventuário; estas regras rejeitam suposições auto-serventuárias — a suíte que é honesta, adversarial, multi-tentativa e ainda assim cega porque cada fixture compartilha uma pré-condição invisível sobre a forma dos dados.
Contrato de Evidência Real de Ponta a Ponta (#1446)
evidence_class não é inferida de um comando contendo run.sh ou curl.
Um caso que declara uma classe ativa (live_e2e/adversarial_live_e2e) é
qualificado estruturalmente e rebaixado (nunca aceito silenciosamente) se ele:
- alimenta a si mesmo com entradas de
fixtures//stub/mockedcomo autoridade de limite; - não atinge um ponto de entrada de produção substancial;
- não tem oráculo de leitura independente (
expected.artifacts,readback: true, oustdout_excludes) — um código de saída mais a própria prosa de sucesso do comando não é prova; ou - reivindica evidência ativa para manipuladores
$askdo navegadortau-dag/competesem--executee leitura de artefatos de execução do navegador/provedor, comonode-receipt.json,response.md,response.meta.json,browser-tab-lifecycle.json,execution-status.json,roundtable-summary.mdoucompete-scorecard.json. Casos$askapenas de compilação/pré-voo são evidência de mecanismo determinístico, nuncalive_e2e.
Um caso rebaixado torna-se fault_injected_deterministic (falha em um caminho real)
ou deterministic, e o relatório registra evidence_disqualifiers. Um slot
ativo obrigatório atendido apenas por um caso BLOCKED_EXTERNAL deixa a reivindicação não-PROVEN.
Isenções são explícitas e expiradas. Uma reivindicação pode carregar exemptions nomeando
evidence_class, reason_code, justification, owner e expires. Uma
isenção válida é exibida no relatório (exempt_evidence) mas nunca torna uma reivindicação
PROVEN; uma isenção expirada ou incompleta é ignorada. Nenhum
eval_not_required genérico satisfaz uma capacidade operacional executável.
Incidente → Regressão Retida (#1447)
Uma falha ativa torna-se evidência permanente em fixtures/regressions.json
(agentic_evals.regressions.v1). Cada registro vincula o incidente às reivindicações
e costuras que ameaçou, nomeia o caso de proteção retido (retained_case /
retained_fixture) e carrega um fail_before_fix.proof_command.
regressions show <skill>/regressions audit <root>relatam: regressões não protegidas (caso retido ausente/renomeado), regressões nunca provadas (possivelmente vazias), prova ativa desatualizada, regressões aposentadas e incidentes abertos sem mapeamento de regressão.regressions verify <skill>reexecuta cada comando de prova e confirma que a proteção realmente falha contra o comportamento quebrado (sai com código não zero) — uma prova de não-vacuidade, não uma flag auto-relatada. Sai com código não zero se qualquer regressão ativa da proteção não puder demonstrar falha-antes-da-correção.
Corrigir um bug editando a expectativa da avaliação para corresponder à saída quebrada é exatamente
o que a prova de não-vacuidade captura. Aposentar uma regressão requer um
motivo de retirement.
Suficiência de Cobertura Baseada em Risco (#1448)
Contar casos é sujeito a manipulação. coverage audit/coverage show perguntam, por seam
declarada: existe pelo menos um caso capaz de detectar uma regressão naquela
costura, em cada classe de evidência que o risco da costura exige? Declare seams com
seam_id, seam_type, criticality e required_evidence; marque casos com
seams. Um caso cobre uma costura apenas quando lista essa costura e carrega um
oráculo que pode falhar — um exit 0 positivo simples é weak_only e não
conta. A auditoria reporta costuras cobertas/não cobertas, cobertura apenas fraca, cobertura ativa vs
determinística, regressões de incidentes mapeadas e próximas avaliações priorizadas.
Cobertura (uma proteção capaz é declarada) e atualidade (uma prova ativa é
corrente) são dimensões separadas; o executor não executa os casos da costura aqui.
Contrato de Fixture
{
"version": 2,
"skill": "example-skill",
"trials": 3,
"proof_scope": "fumaça de fiação de fixture",
"claims": {
"proves": "o comando declarado sai com o status esperado",
"does_not_prove": "correção semântica, comportamento de serviço ativo ou prontidão total da habilidade"
},
"cases": [
{
"name": "caminho-feliz",
"type": "positive",
"command": ["echo", "sucesso"],
"expected": {
"exit_code": 0,
"stdout_contains": ["sucesso"]
}
}
]
}
Cada caso deve declarar:
nametype:positive,negativeouadversarialcommand: uma lista argv não vaziaexpected.exit_code
Expectativas opcionais:
expected.stdout_containsexpected.stderr_containsmust_exercise: lista de substrings de comando de contrato downstream que devem aparecer no comando de nível superior do caso. Use isso quando um wrapper poderia, de outra forma, falsificar o sucesso; por exemplo, uma avaliação que reivindica roteabilidade$ticket/$project-watchdogdeve incluir"skills/ticket/run.sh feature", não apenas um script auxiliar que imprimeOK.
Contrato Anti-Slop (falha-fechada)
Uma fixture de avaliação de habilidade é REJEITADA no momento do carregamento (saída não zero, sem execução) se ela for um encanamento determinístico auto-serventuário em vez de prova do mundo real. Para passar, uma fixture de habilidade DEVE:
- definir
trials>= 2 (uma única tentativa não é evidência); - incluir pelo menos um caso
negativeouadversarial(uma fixture totalmente positiva é auto-serventuária); - incluir pelo menos um caso do mundo real:
"real_world": truecujo comando exercite um caminho ativo (orun.shda habilidade / um script / HTTP ativo / um executor de teste) e NÃO alimente a si mesmo com entradas stub defixtures/; - não conter casos triviais de
echo/constantes que não provam nada.
A mensagem de rejeição nomeia cada violação. Isso impede uma avaliação que passa trivialmente enquanto não prova nada sobre se a habilidade realmente funciona.
Nível de conformidade ("eval_tier": "compliance")
Uma fixture que protege um estágio de pipeline de conformidade declara
"eval_tier": "compliance" e o executor então EXIGE o contrato forte sobre
a linha de base (diretiva do operador 2026-08-12, "este é um pipeline de conformidade
e deve ser robustamente endurecido"). Tal fixture é REJEITADA a menos que:
- uma maioria estrita dos casos seja
adversarial/negative(mais da metade, não exatamente metade — controles positivos são a minoria); - pelo menos um caso seja não-determinístico: seu comando amostra entradas novas
a cada execução via
--samples,--seedou um$RANDOMdo shell (um nome de script de sonda com uma chave fixa não conta); - cada caso não-determinístico nomeie
--samples>= 50, para que a cobertura de cada estágio seja centenas a milhares de asserções por execução, visando ~1000 por estágio em seus modos.
A declaração não pode ser silenciosamente relaxada: as próprias fixtures do pipeline de conformidade
definem o nível, então removê-lo para evitar a comporta é em si uma regressão.
tests/test_compliance_tier_gate.py fixa cada regra contra seu enfraquecimento.
Duas isenções declaradas honestamente ignoram a comporta — nunca válidas para uma avaliação de habilidade real:
"eval_kind": "runner_selftest"— uma fixture que testa este próprio executor ou é um exemplo de documentação."eval_kind": "scaffold"— a fixture mecânica de primeira postura emitida porscaffold-fixture/apply-scaffolds, que a auditoria ainda sinaliza como precisando de casos reais.
Mapeamento de Prontidão
A prontidão é pontuada apenas sobre casos obrigatórios ("required": false opta por um caso
fora). Um caso BLOCKED obrigatório não pode alcançar READY: uma pré-condição não atendida é
ausência de evidência, não evidência de sucesso.
READY: todo caso obrigatório passou em todas as tentativas.USABLE_WITH_GAPS: pelo menos uma tentativa passou e pelo menos uma não passou.NOT_READY: tentativas executadas, mas nenhum caso obrigatório passou completamente.NOT_ESTABLISHED: nenhum caso foi executado.
Saída com falha-fechada
run sai com código não zero a menos que a prontidão seja READY. Um executor que sai 0 em
USABLE_WITH_GAPS permite que um trabalho de CI externo fique verde sobre casos falhos, o que é
exatamente a falha que esta comporta existe para prevenir. Passe --report-only quando quiser o
relatório sem a comporta.
Resultados de Casos
Cada caso relata um outcome, porque esses significam coisas diferentes para uma comporta:
| Resultado | Significado |
|---|---|
PASS | toda tentativa atendeu a toda expectativa |
FAIL | um defeito, ou um timeout, ou uma tentativa que deixou um processo filho para trás |
BLOCKED | uma pré-condição não foi atendida; declare marcadores via blocked_when_stdout_contains |
NOT_TESTED | nenhuma tentativa foi executada |
Asserções de Artefato
A correspondência de substring de stdout não pode expressar "esses dois recibos nomeiam a mesma
sessão" ou "a execução não deixou nada para trás". Declare expected.artifacts:
"expected": {
"exit_code": 0,
"artifacts": [
{"path": "out/session.json", "json_pointer": "/sessionId",
"equals_artifact": {"path": "out/detach.json", "json_pointer": "/sessionId"}},
{"path": "out/attach.json", "json_pointer": "/sessionId",
"exists": true}
]
}
Operadores de asserção de artefato suportados:
json_pointer+equals: verifica se o valor no ponteiro JSON é exatamente o valor fornecido.json_pointer+equals_artifact: verifica se os valores em dois caminhos de artefato são iguais.json_pointer+exists: verifica se a chave existe (qualquer valor).json_pointer+matches_regex: verifica se o valor corresponde a uma expressão regular.path: caminho relativo ao diretório de trabalho da execução do caso.readback: quandotrue, o runner relê o artefato após a execução do comando para verificar consistência.
Variáveis de Ambiente
O runner respeita as seguintes variáveis de ambiente:
AGENTIC_EVALS_TRIALS: substitui o número de tentativas por caso.AGENTIC_EVALS_OUTPUT: caminho para o arquivo de relatório de saída.AGENTIC_EVALS_VERBOSE: quando definida, ativa a saída detalhada.AGENTIC_EVALS_NO_GATE: quando definida, desativa a verificação de prontidão (comporta).AGENTIC_EVALS_FAIL_FAST: quando definida, interrompe a execução no primeiro casoFAIL.
Arquitetura
O runner opera em três fases:
- Carregamento e Validação: A fixture é carregada de um arquivo JSON e validada contra o contrato de fixture, incluindo verificações anti-slop.
- Execução: Cada caso é executado pelo número declarado de
trials, com cada tentativa registrando stdout, stderr, status de saída e duração. - Relatório e Portão: Os resultados são agregados em um relatório, a prontidão é calculada com base em reivindicações e casos, e o portão de saída (código não zero a menos que
READY) é aplicado a menos que--report-onlyseja passado.
Tratamento de Erros
- Fixture inválida: Sai imediatamente com código 1 e uma mensagem de erro nomeando cada violação do contrato.
- Tentativa com timeout: Marcada como
FAILno relatório. - Processo filho órfão: Se uma tentativa deixar um processo filho em execução após o timeout, a tentativa é marcada como
FAIL. - Artefato ausente: Se um artefato esperado não existir, a asserção falha como
FAIL. - JSON inválido: Se um arquivo de artefato JSON não puder ser analisado, a asserção falha como
FAIL.
Casos de Uso
- Avaliação de Habilidade Pós-Desenvolvimento: Execute
./run.sh run fixtures/seu_skill_eval.jsonpara verificar se uma habilidade atende aos critérios básicos de prontidão após a implementação. - Auditoria de Regressão: Use
./run.sh regressions audit ../para verificar se as regressões retidas ainda são válidas e detectáveis. - Auditoria de Cobertura: Use
./run.sh coverage audit ../para identificar costuras não cobertas na sua habilidade. - Fixture de Conformidade: Defina
"eval_tier": "compliance"para pipelines que exigem o contrato forte de avaliação (casos adversariais majoritários, casos não-determinísticos,--samples >= 50).