가이드
Node에서 평가하기
Node SDK는 여러분의 시스템과 그 평가기를 Node에서, 여러분의 테스트 러너 안에서 실행하고, 점수를 Python 엔진에 넘겨 엔진이 결정하게 합니다. TypeScript 팀은 자신의 코드, 픽스처, 테스트 러너를 그대로 유지합니다. 모든 구간, 비교, 결정은 엔진의 몫으로 남으며, SDK는 그중 어느 것도 계산하지 않습니다. 평균조차 계산하지 않습니다.
설치
npm install --save-dev @oloproof/sdk
pip install oloproof첫 번째 줄은 SDK이고, 두 번째 줄은 SDK가 점수를 넘기는 엔진입니다(Python 3.11 이상). SDK는 PATH에서 oloproof를 찾으며, 그곳에 없으면 멈추고 설치 방법을 알려 줍니다.
테스트 안에서 시스템 채점하기
스위트는 엔진이 읽는 것과 같은 JSON Lines 파일로(스위트 작성하기), 한 줄에 케이스 하나이며, 각 케이스에는 id가 있습니다. evaluate에 스위트, 시스템, 그리고 기준마다 평가기 하나를 넘기십시오.
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);평가기는 { passed } 또는 { score }를 반환하며, 선택적으로 reason을 붙일 수 있습니다. 함수는 통과 또는 실패를 판정합니다. 점수를 매기는 평가기는 자신의 scale을 선언합니다. 평균에 대한 구간은 점수를 읽기 전에 알려진 범위 안에서만 성립하기 때문입니다. 모델이 판정했다면 judge를 지정하십시오. 그러면 엔진은 그것을 심사 모델로 취급하여, 릴리스에 게이트를 걸 수 있기 전에 사람과 대조해 확인합니다(심사 모델).
concurrency는 동시에 실행되는 케이스 수의 상한입니다(기본값은 네 개). 점수 파일은 케이스가 끝나는 순서와 관계없이, 스위트가 제공하는 순서대로 케이스를 나열합니다.
엔진이 결정하게 하기
const decided = await decide({
scores: "scores/candidate.jsonl",
baseline: "scores/baseline.jsonl",
policy: "release.yaml",
});
console.log(decided.exit, decided.comparison?.gate?.decisions);decide는 여러분이 직접 입력할 명령을, cwd로 지정한 디렉터리(기본값은 현재 디렉터리)에서 실행합니다.
oloproof scores import scores/baseline.jsonl scores/candidate.jsonl --tool node
oloproof compare RUN_ID BASELINE_RUN_ID --policy release.yaml --json기준선이 있으면 엔진은 두 실행을 케이스별로 비교하며, decided.comparison은 oloproof compare --json이 출력한 레코드입니다. 기준선이 없으면 decide는 가져온 실행에 대해 oloproof gate를 실행하고, 그것이 출력한 내용을 decided.decision.stdout에 담아 반환합니다. 어느 쪽이든 decided.exitCode는 엔진의 종료 코드를 바꾸지 않은 그대로이고, decided.exit는 그 이름입니다. EXIT_CODES는 각 이름을 엔진의 값에 대응시키며, 그 목록은 CI에서 실행하기에 있습니다.
파일에 담기는 것
이 파일은 oloproof scores import가 읽는 파일입니다(두 번째 의견). 케이스와 기준의 조합마다 행 하나이며, 케이스 id와 점수만 담습니다. 답변, 입력, reason은 결코 이 파일에 들어가지 않으며, Node 안의 scored.results에 남습니다.
- 시스템이 예외를 던진 케이스는 모든 기준에 빈 값으로 기록되고, 평가기가 예외를 던진 케이스는 그 기준에 빈 값으로 기록됩니다. 엔진은 각각을 누락으로 세고 최악의 값으로 범위를 정하므로, 실패는 근거에서 사라지는 대신 근거가 보여 줄 수 있는 것을 낮춥니다. scored.errors는 각각을 그 메시지와 함께 나열합니다.
- 파일이 담을 수 없는 판정은 오류와 함께 실행을 멈추고 아무것도 쓰지 않습니다. 척도가 없거나 척도를 벗어난 점수, 점수와 통과를 모두 가진 판정, 또는 엔진이 메트릭으로 이름 붙일 수 없는 기준이 그렇습니다.
- 각 파일은 그 내용으로 식별되는 시스템 버전이므로, 같은 파일을 다시 가져오면 엔진이 저장한 것을 재사용합니다.
엔진을 설치하지 않고
secondOpinion은 아무것도 설치하지 않고 "진짜인가?"에 답하는 호스팅된 페이지로 점수 파일 두 개를 보내고, 엔진이 쓴 그대로의 답을 반환합니다.
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);이 페이지는 아무것도 보관하지 않으며 계정이 필요 없습니다. 파일당 최대 2 MB까지 읽고 클라이언트마다 제한되며, 거부되면 바꿔야 할 행을 지목하는 엔진의 문장을 반환합니다.
아직 만들어지지 않은 것
- @oloproof/sdk를 npm에 게시하기. 게시되기 전까지는 저장소의 packages/sdk에서 빌드하십시오.
- Node에서의 통계는 어떤 종류든 설계상 하지 않습니다. SDK는 점수를 쓰고 엔진의 답을 읽습니다.
- 스위트에 있는 group_id나 time_order는 가져오기로 전달되지 않습니다. 가져오기는 케이스 id와 점수만 읽으므로, 엔진은 케이스를 독립적인 것으로 읽습니다.
다음 단계
- 두 번째 의견은 파일 형식과 비교가 무엇에 답하는지 다룹니다.
- CI 게이트는 decide가 엔진에 넘기는 릴리스 정책을 다룹니다.
- Python API는 같은 평가를 엔진이 직접 실행하는 방법을 다룹니다.