Skip to content

Overview

A seed dataset is a few dozen labeled examples plus a description of the task. The teacher grows it into a full training set later, so this is the smallest amount of data you have to write by hand.

Read this page before any task-specific one. It covers what every seed dataset needs, whatever the task type. If you start from production traces instead, trace processing produces the seed dataset for you: go to Trace inputs.

Put the files in one directory. config.yaml sets the task type and the models, and job_description.json describes the task in words. train.jsonl holds the seed training examples and test.jsonl the held-out test examples; both have to be present, and either may be empty. unstructured.jsonl is optional and holds unlabeled in-domain texts. All data files are JSONL.

input-dir/
├── config.yaml
├── job_description.json
├── train.jsonl
├── test.jsonl
└── unstructured.jsonl

Create the seed dataset from the directory:

distil seed-dataset create --data input-dir

The command prints Upload successful. Seed dataset ID: <seed-dataset-id>. Every later job on this data takes that ID.

Train and test rows are chat-format conversations.

Task Row shape
classification, question-answering {"messages": [<user>, <assistant>]}
chat-completion {"messages": [<user>, <assistant>, ...]}, assistant turns carry text, tool_calls or both
chat-completion-agentic {"messages": [<user>, <assistant with tool_calls>, <tool>, ..., <assistant>]}
  • <user> and <assistant> are {"role": ..., "content": "<non-empty>"}. The final assistant message carries the answer or label as its content.
  • Chat completion rows, tool calls and the role rules are on the Chat completion and Agentic chat completion pages.
  • An assistant message may carry reasoning_content for a reasoning student.
  • unstructured.jsonl rows are {"context": "..."}.

There’s no hard minimum row count. Aim for 20+ diverse training examples and a test set that covers your production distribution.

What your task is, in words. The teacher reads it when it’s evaluated and when it generates your training data.

{
  "task_description": "...",
  "llm_as_a_judge_instructions": "..."
}
  • task_description describes the task: what the model should do, what a correct answer looks like, how the output is formatted. Derive it from the system prompt of the system you’re replacing, and keep it the same in every iteration.
  • llm_as_a_judge_instructions tells the judge what to accept when it scores an answer. Optional, and not valid for classification.

Classification also needs classes_description. Chat completion takes tools (required for the agentic variant). The full field reference is Job description.

The task type, the two models and the judge:

base:
  task: question-answering
  student_model_name: Qwen3.5-4B
  teacher_model_name: zai.glm-5.3-low-thinking
evaluation:
  llm_as_a_judge_model_name: zai.glm-5.3-low-thinking

Classification is scored on label accuracy and has no judge, so its config leaves out the evaluation section. Everything else has a default; see Config file and Supported models.

These are enforced when the job parses your directory, so check them before submitting.

  • train.jsonl and test.jsonl are both present. Either may be empty (Empty splits); a missing file is an error.
  • Every message content is non-empty, except a chat completion assistant turn that carries only tool_calls.
  • Per row, the total length is at most synthgen.validation_max_total_length.
  • Train and test share no identical rows. Exact duplicates fail.
  • unstructured.jsonl, when present, holds non-empty string context rows, at least synthgen.num_unlabelled_exemplars_per_generation of them.
  • For classification, the label sets in train.jsonl, test.jsonl and classes_description are identical, and each class has at least the configured exemplar counts (default 1).
  • No in-context exemplar count exceeds the number of training rows (Config file).
  • Chat completion rows follow the conversation rules on their task page.

Creating the seed dataset is the validator. distil seed-dataset create parses the directory exactly as the jobs will and rejects an invalid bundle with the reason, before any job is created. The messages and their fixes are in Troubleshooting.

Both files have to be there, and either one may be empty: an empty file says you have no labeled data of that kind, a missing file is an error. A populated split is held to every rule above.

Stage Empty split What happens
Synthetic data generation train Runs zero-shot, and its output becomes the training set
Teacher evaluation test Refused: there is nothing to score the teacher against
Teacher evaluation train Runs only with evaluation.num_few_shot_examples: 0, since few-shot examples come from the training set
Model training train Refused: there is nothing to train on
Model training test Produces a model with no scores
  • Without a test set nothing is scored: no teacher evaluation, no base-versus-tuned comparison. distil slm metrics returns null scores, which is not a failed job. A seed dataset you upload yourself needs a test set for any of the scores on the following pages.
  • Without a training set, synthetic data generation runs before training. It works from the task description, the class or tool definitions and unstructured.jsonl, with no seed examples to imitate.

A test set with no training set is the more useful of the two: teacher evaluation runs with evaluation.num_few_shot_examples: 0, generation and training both run, and every score is available.

Pick your task’s page for the exact row format and a worked example:

Then run teacher evaluation.