Vai al contenuto

Guide

Da zero a un verdetto sulla tua app

Hai una funzione Python che risponde a domande e vuoi sapere se è abbastanza buona da rilasciare. Tre comandi ti portano da quella funzione a una decisione di rilascio, senza YAML scritto a mano: oloproof init --system scrive il progetto attorno alla tua funzione, oloproof check dice se funzionerà prima di spendere qualsiasi cosa, e oloproof run decide. Tutto gira sulla tua macchina, senza account e senza chiamate a modelli.

Ogni output qui sotto viene dall'esecuzione di questi comandi sulla funzione mostrata.

1. La tua funzione

Qualsiasi funzione che prende un caso e restituisce una risposta. Questa è bot.py, con un modulo di supporto che 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. Scrivi il progetto attorno a essa

Dalla directory che contiene 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

Il riferimento viene importato per primo, e nulla viene scritto se non si risolve in una funzione; un errore nel tuo modulo si ferma qui, con il suo file e la sua riga. La funzione non viene chiamata. Compaiono tre file: oloproof.yaml (la tua funzione e un controllo), data/cases.jsonl (tre casi segnaposto) e release.yaml (la soglia). L'input del caso è una stringa perché il primo parametro si chiama question; un parametro chiamato case, inputs, row o annotato come dict riceve invece un oggetto.

Il controllo è contains: un caso passa quando la risposta contiene la frase attesa del caso. È un controllo deterministico, quindi non deve essere misurato rispetto a delle persone prima di poter decidere. La guida alle suite elenca ogni altro controllo e giudice.

3. Compila i casi

Sostituisci i segnaposto con domande reali e le parole che una risposta corretta contiene, un caso per riga:

{"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"}}

Tre casi non possono superare una soglia di 0,80, come dice la tabella sopra: con tre, la risposta migliore è INSUFFICIENT_EVIDENCE. L'esecuzione qui sotto usa 30 casi come questi, dieci per argomento, dove 29 superati bastano.

4. Controlla prima di eseguire

oloproof check

Prima che il campo fosse impostato, diceva:

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.

Quindi aggiungi field: reply sotto il controllo in oloproof.yaml, e controlla di nuovo:

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

Che cosa significa ogni parte:

  • Importazione e risposte: Il sistema viene costruito esattamente come lo costruisce oloproof run, e chiamato sul primo caso (--case ID ne sceglie un altro, --no-call salta la chiamata). Se solleva un'eccezione, la riga indica l'errore e il file e la riga nel tuo codice.
  • Valutatori: Ogni controllo che non richiede un modello viene eseguito su quell'unica risposta. Un campo che non riesce a trovare viene indicato insieme ai campi che la risposta ha. Un superamento o un fallimento qui è un caso, non un risultato. Un giudice basato su modello non viene mai chiamato da check; lo dice, ed è un'esecuzione a chiamarlo.
  • Codice: I file il cui contenuto è la versione del sistema: il suo modulo e i moduli del progetto che importa, più eventuali system.code_paths. Un file del progetto caricato durante l'importazione o la chiamata del sistema che non è tra questi (per esempio un modulo importato per nome durante l'esecuzione) viene elencato come non sottoposto a hash: aggiungilo a code_paths, altrimenti una sua modifica riutilizza risposte obsolete.
  • Che cosa può decidere: La stessa tabella di oloproof plan. Senza un release.yaml, dice che un'esecuzione risponde in parole semplici e non decide nulla.
  • CI: Ogni modello che il progetto chiama e il segreto che un job di CI richiede per esso, ANTHROPIC_API_KEY o OPENAI_API_KEY a meno che api_key_env ne indichi un altro, e nessuno per un server su questa macchina.

check non salva nulla. Esce con 2 quando qualcosa va corretto e con 0 altrimenti, e oloproof check --json stampa gli stessi risultati come un unico documento.

5. Eseguilo

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

Il report dell'esecuzione è più lungo; queste sono il suo verdetto e la riga della regola. Tutti i 30 casi sono stati superati, e l'intervallo entro cui è tenuto il tasso parte da 88,4%, sopra la soglia di 0,80, quindi la regola dice PASS e il gate consente il rilascio. oloproof inspect latest lo rilegge.

Prossimi passi

  • Aggiungi il gate alle pull request: oloproof init --ci github scrive il workflow accanto a questo progetto (guida alla CI).
  • Sostituisci il controllo con un giudice quando una frase non riesce a dire che cos'è una risposta corretta (guida ai giudici); oloproof check indica poi la chiave di cui la CI ha bisogno.
  • Hai già le risposte in un file invece che in una funzione? oloproof eval answers.jsonl le controlla senza alcun progetto.