GuidesContinuous evaluation

Continuous evaluation

Continuous evaluation scores your traffic as it arrives: every time new traces are ingested, Neens samples them and runs your continuous judges against the sample — no manual runs, no schedules to manage. It’s how an agent accumulates a live quality signal (and a failure set for clustering) without anyone pressing a button.

At a glance

WhereThe Judges page — a scorer with Apply for set to Continuous (score new traces)
What runs by defaultPrimary Score, the out-of-the-box composite every agent ships with
NeedsAn LLM connection (Settings → Connections) — see LLM connections
ProducesScore rows, written moments after each trace arrives
Cost controlsPercentage sampling per scorer + a per-scorer daily cap (default 500 traces/day)
When nothing scoresThe run ends Skipped with a reason code — transient reasons are retried, permanent ones are not

How it works

After a batch of traces is ingested and persisted, Neens checks the agent’s enabled scorers whose trigger is Continuous (score new traces) and, for each one:

  1. Samples the just-arrived traces at the scorer’s effective sampling rate (a coin flip per trace at the configured percentage).
  2. Applies the daily budget. Each continuous scorer has its own daily cap (max_scored_per_day); once a scorer has dispatched its cap for the day, further traces are skipped until the next UTC day. Budgets are per scorer, so one continuous judge can never starve another’s.
  3. Creates a small eval run scoped to exactly the sampled traces and queues it for the eval worker — the same scoring path, retries, and run outcomes as a manual run. These runs are attributed as Automated in run history and the Activity feed.
  4. Writes scores. Verdicts land in the score catalogue with source llm_judge (or composite for composites). A composite like Primary Score inline-scores any component that has no score yet, so its component metrics fill in as byproducts.

Continuous evaluation is best-effort by design: it runs after ingestion completes and can never block, slow down, or fail a trace write. If scoring hiccups, the traces are still safely stored.

Scores are asynchronous. A trace appears on the Traces page immediately; its scores land shortly after — typically seconds, longer under queue depth or a slow LLM provider. Expect a brief window where a new trace is visible but not yet scored.

Primary Score, cold start, and steady state

Every new agent ships with one continuous scorer enabled: the Primary Score composite (Faithfulness + Answer Relevancy + Coherence). Its defaults balance signal against cost:

PhaseSampling rateWhy
Cold start — until 200 traces have been dispatched100%A brand-new agent builds a scoreable failure set fast.
Steady state — after that5%A representative ongoing sample.
AlwaysCapped at 500 traces/dayPercentage sampling alone isn’t safe on a firehose.

The cold-start boost graduates automatically once the threshold is crossed — if your scoring rate drops from “everything” to “a sample” after the first couple hundred traces, that’s expected, not a failure.

What continuous evaluation is not

  • It is not retroactive. A continuous scorer only scores traces that arrive after it’s enabled (or resumed). To score existing traces, use Run now on the scorer — a one-off run over eligible historical traffic.
  • It is not the Issue Classification path. The built-in Issue Classification judge also shows up as a continuous scorer, but it’s dispatched by a background sweep (every 30 minutes) over the agent’s failure set only — not on ingest, and never over healthy traffic. See Issues & failure modes.

Enable, pause, and resume

Make a scorer continuous

On the Judges page, Configure the judge and set Apply for to Continuous (score new traces). The What traces to score percentage becomes the continuous sampling rate. Saving configuration never runs anything by itself — new arrivals start being scored from that point on, and the hint reminds you: “Use ‘Run now’ to also score existing traces.”

A user-created continuous scorer that ships without a daily cap automatically gets the default (500 traces/day) so an unbounded on-ingest scorer can’t become a cost surprise.

Pause when needed

In the Enabled scorers table, a continuous scorer’s toggle reads Pause / Resume (manual scorers say Disable / Enable). Pause stops automatic scoring of new traces, keeps every existing score, and cancels any in-flight run.

Resume — forward only

Resume turns automatic scoring back on for traces arriving from that moment. Traffic that came in while paused is not backfilled; use Run now if you want it scored.

Sampling and cost

Every trace a continuous scorer grades costs at least one LLM call on the agent’s configured LLM connection — and a composite costs one call per component that doesn’t already have a score (up to three for Primary Score). Your levers:

  • Sampling percentage (per scorer, in Configure → What traces to score) — the fraction of arriving traces that get scored.
  • Daily cap (per scorer) — the hard ceiling regardless of traffic volume. Resets at midnight UTC.
  • Scoring connections (pool) — spread continuous load across several connections to dodge provider rate limits.

If the agent has no LLM connection, continuous runs still fire, but they score nothing: the run finishes Skipped and every target records the reason no_llm_connection. Neens never borrows another agent’s credentials, and ingestion is unaffected. Configure one under Settings → Connections (LLM connections).

When a run is Skipped

A run finishes Skipped when it reached the end having scored nothing — no target succeeded and none failed either. It is deliberately neither green nor red: skipping can be perfectly legitimate (there is genuinely nothing to score yet) or it can mean something is misconfigured. The reason tells you which.

Every skipped target carries a reason code plus a plain sentence, visible on the Activity feed row and in its Details drawer. A run can carry more than one code; the drawer lists each with how many targets it accounts for.

“Unknown” is a real answer. If Neens cannot classify a skip it says unknown — “Neens could not determine why this target was skipped” — rather than showing a blank. An unknown skip is a gap in Neens, not in your configuration: please report the run id. Runs that predate skip reasons are also shown as unknown; their history was never rewritten to guess a cause.

Skip reason codes

CodeWhat it meansRetried?What to do
no_llm_connectionNo LLM connection is configured or visible to this agent, so the judge could not run.NoAdd a connection in Settings → Connections.
llm_connection_errorThe connection could not be resolved on this attempt (a credential-store or database blip).YesNothing — Neens retries. If it persists, check the connection’s credential.
component_judge_missingA judge the composite aggregates no longer exists.NoRe-point or remove that component in the composite’s definition.
component_not_scoreableA component isn’t an LLM-prompt judge and has no existing score for the target.NoScore that component separately, or drop it from the composite.
component_llm_errorA component’s LLM call kept failing (timeout / rate limit / provider error) after the per-target retries.YesNothing immediately. A persistent failure points at the provider or your quota.
component_scoring_failedA component returned output Neens could not read as a score.NoCheck that component judge’s prompt and output spec.
insufficient_componentsFewer component scores were available than the composite’s min_components requires.NoLower min_components, or make the missing components scoreable.
expression_component_missingThe composite’s expression references a component that had no value for that target.NoGive the component a score, or set missing_policy.
no_taxonomyIssue Classification has no failure modes to classify against yet.NoAdd failure modes under Taxonomy. This one is benign.
target_not_foundThe target trace wasn’t visible yet when the run resolved its targets (ingest was still landing).YesNothing — Neens re-dispatches it.
unknownNeens could not classify the skip.NoReport the run id.

Are skipped targets retried?

Transient causes are; permanent ones are not. A background sweep (every 30 minutes) looks for terminal runs holding targets skipped for a retryable reason and opens a new run scoped to exactly those targets — never a re-drive of the finished run, so the original’s history and counts stay intact. Both runs appear in the Activity feed, and the drawer links them (“Retried as …” on the original, “Retry 1 of 2 — re-attempt of …” on the new one).

Every retry is bounded twice:

  • Attempts. The retry chain is capped, so a target is attempted at most three times, ever.
  • Rate. The wait before the first retry is 10 minutes and doubles each attempt (10 → 20 → 40 minutes), so a provider that is already struggling isn’t hammered. At most 20 runs per agent are re-dispatched per sweep.

A permanent reason is never retried — it would produce the identical outcome every time and cost real money doing it. Neither is an unknown skip: Neens cannot argue the condition will clear, so it surfaces it loudly instead of looping on it.

Debugging a skipped run, concretely

Open the run

Go to Activity, filter Status → Skipped, and click Details on the run.

Read the header

The drawer’s header lists each reason with a count, whether it is retryable, and what to do — for example:

3× no_llm_connection   not retryable
No LLM connection is configured for this agent, so the judge could not run.
Add an LLM connection in Settings → Connections, then re-run the scorer.

No retry: none of these reasons clear on their own.

Check an individual target

Each target card carries the same code plus the specific detail the scorer recorded — e.g. “only 1 of 3 components available (min_components=2)” — so you can tell an agent-wide misconfiguration from one odd trace.

Fix and re-run

Permanent reasons need an action from you (a connection, a taxonomy, a component). After fixing it, click Run now on the scorer to score the targets that were skipped — continuous scoring itself is forward-only.

Troubleshooting

SymptomLikely causeFix
New traces aren’t being scored at allThe scorer is paused, or Apply for is Manual (run on demand)Check the Enabled scorers table: Resume it, or Configure and switch to Continuous (score new traces).
New traces aren’t scored, runs show Skipped with no_llm_connectionNo LLM connection visible to the agentAdd a connection in Settings → Connections, then Run now to score what was skipped.
Runs show Skipped with insufficient_componentsThe composite could not gather min_components scores for those tracesLower min_components on the composite, or make the missing component scoreable.
A run is Skipped with reason unknownNeens could not classify the cause (or the run predates skip reasons)Report the run id — an unclassified skip is a gap in Neens, not in your setup.
Only some new traces get scoredPercentage sampling — that’s the designRaise the sampling percentage in Configure if you want more coverage (mind the cost).
Scoring stops partway through the day, resumes tomorrowThe scorer’s daily cap was reachedRaise the cap deliberately, or accept it as your cost ceiling; the budget resets at midnight UTC.
Scoring rate suddenly dropped after the first ~200 tracesCold-start graduation (100% → steady rate)Expected behavior for Primary Score in a new agent — not an outage.
Scores trail traces by minutesEval queue depth or a slow LLM providerNormal under load; check the run’s status on the Judges page. Transient provider errors are retried automatically.
Old traces never got scored after enablingContinuous scoring is forward-onlyClick Run now on the scorer to score existing eligible traces once.

Related: Judges · Scores · Pre-prod evaluations · Metrics catalogue