Pular para o conteúdo

Guias

Do zero a um veredito sobre a sua própria aplicação

Você tem uma função Python que responde perguntas e quer saber se ela é boa o bastante para lançar. Três comandos levam você dessa função a uma decisão de release, sem YAML escrito à mão: oloproof init --system escreve o projeto em torno da sua função, oloproof check diz se vai funcionar antes de qualquer gasto, e oloproof run decide. Tudo roda na sua máquina, sem conta e sem chamadas de modelo.

Cada saída abaixo vem da execução desses comandos na função mostrada.

1. A sua função

Qualquer função que receba um caso e devolva uma resposta. Esta é bot.py, com um módulo auxiliar que ela importa:

from prompts import GREETING


def answer(question):
    text = question.lower()
    if "refund" in text:
        reply = "Refunds are available within 30 days of purchase."
    elif "ship" in text:
        reply = "We ship to the US and Canada."
    else:
        reply = "A support agent will follow up within one business day."
    return {"reply": f"{GREETING} {reply}", "topic": "support"}

2. Escreva o projeto em torno dela

A partir do diretório que contém bot.py:

oloproof init --system bot:answer
Initialized Oloproof project in . around bot:answer
  Each case's input is a string, read from the function's first parameter.

Fill in before a run means anything:
  data/cases.jsonl  3 placeholder cases: give each a real input and, as its expected
                    phrase, words a right answer contains. Add more: see below.
  oloproof.yaml     the check reads the whole answer; if your function returns an
                    object, add `field:` naming the key that holds the text.
  release.yaml      a placeholder bar of 0.80; set the one your release needs.

What this suite can decide, if every case is measured:
  mentions-floor (mentions_expected at least 0.8, 3 cases):
    1 or more pass: INSUFFICIENT_EVIDENCE (not established yet); 0: FAIL
    (ruled out). With 50 cases, PASS from 46; with 100, from 89.

Next: oloproof check, then oloproof run

A referência é importada primeiro, e nada é escrito a menos que ela leve a uma função; um erro no seu módulo para aqui, com o arquivo e a linha. A função não é chamada. Aparecem três arquivos: oloproof.yaml (a sua função e uma verificação), data/cases.jsonl (três casos provisórios) e release.yaml (o limiar). A entrada do caso é uma string porque o primeiro parâmetro se chama question; um parâmetro chamado case, inputs ou row, ou anotado como dict, recebe um objeto em vez disso.

A verificação é contains: um caso passa quando a resposta contém a frase esperada do caso. É uma verificação determinística, então não precisa ser medida contra pessoas antes de poder decidir. O guia de suítes lista todas as outras verificações e juízes.

3. Preencha os casos

Substitua os casos provisórios por perguntas reais e pelas palavras que uma resposta certa contém, um caso por linha:

{"id": "refund_01", "input": "Can I get a refund?", "expected": {"phrase": "30 days"}}
{"id": "ship_01", "input": "Do you ship to Canada?", "expected": {"phrase": "US and Canada"}}
{"id": "other_01", "input": "My order is late", "expected": {"phrase": "follow up"}}

Três casos não conseguem passar um limiar de 0,80, como diz a tabela acima: com três, a melhor resposta é INSUFFICIENT_EVIDENCE. A execução abaixo usa 30 casos como estes, dez por assunto, em que 29 aprovados bastam.

4. Verifique antes de executar

oloproof check

Antes de o campo ser definido, ele dizia:

ok   System: callable bot:answer imports.
ok   Called on case refund_01: it answered {"reply": "Thanks for writing in. Refunds are available within 30 days of purchase.", "topic": "support"}

Evaluators on that answer (one case, not a result):
ok   mentions_expected (contains) can read the answer; it passed this case.
note   It reads the whole answer object; `field:` can name one of reply, topic.

Então adicione field: reply sob a verificação em oloproof.yaml e verifique de novo:

ok   System: callable bot:answer imports.
ok   Called on case refund_01: it answered {"reply": "Thanks for writing in. Refunds are available within 30 days of purchase.", "topic": "support"}

Evaluators on that answer (one case, not a result):
ok   mentions_expected (contains) can read the answer; it passed this case.

Code: the system's version hashes bot.py, prompts.py. Edit one and the next run calls the system again.

What this suite can decide, if every case is measured:
  mentions-floor (mentions_expected at least 0.8, 30 cases):
    29 or 30 pass: PASS (established); 19 to 28: INSUFFICIENT_EVIDENCE (not
    established yet); 18 or fewer: FAIL (ruled out). With 50 cases, PASS from
    46; with 100, from 89.

CI: no model key is needed for the evaluators. Keys your own function reads are not checked here.

Ready. Next: oloproof run

O que cada parte significa:

  • Importa e responde: O sistema é montado exatamente como oloproof run o monta, e chamado no primeiro caso (--case ID escolhe outro, --no-call pula a chamada). Se ele lançar uma exceção, a linha nomeia o erro e o arquivo e a linha no seu código.
  • Avaliadores: Cada verificação que não precisa de modelo roda nessa única resposta. Um campo que ela não encontra é nomeado junto com os campos que a resposta tem. Passar ou falhar aqui é um caso, não um resultado. Um juiz de modelo nunca é chamado por check; ele diz isso, e uma execução o chama.
  • Código: Os arquivos cujo conteúdo é a versão do sistema: o módulo dele e os módulos do projeto que ele importa, mais quaisquer system.code_paths. Um arquivo do projeto carregado ao importar ou chamar o sistema que não esteja entre eles (um módulo importado pelo nome em tempo de execução, por exemplo) é listado como sem hash: adicione-o a code_paths, ou uma mudança nele reaproveita respostas desatualizadas.
  • O que pode decidir: A mesma tabela de oloproof plan. Sem um release.yaml, ele diz que uma execução responde em palavras simples e não decide nada.
  • CI: Cada modelo que o projeto chama e o segredo de que um job de CI precisa para ele, ANTHROPIC_API_KEY ou OPENAI_API_KEY, a menos que api_key_env nomeie outro, e nenhum para um servidor nesta máquina.

check não armazena nada. Ele sai com 2 quando algo precisa ser corrigido e com 0 caso contrário, e oloproof check --json imprime as mesmas constatações como um único documento.

5. Execute

oloproof run
Gate: ALLOW (exit 0)
mentions-floor:
  100.0%, range 88.4% to 100.0% (exact binomial interval); 30 of 30 cases

O relatório da execução é mais longo; estes são o veredito e a linha da regra. Todos os 30 casos passaram, e o intervalo em que a taxa é mantida começa em 88,4%, acima do limiar de 0,80, então a regra diz PASS e o gate permite o release. oloproof inspect latest o lê de novo.

Próximos passos

  • Adicione o gate aos pull requests: oloproof init --ci github escreve o workflow ao lado deste projeto (guia de CI).
  • Troque a verificação por um juiz quando uma frase não consegue dizer o que é uma resposta certa (guia de juízes); oloproof check então nomeia a chave de que o CI precisa.
  • Já tem as respostas em um arquivo em vez de uma função? oloproof eval answers.jsonl as verifica sem projeto nenhum.