Skip to content

Endpoint records to traces

The endpoint’s records become the traces of your dataset, the input of Building the test set. Write the dataset’s config.yaml and job_description.json first (Dataset overview); then take one of two routes.

The platform reads the endpoint’s records itself. A call becomes available about 24 hours after it was made, and every record the endpoint holds goes in. Create the traces object, then the dataset from it:

distil traces create-from-inference-endpoint support-yeOdAS
distil dataset create-from-traces --config config.yaml \
  --job-description job_description.json <traces-id>

The first command prints Prepared traces created. ID: <traces-id>, the second Dataset created. ID: <dataset-id>. No job runs: the traces are copied into the dataset, and its train and test splits are empty. The config has to name the format of the endpoint’s records:

trace_processing:
  observation_format: langfuse

Take this route when you need the traces now, or when the records must be filtered first, for example to keep only one model’s answers once a trained model serves the endpoint. Download the records:

distil inference-endpoint download-traces --from-start-time 2026-09-01 --all support-yeOdAS

Each line is one call: the request under input, the response under output, and metadata with the HTTP status and the source (fallback or primary). Convert the successful calls into conversations, one {"messages": [...]} per line. An agent makes one call per step; for the chat completion tasks the platform drops a trace whose messages are a prefix of another trace’s, so each loop counts once.

import json


def convert(record):
    if record["metadata"].get("status") != 200:
        return None
    request = json.loads(record["input"])
    reply = json.loads(record["output"])["choices"][0]["message"]
    if not reply.get("content") and not reply.get("tool_calls"):
        return None
    assistant = {"role": "assistant", "content": reply.get("content") or ""}
    if reply.get("tool_calls"):
        assistant["tool_calls"] = reply["tool_calls"]
    converted = {"messages": [*request["messages"], assistant]}
    if request.get("tools"):
        converted["tools"] = request["tools"]
    return converted


with open("support-yeOdAS-traces.jsonl") as src, open("input-dir/traces.jsonl", "w") as dst:
    for line in src:
        converted = convert(json.loads(line))
        if converted is not None:
            dst.write(json.dumps(converted, ensure_ascii=False) + "\n")

Put the result next to config.yaml and job_description.json, with observation_format: openai_messages (the default) in the config, and create the dataset:

distil dataset create --data ./input-dir

The command prints Upload successful. Dataset ID: <dataset-id>.

Build the test set.