SPB Git
2.5 KB · 35 lines typescript
1import { z } from "zod";2import { guarded, body, json } from "@/lib/api";3import { adapterFor, estimateCost } from "@/lib/ai";4import { requireChatModel } from "@/lib/ai/registry";5import { recordUsage } from "@/lib/usage";6import { sql } from "@/lib/db";78export const maxDuration = 300;910/** AI-assisted comparison — explicitly a model-generated opinion, not ground truth. */11export const POST = guarded(async (req) => {12  const b = await body(req, z.object({ id: z.string(), judgeModel: z.string() }));13  const rows = await sql<{ prompt: string; results: { modelId: string; text: string; error: string | null }[] }[]>`SELECT prompt, results FROM comparisons WHERE id = ${b.id}`;14  if (!rows[0]) return json({ error: "Introuvable" }, { status: 404 });15  const judge = await requireChatModel(b.judgeModel);16  const answers = rows[0].results.filter(r => !r.error && r.text);17  const labels = answers.map((_, i) => String.fromCharCode(65 + i));18  const prompt = `You are evaluating ${answers.length} anonymous answers to the same prompt. Judge accuracy, completeness, clarity and adherence to the request. Be specific and cite short excerpts. Then output a final line exactly: RANKING: ${labels.join(" > ")} (ordered best to worst) and a line SCORES: ${labels.map(l => `${l}=<0-10>`).join(", ")}.1920PROMPT:21${rows[0].prompt.slice(0, 6000)}2223${answers.map((a, i) => `=== ANSWER ${labels[i]} ===\n${a.text.slice(0, 12_000)}`).join("\n\n")}`;24  let text = ""; let usage = { input: 0, output: 0 }; const t0 = Date.now();25  for await (const ev of adapterFor(judge.provider).stream({ model: judge, messages: [{ role: "user", parts: [{ type: "text", text: prompt }] }], settings: { maxOutputTokens: 4000, reasoningSummary: false }, loadAttachment: async () => null })) {26    if (ev.type === "text") text += ev.delta; else if (ev.type === "usage") usage = ev.usage; else if (ev.type === "error") return json({ error: ev.message }, { status: 502 });27  }28  const cost = estimateCost(judge, usage);29  await recordUsage({ provider: judge.provider, modelId: judge.id, kind: "judge", usage, costEstimated: cost, latencyMs: Date.now() - t0, meta: { comparisonId: b.id } });30  const mapping = Object.fromEntries(labels.map((l, i) => [l, answers[i].modelId]));31  const result = { judgeModel: judge.id, text, mapping, costUsd: cost, disclaimer: "Évaluation générée par un modèle : une opinion, pas une vérité objective.", at: new Date().toISOString() };32  await sql`UPDATE comparisons SET judge = ${sql.json(result as never)} WHERE id = ${b.id}`;33  return json({ judge: result });34});35
Files · main
Menu

Theme