Skip to main content
Glama

create eval

create_eval

Queue an eval run that compares models pairwise, applies a calibrated criterion, or screens cheaper models on logged traffic—so you can measure a change before shipping it.

Instructions

Queue an eval run — a pairwise model comparison, an absolute criterion (calibrated judge) run, or a one-click screening of cheaper models against your own logged traffic — so a customer can measure a model, prompt, tool or index change before shipping it. POST /v1/evals (API-key scope: evals:write). SPENDS MONEY: this starts billable work on the workspace wallet. Returns: 201 with the queued run in the same shape as GET /v1/evals/{id} (status PENDING, results null, progress_ratio 0, arms[] describing each candidate key). Poll GET /v1/evals/{id} until status is DONE|ERROR|CANCELLED, or gate a pipeline directly with GET /v1/evals/{id}/gate. Notes: MONEY: a run spends wallet credit (every generation for baseline + each arm, plus judge calls; best-of-N arms pay N×). Plain runs disclose cost and are gated lazily per tick by the runner; screening runs enforce a creation-time funds gate → 402 {error:{type:"insufficient_quota", code:"insufficient_balance"}}. The key's minting user must be workspace OWNER/ADMIN → otherwise 403. 400 on: invalid JSON, schema violations (name length, rubric length, sample_count range, >6 candidates, duplicates, candidate == baseline, bad assertion, bad arm label/override), unknown model, missing criterion_id, population-binding refusal, trace_replay without stored baseline, or too little population ("Not enough logged traffic for this filter (need at least 5 distinct prompts…)"). 404 for a dataset/criterion not in this workspace. Screening-specific: 422 {code:"unprocessable"} when there is nothing to screen (no/too little logged traffic, or nothing cheaper than the incumbent — the message carries the import hint), 400 for an unusable candidate_models list, 402 for funds. All errors are {error:{message, type, code}}. Input keys are snake_case; internally converted to camelCase (candidate_models→candidateModels, candidates[]→candidateModels keys + armOverrides map keyed by label, sample_filters.dataset_id→datasetId, trace_replay→traceReplay, max_output_tokens→genMaxOutputTokens).

Input Schema

TableJSON Schema
NameRequiredDescriptionDefault
nameYesRun name, 1..80 chars after trimming (required unless screening=true, where it is auto-generated).
rubricNoJudge rubric, 10..2000 chars. Required for eval_kind="comparison" (400 if shorter than 10 chars); ignored for criterion runs (the criterion's frozen judge prompt is the rubric).
eval_kindNo"comparison" (default): each candidate arm is judged pairwise against the baseline in both orderings → win rate with Wilson CI. "criterion": every model (baseline and candidates) is graded absolutely by a saved, calibrated criterion → observed and calibration-corrected pass rates; requires criterion_id. Default: "comparison".
screeningNoScreening mode. When true every other field becomes an optional override and the server auto-fills like the dashboard's one-click: incumbent = your dominant logged model, baseline = its stored answers ("__stored__"), candidates = the cheapest model of each distinct family, judge family-checked, fixed quality rubric, sample_count = clamp(min(40, population), 5..500). Only name, sample_count, candidate_models (1..6 explicit picks, validated against the catalog: unknown id / the incumbent itself / duplicate / >6 / empty list = 400 naming the offender), judge_model, and sample_filters.dataset_id (screen an imported dataset's stored answers instead of logged traffic) are honoured in this mode; rubric, rubric_type, eval_kind, criterion_id, baseline_model, candidates[], assertions, other sample_filters and max_output_tokens are ignored. Screening additionally enforces a creation-time funds gate (402).
assertionsNoUp to 10 deterministic output checks run against every generated answer at finalize (free, exact — these are what CI should gate on via min_assertion_pass_rate). Each: {type, value?}. Types: "json_valid" (no value), "json_schema" (value = JSON Schema string ≤4000 chars, must parse), "regex_match" (value = pattern ≤200 chars, must compile), "contains" / "not_contains" (value = substring, required), "max_length" / "min_length" (value = non-negative integer as string), "completed" (finish reason was not a length cut-off), "tool_called" (value = tool name ≤200 chars; matches the canonical "[tool call] name(args)" notation), "no_tool_call". Invalid configs are rejected 400 with the specific reason.
candidatesNoVersioned arms — an alternative to candidate_models (when present, candidate_models is ignored and this list defines the arms; max 6 total). Each item: {model: string (required, catalog id that runs the arm), label?: string (arm key shown in the report; must match /^[A-Za-z0-9][A-Za-z0-9 _.:+\-]{0,63}$/ and must NOT contain "/"), system?: string (replace the logged system prompt on every sampled prompt; "" strips it; max 20000 chars; omit to keep the logged one), tools?: array of tool-definition objects (OpenAI format; replaces the logged tool definitions; [] offers none; max 64; omit to keep), n?: integer 2..8 (best-of-N: sample N times and keep the judge-preferred answer via N−1 pairwise knockout verdicts on the run's own rubric/judge; the arm pays for all N generations plus the selection verdicts)}. A bare {model} is identical to listing the id in candidate_models. Any arm that sets system, tools or n MUST carry a label (400 "candidates[]: an arm that overrides system or tools needs a label"); the label becomes the arm key in candidate_models/arms/results, and the override is stored as armOverrides[label] = {model, system?, tools?, n?}. Two arms may share one model (e.g. old prompt vs new prompt); metering follows the model that actually ran.
judge_modelNoCatalog chat model used as the judge (validated; 400 if not offered). Precedence when omitted: the workspace's default judge, then the house default judge. Ignored for criterion runs (the criterion's judge is frozen). In screening mode an explicit judge is honoured even if it shares a family with a contestant (the report discloses judge_shares_family) instead of being swapped.
rubric_typeNoHow the judge reads the rubric: "direct" (default) judges answers on the rubric alone; "adherence" also requires each sample to carry a reference answer (the logged reply), so the population must have text replies. Default: "direct".
criterion_idNoId of a workspace criterion (calibrated judge). Required when eval_kind="criterion" (400 otherwise). The criterion's judge model and prompt override judge_model/rubric and are frozen into the run (criterion_snapshot). A trace-unit criterion requires baseline_model="__stored__" and no candidates (it grades completed agent runs), and refuses if it was aligned on an older transcript instrument version. Population binding is enforced: sampling a tag/segment different from the criterion's calibrated population is refused (400); sampling with no population filter while the judge is scoped is allowed with a stored warning.
sample_countNoNumber of prompts to sample from the population, integer 5..500. Defaults to 20 when omitted (non-screening). The run is refused at creation (400) if the filtered population cannot supply at least 5 distinct prompts (with references when rubric_type="adherence" or baseline is "__stored__"). Screening: clamped to 5..500, default min(40, population). Default: 20.
baseline_modelYesThe incumbent arm: a catalog model id this workspace is offered (validated, 400 "Model '…' is not available."), or the sentinel "__stored__" to judge candidates against the incumbent's STORED logged answers (nothing is regenerated for the baseline; no savings figure is computed). "__stored__" is required for trace_replay and for the certified-switch (noninferiority) gate shape. Required unless screening=true (then forced to "__stored__").
sample_filtersNoWhich population prompts are sampled from (success-only logged requests by default). Keys: tag?: string (only requests logged with this tag); model?: string (only requests served by this model); segment?: string (an auto-detected traffic segment = the prompt FAMILY shown as `segment` on GET /v1/logs rows — one application surface's traffic, stable under interpolated dates/ids); dataset_id?: string (sample from a managed dataset — e.g. a holdout split — instead of live logs; must belong to this workspace, 404 otherwise; the run needs ≥5 usable rows); trace_replay?: boolean (replay bake-off: sample WHOLE completed agent runs from the last 7 days, one teacher-forced sample per step, max 12 steps per run; REQUIRES baseline_model="__stored__" (400 otherwise) and ≥5 replayable steps). Empty-string values are treated as absent. Screening mode reads only dataset_id here.
candidate_modelsNoArray of catalog model ids (max 6, no duplicates, none equal to baseline_model). Each candidate answers every sample and is judged, so cost is linear in this count. A comparison needs at least 1 (400 otherwise); a criterion run may have 0 (grade the baseline alone). Ignored when candidates[] is present (candidates[] replaces it).
max_output_tokensNoPer-answer generation output cap, integer 256..16384 (default 4096) — sized so thinking models can finish reasoning and answer; the runaway-spend guard. Silently ignored in screening mode. Default: 4096.
Install Server

TDQS

A4.6/5.0
Behavior5/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

The annotations are sparse (readOnlyHint false, openWorldHint true, idempotentHint false, destructiveHint false), and the description carries the behavioral burden thoroughly: it discloses that the call 'SPENDS MONEY', requires the key's minting user to be workspace OWNER/ADMIN, returns 201 with status PENDING, requires polling until DONE|ERROR|CANCELLED, and enumerates 400/403/404/402/422 error paths. No contradiction with annotations.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness4/5

Is the description appropriately sized, front-loaded, and free of redundancy?

The description is long, but it is front-loaded with the core purpose and then organized into labeled operational sections ('Returns', 'Notes', 'Screening-specific'). The density is justified by the tool's complexity, though some redundancy in the money warnings and error enumerations prevents a perfect conciseness score.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness5/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

Because there is no output schema, the description supplies the return shape (status PENDING, results null, progress_ratio 0, arms[]), the polling/gating pattern, authentication requirements, cost model, error schema, and screening-specific failure modes. This is unusually complete for a tool with 14 parameters and no structured output definition.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters4/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema coverage is 100%, so the baseline is 3, but the description adds meaningful operational semantics beyond the schema: snake_case-to-camelCase conversion, best-of-N cost multiplication, screening-mode parameter precedence, and creation-time funds gating. It does not replace the per-parameter schema descriptions, but it augments them with cross-cutting details.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

The description opens with a specific verb and resource: 'Queue an eval run', and immediately enumerates the three run modes (pairwise comparison, absolute criterion, screening). This clearly differentiates create_eval from siblings such as list_evals, get_eval, compare_evals, and create_criterion.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines4/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

It provides clear context for when to use the tool ('so a customer can measure a model, prompt, tool or index change before shipping it') and explains the mode alternatives. It does not explicitly name sibling tools or state when not to use create_eval, so it stops short of full when/when-not routing.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

Other Tools

Latest Blog Posts

MCP directory API

We provide all the information about MCP servers via our MCP API.

curl -X GET 'https://glama.ai/api/mcp/v1/servers/omnia-v/errorbar-mcp'

If you have feedback or need assistance with the MCP directory API, please join our Discord server