Handleidingen
Evalueren vanuit Node
De Node-SDK draait je systeem en zijn evaluators in Node, binnen je eigen testrunner, en geeft de scores door aan de Python-engine, die beslist. Een TypeScript-team houdt zijn code, zijn fixtures en zijn testrunner; elk interval, elke vergelijking en elke beslissing blijft van de engine, en de SDK berekent er geen enkele van, zelfs geen gemiddelde.
Installeren
npm install --save-dev @oloproof/sdk
pip install oloproofDe eerste regel is de SDK, de tweede de engine waaraan hij de scores doorgeeft (Python 3.11 of later). De SDK vindt oloproof op je PATH; staat het daar niet, dan stopt hij en zegt hij hoe je het installeert.
Een systeem scoren in een test
Een suite is hetzelfde JSON Lines-bestand dat de engine leest (Een suite schrijven), één case per regel, elk met een id. Geef evaluate de suite, het systeem en één evaluator per criterium:
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);Een evaluator geeft { passed } of { score } terug, met een optionele reason. Een functie oordeelt geslaagd of mislukt; een evaluator die scoort declareert zijn scale, omdat een interval op een gemiddelde alleen geldt binnen een bereik dat bekend is voordat de scores worden gelezen. Noem de judge wanneer een model oordeelde: de engine behandelt hem dan als een judge die aan mensen moet worden getoetst voordat hij een release mag gaten (Judges).
concurrency begrenst hoeveel cases tegelijk draaien (standaard vier). Het scorebestand somt de cases op in de volgorde waarin de suite ze geeft, in welke volgorde ze ook klaar zijn.
Laat de engine beslissen
const decided = await decide({
scores: "scores/candidate.jsonl",
baseline: "scores/baseline.jsonl",
policy: "release.yaml",
});
console.log(decided.exit, decided.comparison?.gate?.decisions);decide draait de opdrachten die je zelf zou typen, in de map die als cwd is opgegeven (standaard de huidige):
oloproof scores import scores/baseline.jsonl scores/candidate.jsonl --tool node
oloproof compare RUN_ID BASELINE_RUN_ID --policy release.yaml --jsonMet een baseline vergelijkt de engine de twee runs case voor case, en decided.comparison is het record dat oloproof compare --json afdrukte. Zonder baseline draait decide oloproof gate op de geïmporteerde run en geeft het wat die afdrukte terug in decided.decision.stdout. Hoe dan ook is decided.exitCode de exitcode van de engine, ongewijzigd, en decided.exit de naam ervan: EXIT_CODES koppelt elke naam aan de waarde van de engine, zoals Draaien in CI ze opsomt.
Wat het bestand bevat
Het bestand is het bestand dat oloproof scores import leest (Een second opinion): één rij per case en criterium, alleen case-id's en scores. Een antwoord, een input of een reason komt er nooit in; die blijven in scored.results, in Node.
- Een case waarvan het systeem een fout gooit, wordt geschreven met een lege waarde op elk criterium, en een case waarvan de evaluator een fout gooit, met een lege waarde op dat criterium. De engine telt elk als ontbrekend en begrenst het op zijn slechtst, zodat een fout verlaagt wat het bewijs kan tonen in plaats van eruit te verdwijnen. scored.errors somt elk op met zijn melding.
- Een oordeel dat het bestand niet kan dragen, stopt de run met een fout en schrijft niets: een score zonder schaal of erbuiten, zowel een score als een geslaagd, of een criterium dat de engine niet als metriek zou kunnen benoemen.
- Elk bestand is een systeemversie die door zijn inhoud wordt geïdentificeerd, dus hetzelfde bestand opnieuw importeren hergebruikt wat de engine heeft opgeslagen.
Zonder de engine te installeren
secondOpinion stuurt twee scorebestanden naar de gehoste pagina die "is het echt?" beantwoordt zonder dat er iets geïnstalleerd is, en geeft het antwoord van de engine terug zoals die het schreef:
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);De pagina bewaart niets en heeft geen account nodig. Ze leest tot 2 MB per bestand en is per client begrensd; een weigering geeft de zin van de engine terug die de te wijzigen rij noemt.
Wat niet gebouwd is
- @oloproof/sdk publiceren op npm. Tot dat gebeurt, bouw je het vanuit packages/sdk in de repository.
- Een statistiek van welke soort ook in Node, bewust zo ontworpen: de SDK schrijft scores en leest het antwoord van de engine.
- Een group_id of time_order in je suite wordt niet meegenomen in de import, die alleen case-id's en scores leest, dus de engine leest de cases als onafhankelijk.
Verder lezen
- Een second opinion: het bestandsformaat en wat een vergelijking beantwoordt.
- CI gaten: de releasepolicy die decide aan de engine doorgeeft.
- De Python-API: dezelfde evaluatie, gedraaid door de engine zelf.