Guias
Avaliando a partir do Node
O SDK para Node executa o seu sistema e os seus avaliadores em Node, dentro do seu próprio executor de testes, e entrega as pontuações ao engine Python, que decide. Uma equipe TypeScript mantém o seu código, as suas fixtures e o seu executor de testes; cada intervalo, comparação e decisão continua sendo do engine, e o SDK não calcula nenhum deles, nem mesmo uma média.
Instalar
npm install --save-dev @oloproof/sdk
pip install oloproofA primeira linha é o SDK, a segunda o engine ao qual ele entrega as pontuações (Python 3.11 ou posterior). O SDK encontra oloproof no seu PATH; se ele não estiver lá, o SDK para e diz como instalá-lo.
Pontuar um sistema em um teste
Uma suíte é o mesmo arquivo JSON Lines que o engine lê (Escrevendo uma suíte), um caso por linha, cada um com um id. Passe para evaluate a suíte, o sistema e um avaliador por critério:
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);Um avaliador retorna { passed } ou { score }, com um reason opcional. Uma função julga aprovado ou reprovado; um avaliador que pontua declara a sua scale, porque um intervalo sobre uma média só vale dentro de uma faixa conhecida antes de as pontuações serem lidas. Indique o judge quando um modelo julgou: o engine então o trata como um juiz a ser verificado contra pessoas antes de poder aplicar um gate a um lançamento (Juízes).
concurrency limita quantos casos são executados ao mesmo tempo (quatro por padrão). O arquivo de pontuações lista os casos na ordem em que a suíte os fornece, seja qual for a ordem em que terminem.
Deixe o engine decidir
const decided = await decide({
scores: "scores/candidate.jsonl",
baseline: "scores/baseline.jsonl",
policy: "release.yaml",
});
console.log(decided.exit, decided.comparison?.gate?.decisions);decide executa os comandos que você digitaria, no diretório indicado como cwd (o atual, por padrão):
oloproof scores import scores/baseline.jsonl scores/candidate.jsonl --tool node
oloproof compare RUN_ID BASELINE_RUN_ID --policy release.yaml --jsonCom uma linha de base, o engine compara as duas execuções caso a caso e decided.comparison é o registro que oloproof compare --json imprimiu. Sem uma, decide executa oloproof gate na execução importada e retorna o que ele imprimiu em decided.decision.stdout. De qualquer forma, decided.exitCode é o código de saída do engine, inalterado, e decided.exit o seu nome: EXIT_CODES mapeia cada nome para o valor do engine, tal como Executando no CI os lista.
O que o arquivo contém
O arquivo é aquele que oloproof scores import lê (Uma segunda opinião): uma linha por caso e critério, apenas ids de casos e pontuações. Uma resposta, uma entrada ou um reason nunca entra nele; eles ficam em scored.results, no Node.
- Um caso cujo sistema lança uma exceção é escrito com um valor vazio em cada critério, e um caso cujo avaliador lança uma exceção, com um valor vazio nesse critério. O engine conta cada um como ausente e o limita no seu pior valor, de modo que uma falha reduz o que a evidência pode mostrar em vez de desaparecer dela. scored.errors lista cada um com a sua mensagem.
- Um veredito que o arquivo não pode conter interrompe a execução com um erro e não escreve nada: uma pontuação sem escala ou fora dela, uma pontuação e um aprovado ao mesmo tempo, ou um critério que o engine não conseguiu nomear como métrica.
- Cada arquivo é uma versão do sistema identificada pelo seu conteúdo, então importar o mesmo arquivo de novo reutiliza o que o engine armazenou.
Sem instalar o engine
secondOpinion envia dois arquivos de pontuações para a página hospedada que responde "isso é real?" sem nada instalado, e retorna a resposta do engine tal como ele a escreveu:
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);A página não guarda nada e não exige conta. Ela lê até 2 MB por arquivo e é limitada por cliente; uma recusa retorna a frase do engine que indica a linha a alterar.
O que não foi construído
- Publicar @oloproof/sdk no npm. Até que isso aconteça, compile-o a partir de packages/sdk no repositório.
- Uma estatística de qualquer tipo em Node, por design: o SDK escreve pontuações e lê a resposta do engine.
- Um group_id ou time_order na sua suíte não é levado para a importação, que lê apenas ids de casos e pontuações, então o engine lê os casos como independentes.
Próximos passos
- Uma segunda opinião: o formato do arquivo e o que uma comparação responde.
- Gate no CI: a política de lançamento que decide passa para o engine.
- A API Python: a mesma avaliação, executada pelo próprio engine.