- One editor writes all of it atomically, and every save through the editor upserts the online config row - disabled by default, so live scoring is gated by the online config’s Score live traffic switch (off = the config stays saved, nothing is scored live, no LLM spend).
- On the wire,
online: nullmeans the scorer has no online profile yet - an SDK create that omittedonline, a seeded template, or a template you just added. A scorer in that state has no live-traffic evidence, so its row menu hides Ratings and shows Tune judge disabled with a tooltip telling you to enable online scoring first; flipping its row toggle opens the editor rather than silently going live - going live is always an explicit save. - Engine-seeded quick-start templates (the RAG/Agent/Session/Safety metric packs and the “Example: Helpfulness Judge”) carry
seeded: trueon the wire; the Scorers page shows its first-run starter state until a non-seeded scorer exists, and lists templates under New scorer → Template scorer (Add clones the template into your own scorer) instead of padding the table.
- Judge - the rubric (acceptance / rejection / guidance; acceptance criteria is
recommended, not required - offline runs grade against the dataset’s expected results, so
the default template alone is a valid judge, while live and session scoring lean on your
criteria), with Judge model & prompt as a collapsible machinery card beneath it (model,
tool-context level, template - auto-expanded when a custom template exists). The right rail
is Try it on real traffic: pick any recent trace or a whole multi-turn session and run
ONE judge call with the unsaved draft (
GET /agent-monitoring/judge-scorers/preview-contextlists the targets,POST .../preview-scorescores; sessions go through the sweep’s exact structured session prompt), followed by live assembly cards showing exactly what the judge receives. - Live scoring - the Score live traffic switch, scope (per trace / per session + idle seconds), sample rate, signal threshold and severity, agent restriction, and a judge-calls/day estimate from your last 7 days of traffic.
- Offline runs - repetitions, deterministic metrics, code scorers, default-for-runs.
online_evaluators with an evaluation_settings_id reference, and evaluation-settings) keep working as views onto the same entity - the SDK clients now emit a (default-hidden) DeprecationWarning pointing at client.monitor.judge_scorers, and the dashboard no longer uses them anywhere - binding a config that is already another evaluator’s profile transparently binds a fresh copy instead of sharing.
A score below the evaluator’s alert threshold (0-10, default 5) raises a signal, the same triage surface a failing Monitor pattern already lands on, deduped by evaluator and agent so a recurring low score accumulates one occurrence count instead of a new signal per trace. Set the threshold’s severity (low/medium/high/critical), or turn the threshold off entirely to score purely for the ratings chart with no triage. A signal raised this way shows the evaluator’s own name and an “LLM judge” tag in the Signals list, distinguishing it from a pattern match at a glance; clicking through opens that evaluator’s ratings dialog directly.
The same thing works from the Python SDK:
sample_rate (default 0.1) matters more here than it does for pattern-matching: every check is a real LLM call against your own API key. scope_mode/agent_ids restrict an evaluator to specific agents, same as a pattern’s. Results land in the same event log Overview’s KPI/trend widgets read from, but are excluded from that health-rate math (they’re a continuous score, not a failure signal). For a hard spend ceiling on top of sampling, set AGENTX_QUOTA_ONLINE_JUDGE_CALLS_PER_DAY: a daily per-project cap on all live judge calls - per-trace and per-session evaluators plus scorer-group judge members all draw from the same budget. Unset = unlimited (the broader AGENTX_QUOTA_JUDGE_CALLS_PER_DAY cap - per organization in multi-tenant mode, per instance otherwise - still applies separately).
When the judge fails
A judge call that returns nothing usable (empty response, unparseable verdict) is retried once automatically. If the retry also fails, the failure is never disguised as a score:- Offline runs: the result is stored with status
"skipped"and anullrating - excluded fromaverageRatingand from CI gates, never averaged in as a zero. The run’sliveStatisticscarriesskippedCountandfailedCountso a run that silently judged nothing is visible at a glance. - Online scoring: no Signal is raised and no rating is recorded. An
online_eval_judge_failureevent is kept instead, and the Scorers page shows a per-scorer judge-failure count - a judge that has quietly stopped scoring looks broken there, not healthy.
What the judge actually receives
The editable template carries four substitutable variables -{input}, {output},
{expected}, and {context} (retrieval context from metadata.retrievalContext or recorded
retrieval spans) - but the judge always sees more than the template. The engine assembles the
final message in a fixed order, and a custom prompt can never silently lose the extra context:
- Your template, with the four variables substituted.
- Agent execution trajectory - tools called with arguments and results, order, failures,
rendered from the trace’s span tree (when a trace is linked). Governed by the scorer’s
Tool context level (
judge.toolContext):"none"strips this block entirely (the judge sees only conversation + expected results - for pure text rubrics),"simple"(the default, the historical behavior) includes it,"detailed"adds the block below. - Tool definitions (
toolContext: "detailed"only) - full definitions of each tool the agent actually used, deduped: capturedmetadata.toolsfrom the trace’s spans first (the exact schema the model saw - the SDK integrations record every request’stools=[...]list), with the Tools & MCPs registry as a by-name fallback for manual tracer users. Plus one line naming tools advertised to the model but not used, so “was there a better tool it didn’t pick?” stays gradeable without paying for unused schemas. The used-names-only registry lookup is what keeps the project-wide registry safe - it can never inject another agent’s tools. - Judge Guideline - the dataset case’s per-question guideline (offline runs only).
- Acceptance Criteria, Rejection Criteria, and Evaluation Criteria (the editor’s “Additional guidance” field) - appended verbatim as labeled blocks.
"none" = conversation turns only, "detailed" adds
the used-tool definitions to the transcript). The
editor’s “What the judge receives” cards render this order live as you edit, with expanders for
the exact assembled prompt and a fully filled example.
Trajectory-aware judging
Per-trace scoring is trajectory-aware: the judge prompt includes the agent’s actual execution path - tools called with their arguments and results, order, failures - rendered from the trace’s span tree (or its flat tool-call list). Criteria written against the trajectory (“no unnecessary or repeated tool calls”, “answers must follow from tool outputs”) are scoreable, not just aspirational - and the Detailed tool-context level adds the used tools’ full definitions so “was there a better tool it didn’t pick?” is scoreable too.Per-trace vs. per-session scope
By default an evaluator scores individual traces as they arrive (scope="trace"). Pass scope="session" to judge whole conversations instead: a background sweep watches for multi-turn sessions that have been quiet for idle_seconds (default 120), builds the full transcript, and scores it against the same evaluator criteria - so criteria like “did the conversation actually resolve the customer’s problem” become answerable. sample_rate keeps its per-trace meaning here: the keep-or-skip decision is hashed once per (conversation, scorer) and is stable across sweep ticks, so a sampled-out conversation stays out permanently and the configured rate is the true fraction of conversations judged - not a per-tick roll that would eventually score everything. See Multi-Turn Session Evaluation for the full guide: sweep mechanics, the built-in Session Baseline Judge, on-demand SDK checks, and turning failing conversations into regression tests.
Every project ships with one built-in session evaluator: Session Baseline Judge, created paused like every other scorer - switch it on from the Scorers page. It scores whole-conversation consistency - context retention, self-contradiction, goal drift - and points at the first step where the conversation broke. Its rubric is a normal judge rubric (not code), so Tune judge improves it from calibration evidence like any other scorer; the scorer itself is read-only except the rubric, the prompt, and the live-scoring switch, and can’t be deleted.
AGENTX_SESSION_SWEEP=false disables the background sweep; POST /agent-monitoring/session-sweep/run triggers one manually either way.
Full lifecycle from the SDK - list/get/update/delete alongside the builder, plus the
scored evidence behind each evaluator:
Tuning the judge from the SDK
The dashboard’s Tune judge flow (measure the evaluator against recorded reality, rewrite its criteria from the disagreements, validate by exact re-judging, publish behind approval) is fully scriptable:window argument accepts "24h", "7d", "30d", or "rubric". "rubric" - the
dashboard’s Tune Judge default - means verdicts produced by the current rubric: everything
since the scorer’s criteria were last edited or a tuning proposal was published, clamped to 30
days. That is the semantically right evidence set for tuning, because disagreements older than
the last rewrite are complaints about criteria that no longer exist, and tuning from them
re-litigates issues a previous rewrite already fixed. The time windows remain useful for
scorers with sparse review coverage, where the current rubric hasn’t accumulated ground truth
yet. The response’s window and since fields echo the boundary that was actually applied.
Reading the agreement numbers
agreementRate is raw agreement, and raw agreement flatters a judge on imbalanced traffic: if
90% of responses are genuinely fine, a judge that passes everything scores 90% while detecting
nothing. alpha is the same comparison corrected for chance - Krippendorff’s alpha over the
binary verdict pair, which for two raters is Scott’s pi with a small-sample correction. Read it
as: 1 = perfect alignment, 0 = no better than a coin weighted like the traffic, negative =
systematically opposed. alphaBand ships a plain-language band (poor / slight / fair /
moderate / substantial / near-perfect) so every surface interprets the same value the same way.
Two honesty rules. First, alpha is null until at least 15 compared items have ground truth
(alphaMinItems echoes the threshold) - with a handful of labels the statistic swings wildly,
so it is withheld rather than fabricated.
Second, the ground-truth streams (triage corrections, review labels, disputes) skew toward
contested cases by construction, so read alpha as alignment on human-reviewed items, not on
raw traffic - a genuinely fine judge can look mediocre if humans only ever reviewed the hard
calls. Sampled labels from the review queue reduce that skew.
Ground truth comes from outcomes, user feedback, and
human review-queue labels; the validation verdict
is measured (candidate criteria re-judge the exact cases the current ones got wrong, plus a
control set they got right), not estimated. Publishing is gated on that provenance: pass the
validate_tuning result as validation, and a "regressed" verdict is refused - force=True
is the deliberate escape hatch, recorded as such in the version history.
The provenance gate is enforced with a signed token. validate_tuning returns a
validationToken proving the verdict was measured for exactly that candidate package on that
scorer, and publish requires it - the SDK passes it automatically when you hand the
validate_tuning result to publish_tuning. The token expires after 24 hours; a publish
after that returns 409, and you re-run validate_tuning on the same package to get a fresh
one.
Built-in metric pack
Every project ships with seeded judge-scorer templates (seeded: true on the wire) - twelve across four families (RAG, Agent, Session, Safety; the full list is on the Scorers page). They are pickable as the grader anywhere one is chosen (dataset runs, the Playground) and live in New scorer → Template scorer rather than padding the Scorers table - Add clones one into your own editable, deletable scorer. The RAG five:
- RAG: Faithfulness - every factual claim in the response must be supported by the retrieved context.
- RAG: Answer Relevancy - does the response actually address the query?
- RAG: Context Relevancy - judges the retriever: were the retrieved chunks relevant and sufficient? A low score means fix retrieval, not the prompt.
- RAG: Contextual Precision - are the relevant chunks ranked above the irrelevant ones? Targets the reranker.
- RAG: Contextual Recall - does the context cover what the expected answer needs? Offline-oriented (needs a case’s
expected_results).
{context}, which resolves from a trace’s metadata.retrievalContext (a string or an array of chunk strings) when set, else from the trace’s own recorded retrieval spans (tracer.trace_retrieval(...), LangChain/LlamaIndex retriever callbacks, OTel retrieval spans) - so if your integration already records retrievals, the judges see the chunks with no caller changes. See RAG evaluation for the full metric guide and the offline context sources. Add one from the template picker to get an ordinary scorer you can edit, tune with Tune judge, or delete - the template itself stays in the library. A zero-cost PII in response built-in pattern (emails, phone numbers, SSNs, payment cards, regex-based) also runs alongside the other built-in checks.
