Skip to main content
Eval scoring is Python-backed. Each task defines a Python grader with one of three contracts: Python runs in the sandbox service. Do not pass API keys or provider credentials into grader code. Use ctx.responses_create and ctx.embeddings_create for model-backed scoring.

Grader declaration

Use inline source for short graders:
Use uploaded files for reusable graders:
Fields: Provide either source or file_id.

Sample contract

Sample graders define:
They can also accept ctx:
sample describes the model output:
item contains the dataset row plus convenience fields:
The exact row fields depend on your dataset and preprocessor.

Return a single score

Return a finite float when the task has one metric. MKA1 stores it under metric_id.
If metric_id is omitted, the score key is score.

Return multiple scores

Return a dict with a scores object when the task has multiple metrics.
Only finite numeric score values are stored in scores. The optional judge object is preserved on the sample for debugging and dashboards.

Invalid results

The following results become invalid and receive a zero score:
  • Exceptions.
  • Non-finite floats such as NaN or Infinity.
  • Boolean returns.
  • Strings or other non-dict, non-number returns.
  • Dicts without any finite numeric score.
The sample judge payload includes the raw invalid payload and error details.

Batch contract

Batch graders define:
They run once per task and model during finalization. Use them when the metric needs the whole set of samples. Each batch sample contains:
Return aggregate metrics:
Return sample updates when you want to add per-sample scores, judge details, or corrected extracted outputs:
Sample update fields: If a task declares metrics, unexpected batch metric IDs are dropped from final aggregates. This protects dashboards from accidental metric drift.

Model-backed graders

Use contract: "model_backed" when Python needs model or embedding calls. The Python code asks for a tool call. Gateway performs the call with the run’s authenticated context and returns the result to the sandbox.
The run should set judge_model and embedding_model when the grader uses model="auto":
If Python passes an explicit model ID, that explicit model is used. If it passes model="auto" or omits model, MKA1 uses the run’s judge_model or embedding_model.

LLM-as-judge

ctx.responses_create accepts the same request shape as the MKA1 Responses API, except the eval system forces stream=false, store=true, and background=false. Judge responses are stored and can be audited like normal Responses traffic.

Embedding similarity

ctx.embeddings_create routes through the MKA1 Embeddings API. Usage is logged under the run’s authenticated context.

Python preprocessors

Preprocessors are not graders, but they use the same sandbox execution model and file loading rules. They run before prompt rendering. Row preprocessor:
Batch preprocessor:
Declare them on a task:

Common scoring recipes

Exact match

Case-insensitive exact match

Numeric tolerance

Token F1

Macro F1 with grade_batch

Debugging graders

Use sample details first:
curl
Look at: Common fixes:

Security model

Python graders and preprocessors execute in the sandbox service. They are intended for eval logic, not for arbitrary application workflows. Keep these rules in mind:
  • Do not put secrets in grader source, dataset rows, or metadata.
  • Do not expect raw network credentials inside Python.
  • Use ctx.responses_create and ctx.embeddings_create for model calls.
  • Keep uploaded Python files scoped to the team that owns the suite.
  • Prefer uploaded grader files for reusable logic so suite versions clearly track their dependencies.
The eval API preserves the model call details it can observe, including candidate response_ids and grader judge payloads, so you can audit how scores were produced.