Aller au contenu

Guides

De zéro à un verdict sur votre propre application

Vous avez une fonction Python qui répond à des questions, et vous voulez savoir si elle est assez bonne pour être publiée. Trois commandes vous mènent de cette fonction à une décision de publication, sans YAML écrit à la main : oloproof init --system écrit le projet autour de votre fonction, oloproof check dit s’il fonctionnera avant que quoi que ce soit ne soit dépensé, et oloproof run décide. Tout s’exécute sur votre machine, sans compte et sans appel de modèle.

Chaque sortie ci-dessous provient de l’exécution de ces commandes sur la fonction montrée.

1. Votre fonction

N’importe quelle fonction qui prend un cas et renvoie une réponse. Celle-ci est bot.py, avec un module auxiliaire qu’elle importe :

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. Écrire le projet autour d’elle

Depuis le répertoire qui contient 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

La référence est d’abord importée, et rien n’est écrit à moins qu’elle ne se résolve en une fonction ; une erreur dans votre module s’arrête ici avec son fichier et sa ligne. La fonction n’est pas appelée. Trois fichiers apparaissent : oloproof.yaml (votre fonction et une vérification), data/cases.jsonl (trois cas provisoires) et release.yaml (la barre). L’entrée du cas est une chaîne parce que le premier paramètre s’appelle question ; un paramètre nommé case, inputs, row ou annoté comme dict reçoit plutôt un objet.

La vérification est contains : un cas passe quand la réponse contient la phrase attendue du cas. C’est une vérification déterministe, elle n’a donc pas besoin d’être mesurée face à des personnes avant de pouvoir décider. Le guide des suites énumère toutes les autres vérifications et tous les juges.

3. Remplir les cas

Remplacez les cas provisoires par de vraies questions et les mots que contient une bonne réponse, un cas par ligne :

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

Trois cas ne peuvent pas franchir une barre de 0.80, comme le dit le tableau ci-dessus : avec trois, la meilleure réponse est INSUFFICIENT_EVIDENCE. L’exécution ci-dessous utilise 30 cas comme ceux-ci, dix par sujet, où 29 réussites suffisent.

4. Vérifier avant d’exécuter

oloproof check

Avant que le champ ne soit défini, elle disait :

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.

Ajoutez donc field: reply sous la vérification dans oloproof.yaml, et vérifiez à nouveau :

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

Ce que signifie chaque partie :

  • Importe et répond: Le système est construit exactement comme oloproof run le construit, et appelé sur le premier cas (--case ID en choisit un autre, --no-call saute l’appel). S’il lève une exception, la ligne nomme l’erreur ainsi que le fichier et la ligne dans votre code.
  • Évaluateurs: Chaque vérification qui n’a pas besoin de modèle est exécutée sur cette seule réponse. Un champ introuvable est nommé avec les champs que la réponse possède. Une réussite ou un échec ici porte sur un cas, pas sur un résultat. Un juge par modèle n’est jamais appelé par check ; il le dit, et une exécution l’appelle.
  • Code: Les fichiers dont le contenu est la version du système : son module et les modules du projet qu’il importe, plus tout system.code_paths. Un fichier du projet chargé pendant l’import ou l’appel du système qui n’en fait pas partie (un module importé par son nom à l’exécution, par exemple) est indiqué comme non haché : ajoutez-le à code_paths, sinon une modification réutilise des réponses périmées.
  • Ce qu’elle peut décider: Le même tableau que oloproof plan. Sans release.yaml, elle dit qu’une exécution répond en mots simples et ne décide rien.
  • CI: Chaque modèle que le projet appelle et le secret dont un job de CI a besoin pour lui, ANTHROPIC_API_KEY ou OPENAI_API_KEY à moins que api_key_env n’en nomme un autre, et aucun pour un serveur sur cette machine.

check ne stocke rien. Elle sort avec 2 quand quelque chose doit être corrigé et 0 sinon, et oloproof check --json imprime les mêmes constats en un seul document.

5. L’exécuter

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

Le rapport de l’exécution est plus long ; voici son verdict et la ligne de la règle. Les 30 cas ont réussi, et l’intervalle auquel le taux est tenu commence à 88.4 %, au-dessus de la barre de 0.80, donc la règle dit PASS et la porte autorise la publication. oloproof inspect latest le relit.

Ensuite

  • Ajoutez la porte aux pull requests : oloproof init --ci github écrit le workflow à côté de ce projet (guide CI).
  • Remplacez la vérification par un juge quand une phrase ne peut pas dire ce qu’est une bonne réponse (guide des juges) ; oloproof check nomme alors la clé dont la CI a besoin.
  • Vous avez déjà des réponses dans un fichier plutôt qu’une fonction ? oloproof eval answers.jsonl les vérifie sans aucun projet.