OpenObserve Docs
IntegrationAI

LLM Evaluations

Updated View MarkdownOpen in ChatGPTOpen in Claude

OpenObserve offers two evaluation modes: Online Evaluations, which score live traces and spans as they happen, and Experiments, which run scorers over a static dataset for offline testing and comparison. Both use LLM-as-a-judge scorers (your own AI provider) or external remote scoring endpoints.

Overview

ResourceWhat it does
ProviderAn LLM API configuration (OpenAI, Anthropic, etc.) used by LLM Judge scorers.
Score ConfigDefines a score's shape (numeric, categorical, or boolean) and its healthy/unhealthy threshold.
ScorerThe evaluation logic: a prompt template plus a score config. Two types: LLM Judge and Remote.
Eval JobBinds scorers to a stream, defines what to evaluate (span, trace, or session), and how much to sample.

Activating an eval job runs your scorers against incoming data. Scores land in the _llm_scores stream; evaluator telemetry lands in the _evaluator stream.

the Quality page listing score configs with their health, typical score, and score counts

Enable Online Evaluations

Online Evaluations is available in the Enterprise edition and OpenObserve Cloud, and is enabled by default:

O2_EVAL_ENABLED=true

Renamed setting

O2_EVAL_ENABLED replaces O2_ONLINE_EVALS_ENABLED. The old name still works when the new one is not set, but OpenObserve logs a deprecation warning. If both are set, O2_EVAL_ENABLED wins.

When disabled, the evaluation sections of the AI Observability menu, Settings > Data & AI > LLM Providers, and Settings > Data & AI > GenAI Agent Mapping are hidden, and the evaluation API endpoints are not registered.

Other server settings:

VariableDefaultDescription
O2_EVAL_SCHEDULER_POLL_INTERVAL_SECS45How often the scheduler polls trace streams for trace- and session-scope jobs.
O2_EVAL_TRACE_IDLE_TIMEOUT_SECS30Default idle window for trace-scope jobs that don't set their own. Capped at 30 minutes.
O2_EVAL_TRACE_MAX_AGE_SECS1800Default max age for trace-scope jobs.
O2_EVAL_SESSION_IDLE_TIMEOUT_SECS1800Default idle window for session-scope jobs that don't set their own. Capped at 4 hours.
O2_EVAL_SESSION_MAX_AGE_SECS14400Default max age for session-scope jobs.
O2_EVAL_WORKER_THREAD_NUM0Worker threads that run scorers. 0 uses half of ZO_CPU_NUM.
O2_EVAL_SCHEDULER_MAX_PENDING_MEMORY_MB0Memory budget for targets waiting to complete. 0 uses 1% of system memory, between 32 and 512 MB.

Providers

A Provider stores the connection details for an LLM API. Providers live under Settings > Data & AI > LLM Providers. Click New Provider to add one.

the LLM Providers list under Settings > Data & AI with an Anthropic and an OpenAI-compatible provider

FieldDescription
NameDisplay name.
Provider typeOpenAI, DeepSeek, Anthropic, Ollama, vLLM, OpenAI-compatible, or System One (TypeSafe Jev).
Default modelUsed when a scorer doesn't specify one.
Available modelsModel IDs this provider offers, for scorer selection.
Base URLRequest URL. Leave empty to use the provider's default endpoint. Required for OpenAI-compatible.
API KeyStored encrypted and never read back. Leave blank when editing to keep the existing key. Optional for keyless self-hosted providers.

the Create LLM Provider form with the provider type list open

Use OpenAI-compatible for any service that implements the OpenAI chat completions API, and vLLM for a self-hosted vLLM server (defaults to http://localhost:8000/v1/chat/completions). System One (TypeSafe Jev) is available to scorers only; it does not appear in the Playground or Experiments.

Click Test Connection to check the endpoint and key before you save. To edit or delete a provider, use the actions on its row. Scorers that use a deleted provider fail until you reassign them.

Score Configs

A Score Config defines what a score looks like and when it's healthy. Navigate to AI Observability > Evaluate > Score Configs and click New score config.

FieldDescription
Namee.g., "Faithfulness", "Accuracy".
Data Typenumeric, categorical, or boolean.
Numeric RangeFor numeric scores: {"min": 0.0, "max": 1.0}.
CategoriesFor categorical scores: a list of valid labels.
Healthy Thresholde.g., {"direction": "gte", "value": 0.7} means scores ≥ 0.7 are healthy.

the Score Configs list with numeric, boolean, and categorical configs and their healthy thresholds

Updating a score config creates a new version; scorers can pin to a specific version or always use the latest.

Scorers

A Scorer is the evaluation unit: a prompt template with {{variable}} placeholders, execution parameters, and an optional linked score config. Navigate to AI Observability > Evaluate > Scorers and click New scorer.

the Scorers list with LLM Judge and Remote scorers and the score config each produces

  • LLM Judge: sends the rendered template to an LLM via a provider. Configure provider, model, temperature, max tokens, timeout, and optional reasoning.
  • Remote: sends the rendered template as an HTTP request to an external service. Configure endpoint, method, auth (none/bearer/basic/api_key), headers, timeout, and retries.

the New LLM Judge Scorer form with a score config, provider, model, judge prompt, and the Test this scorer panel

Use the Test button on the scorer detail page to try it with sample variable values; you'll see the score, reasoning, model, latency, and token usage.

the Scorer Test dialog showing results

Like score configs, scorers are versioned. Eval jobs can reference a scorer by entity ID (always latest) or pin a specific version. The Versions tab in the scorer drawer lists every version, newest first, and tags the active one. Select two versions to compare them: you see a split or unified diff of the template and a table of the fields that changed.

Eval Jobs

An Eval Job runs scorers against incoming traces at a chosen target scope: span, trace, or session. Navigate to AI Observability > Evaluate > Eval Jobs and click New job. Saving a job checks that you can read the selected stream.

the Eval Jobs list with one active and one paused job

FieldDescription
StreamThe traces stream to evaluate.
Target Scopespan (score each matching span), trace (score a whole trace once complete), or session (score an entire conversation).
Filter ConditionWhich spans/traces/sessions are eligible. Besides comparison operators, conditions support is_null, is_not_null, is_empty, and is_not_empty.
ScorersOne or more scorers to run against each target.
Input MappingMaps each scorer's {{variables}} to a value source: a system-provided value (like input, output, statistics) or a span attribute.
Sampling Modeall or rate (evaluate a percentage, e.g., 0.1 for 10%).

the New Eval Job form with a filter condition, sampling rate, a scorer, and its prompt variable mapping

Target scope

ScopeWhat is evaluatedWhen it runs
SpanEach matching spanImmediately, in real time.
TraceA whole trace assembled from its spansOnce the trace is judged complete (see below).
SessionA full conversation across multiple traces, grouped by session IDOnce the session is judged complete.

Trace and session completion

For trace- and session-scope jobs, configure how OpenObserve decides a target is "done":

FieldDefaultDescription
Idle Window30 sec (trace) / 1800 sec (session)Time with no new spans before the target is considered complete.
Max Age1800 sec (trace) / 14400 sec (session)Score the target after this long even if spans are still arriving.
End SignalnoneAn optional filter; when a matching span arrives, evaluate immediately instead of waiting.

Example end signal (evaluate as soon as a span with status = "complete" arrives):

{
  "version": 2,
  "conditions": {
    "filterType": "group",
    "logicalOperator": "AND",
    "conditions": [{
      "filterType": "condition",
      "column": "status",
      "operator": "=",
      "value": "complete",
      "logicalOperator": "AND"
    }]
  }
}

trace config with end signal

Span selectors (trace scope)

For trace-scope jobs, a scorer may only need a subset of a trace's spans. A Span Selector filters, picks, and limits which spans (and fields) get sent to a given scorer; bind one to any scorer whose template uses {{ spans }}.

span selector configuration

Input mapping and template variables

Each scorer's {{variables}} are mapped to a source in the job form's Prompt variables section, either a system-provided value or a span attribute.

For trace/session scope, OpenObserve auto-supplies these as ready-to-use template variables:

VariableScopesDescription
input / outputtrace, sessionFor a trace, the LLM input/output messages from the root span. For a session, the user and assistant chat turns.
tool_callstrace, sessionThe tool calls made in the target, for scorers that need tool evidence.
spanstraceA compact list of spans (up to 5 by default, or per a bound span selector).
stepstrace, sessionAn ordered sequence of LLM calls, tool calls, and other spans.
statisticstrace, sessionAggregate counts: spans, LLM calls, tool calls, errors, duration, tokens, cost.

For span-scope jobs, every variable maps to a span attribute instead (e.g. input → {{gen_ai_input_messages}}).

Manual evaluation

Trigger an evaluation on demand for a specific trace, span, or session. This is useful for re-testing after changing scorers. From the trace, span, or session detail page, click Evaluate trace / Evaluate span / Evaluate session, then pick which Eval Job to run.

Job lifecycle

draft → active ⇄ paused
          ↓
       degraded → active
          ↓
       archived
  • Activate: starts scoring.
  • Pause: stops it temporarily.
  • Resume: restarts it.
  • Archive: stops it permanently.

Editing an active job's config (filters, sampling, scorers, scope) takes effect immediately. No need to pause first.

Where scores go

Scores land in the _llm_scores stream; evaluator telemetry (latency, tokens, status) lands in the _evaluator traces stream. Query both directly for debugging or dashboards.

Quality Dashboard

AI Observability > Evaluate > Quality gives a real-time overview of evaluation health across your score configs, agents, and streams. The table lists each score config with Health, Typical score, Unhealthy, Scores, and Updated. Click a score config to see its trend and distribution charts and the scores behind them, filterable by scope (All/Span/Trace/Session).

quality page KPI cards with scope breakdown

To see scorer runs that failed, open the eval job and select its Failures tab.

Evaluation scores

The Evaluation scores list in a score config's detail shows individual score records: value, health, target identity, agent, and reasoning. Switch between All and Unhealthy.

evaluation runs table in quality detail

Gen-AI Agents

OpenObserve auto-discovers agents from your trace telemetry (via gen_ai.agent.name/id, or your own configured attribute fields), so you can scope the Quality, Insights, and Sessions views to a single agent or All Agents.

If your telemetry uses non-standard attribute names, map them under Settings > Data & AI > GenAI Agent Mapping. Scorer templates can also reference {{agent_name}}, {{agent_id}}, and {{pipeline_source_stream_type}}. See LLM Monitoring for the attributes OpenObserve checks.

Experiments

For offline, batch evaluation against a versioned dataset (pinned scorers, trial counts, cost estimates, baseline comparisons), see LLM Experiments.

RBAC

Providers, Score Configs, Scorers, and Eval Jobs each have their own permissions (GET, LIST, POST, PUT, DELETE). Assign roles in IAM > Roles to control access.

API Reference

All endpoints are prefixed with /api/{org_id}.

ResourceKey endpoints
ProvidersGET/POST /providers, GET/PUT/DELETE /providers/{id}, POST /providers/test
Score ConfigsGET/POST /score_configs, GET/PUT/DELETE /score_configs/{id}, GET /score_configs/{id}/versions
ScorersGET/POST /scorers, GET/PUT/DELETE /scorers/{id}, POST /scorers/test, POST /scorers/llm_judge/output_schema, GET /scorers/{id}/versions
Eval JobsGET/POST /eval_jobs, GET/PUT/DELETE /eval_jobs/{id}, POST /eval_jobs/{id}/activate|pause|resume|archive, POST /eval_jobs/{id}/manual_eval
Gen-AI AgentsGET /gen_ai/agents, GET/PUT /settings/gen_ai/agent_mapping, DELETE /settings/gen_ai/agent_registry
ExperimentsSee the LLM Experiments API Reference.
Was this page helpful?

On this page