Zum Inhalt springen

Anleitungen

Aus Node evaluieren

Das Node-SDK führt Ihr System und seine Evaluatoren in Node aus, innerhalb Ihres eigenen Test-Runners, und übergibt die Scores an die Python-Engine, die entscheidet. Ein TypeScript-Team behält seinen Code, seine Fixtures und seinen Test-Runner; jedes Intervall, jeder Vergleich und jede Entscheidung bleibt Sache der Engine, und das SDK berechnet nichts davon, nicht einmal einen Durchschnitt.

Installation

npm install --save-dev @oloproof/sdk
pip install oloproof

Die erste Zeile ist das SDK, die zweite die Engine, an die es die Scores übergibt (Python 3.11 oder neuer). Das SDK findet oloproof in Ihrem PATH; ist es dort nicht vorhanden, hält es an und sagt, wie man es installiert.

Ein System in einem Test bewerten

Eine Suite ist dieselbe JSON-Lines-Datei, die die Engine liest (Eine Suite schreiben), ein Fall pro Zeile, jeder mit einer id. Übergeben Sie evaluate die Suite, das System und einen Evaluator pro Kriterium:

import { test } from "vitest";
import { type Case, decide, evaluate } from "@oloproof/sdk";
import { answer, rateHelpfulness } from "./support-bot.js";

type SupportCase = Case<{ question: string }, { label: string }>;
type Answer = { label: string; text: string };

test("the support bot is good enough to release", async () => {
  const scored = await evaluate<SupportCase, Answer>({
    suitePath: "data/support.jsonl",
    system: (testCase) => answer(testCase.input.question),
    evaluators: {
      exact_label: (output, testCase) => ({ passed: output.label === testCase.expected?.label }),
      helpfulness: {
        scale: [0, 1],
        judge: "gpt-4o-mini",
        evaluate: async (output, testCase) => ({ score: await rateHelpfulness(output, testCase) }),
      },
    },
    concurrency: 8,
    out: "scores/candidate.jsonl",
  });
  console.log(scored.counts);
}, 600_000);

Ein Evaluator gibt { passed } oder { score } zurück, mit einem optionalen reason. Eine Funktion urteilt über Bestanden oder Nicht-bestanden; ein Evaluator, der Scores vergibt, deklariert seine scale, denn ein Intervall um einen Mittelwert gilt nur innerhalb eines Bereichs, der bekannt ist, bevor die Scores gelesen werden. Nennen Sie den judge, wenn ein Modell geurteilt hat: Die Engine behandelt ihn dann als Judge, der an Menschen zu prüfen ist, bevor er als Gate über ein Release entscheiden darf (Judges).

concurrency begrenzt, wie viele Fälle gleichzeitig laufen (standardmäßig vier). Die Score-Datei listet die Fälle in der Reihenfolge, in der die Suite sie angibt, unabhängig davon, in welcher Reihenfolge sie fertig werden.

Die Engine entscheiden lassen

const decided = await decide({
  scores: "scores/candidate.jsonl",
  baseline: "scores/baseline.jsonl",
  policy: "release.yaml",
});
console.log(decided.exit, decided.comparison?.gate?.decisions);

decide führt die Befehle aus, die Sie eingeben würden, in dem als cwd angegebenen Verzeichnis (standardmäßig dem aktuellen):

oloproof scores import scores/baseline.jsonl scores/candidate.jsonl --tool node
oloproof compare RUN_ID BASELINE_RUN_ID --policy release.yaml --json

Mit einer Baseline vergleicht die Engine die beiden Läufe Fall für Fall, und decided.comparison ist der Datensatz, den oloproof compare --json ausgegeben hat. Ohne Baseline führt decide oloproof gate auf dem importierten Lauf aus und gibt in decided.decision.stdout zurück, was dieser Befehl ausgegeben hat. In beiden Fällen ist decided.exitCode der Exit-Code der Engine, unverändert, und decided.exit sein Name: EXIT_CODES ordnet jedem Namen den Wert der Engine zu, wie In CI ausführen sie auflistet.

Was die Datei enthält

Die Datei ist die, die oloproof scores import liest (Eine zweite Meinung): eine Zeile pro Fall und Kriterium, nur Fall-IDs und Scores. Eine Antwort, eine Eingabe oder ein reason gelangt nie hinein; sie bleiben in scored.results, in Node.

  • Ein Fall, dessen System eine Ausnahme wirft, wird mit einem leeren Wert in jedem Kriterium geschrieben, und ein Fall, dessen Evaluator eine Ausnahme wirft, mit einem leeren Wert in diesem Kriterium. Die Engine zählt jeden als fehlend und begrenzt ihn auf seinen ungünstigsten Wert, sodass ein Fehler verringert, was die Evidenz zeigen kann, statt aus ihr zu verschwinden. scored.errors listet jeden mit seiner Meldung auf.
  • Ein Urteil, das die Datei nicht tragen kann, stoppt den Lauf mit einem Fehler und schreibt nichts: ein Score ohne Skala oder außerhalb davon, sowohl ein Score als auch ein Bestanden, oder ein Kriterium, das die Engine nicht als Metrik benennen konnte.
  • Jede Datei ist eine Systemversion, die durch ihren Inhalt identifiziert wird, daher verwendet ein erneuter Import derselben Datei wieder, was die Engine gespeichert hat.

Ohne die Engine zu installieren

secondOpinion sendet zwei Score-Dateien an die gehostete Seite, die „Ist es echt?“ beantwortet, ohne dass etwas installiert ist, und gibt die Antwort der Engine so zurück, wie sie sie geschrieben hat:

import { secondOpinion } from "@oloproof/sdk";

const result = await secondOpinion({
  baseUrl: "https://oloproof.com",
  baseline: "scores/baseline.jsonl",
  candidate: "scores/candidate.jsonl",
});
if (result.ok) console.log(result.opinion.answers);
else console.log(result.error, result.description);

Die Seite bewahrt nichts auf und braucht kein Konto. Sie liest bis zu 2 MB pro Datei und ist pro Client begrenzt; eine Ablehnung gibt den Satz der Engine zurück, der die zu ändernde Zeile nennt.

Was nicht gebaut ist

  • @oloproof/sdk auf npm veröffentlichen. Bis dahin bauen Sie es aus packages/sdk im Repository.
  • Eine Statistik irgendeiner Art in Node, mit Absicht: Das SDK schreibt Scores und liest die Antwort der Engine.
  • Eine group_id oder time_order in Ihrer Suite wird nicht in den Import übernommen, der nur Fall-IDs und Scores liest, daher liest die Engine die Fälle als unabhängig.

Wie es weitergeht