Curatrix

tutorial.title

tutorial.description

Schritt 1 — Sample evaluieren

Bevor Sie auf ein vollständiges Release zugreifen, evaluieren Sie das Manifest eines Sample-Datensatzes. Das Manifest zeigt Schemaversion, Episodenanzahl, abgenommene Stunden und die Dateimap. Es zuerst zu lesen bewahrt Sie davor, eine Format-Inkompatibilität nach dem Download eines großen Releases zu entdecken.

Manifest abrufen und prüfen
# 1. Fetch the sample manifest (replace with your download URL)
curl -H "Authorization: Bearer $CURATRIX_API_KEY" \
  https://api.curatrix.de/v1/datasets/electrical-assembly/versions/1.3.0/manifest \
  -o manifest.json

# 2. Inspect the top-level keys
python - <<'EOF'
import json
m = json.load(open("manifest.json"))
print("dataset:", m["dataset_id"], "version:", m["version"])
print("episodes:", m["episode_count"], "accepted_hours:", m["accepted_hours"])
print("schema_version:", m["schema_version"])
EOF

Schritt 2 — Episoden und Annotationen laden

Episoden und Annotationen sind Standard-Parquet. Kein SDK erforderlich — jeder Parquet-Reader funktioniert. Beginnen Sie mit der Episodentabelle, um die Ergebnisverteilung und Umgebungsaufteilung zu verstehen, bevor Sie die Annotationstabelle öffnen.

Episoden laden (pyarrow)
import pyarrow.parquet as pq
import pandas as pd

episodes = pq.read_table("episodes/episodes.parquet").to_pandas()
print(episodes.dtypes)
print(episodes.head())

# Outcome distribution
print(episodes["outcome"].value_counts())

# Filter to success episodes in workshop
success_workshop = episodes[
    (episodes["outcome"] == "success") &
    (episodes["environment"] == "workshop")
]
print(f"{len(success_workshop)} success/workshop episodes")

Dann die Annotationstabelle laden und über episode_id verknüpfen:

Schritt 2b — Annotationsdetail

Die Annotationstabelle hat eine Zeile je Teilaufgaben-Abschnitt. Abschnitte sind innerhalb einer Episode zusammenhängend und decken sie vollständig ab. Die label-Spalte verwendet das veröffentlichte Vokabular; span_index gibt die Reihenfolge innerhalb der Episode an.

Teilaufgabendauer und Korrekturen erkennen
import pyarrow.parquet as pq

spans = pq.read_table("episodes/annotations.parquet").to_pandas()

# Subtask duration analysis
spans["duration_s"] = spans["end_s"] - spans["start_s"]
print(spans.groupby("label")["duration_s"].describe().round(2))

# Find episodes with recovery sequences
recovery_ids = spans[spans["label"] == "recover"]["episode_id"].unique()
print(f"{len(recovery_ids)} episodes contain a recovery sequence")

Schritt 3 — Python-SDK verwenden (optional)

Das SDK ist eine dünne Schicht über den Parquet-Tabellen. Es übernimmt Versionsauflösung, Prüfsummenverifizierung und verzögertes Frame-Dekodieren. Wenn Ihr Stack Parquet und MP4 bereits direkt liest, brauchen Sie es nicht.

Episoden filtern und Frames mit dem SDK lesen
from curatrix import Dataset

# Pin the version — omitting it resolves to the newest licensed release,
# making a training run non-reproducible.
ds = Dataset.open("electrical-assembly", version="1.3.0")

print(ds.schema_version, ds.episode_count, ds.accepted_hours)

for episode in ds.episodes(outcome="failure", environment="workshop"):
    # frames() is lazy — decoded on demand, not all loaded at once
    frames = episode.frames(stream="head", fps=10)
    recovery = [s for s in episode.subtasks if s.label == "recover"]
    if recovery:
        print(episode.id, len(frames), recovery[0].start_s)

Schritt 4 — Evaluierung und Benchmark durchführen

Das Benchmark-Ziel sollte vor Beginn der Erhebung vereinbart worden sein. Sperren Sie den Evaluierungssplit vor dem Training — verwenden Sie den im Release enthaltenen Split ohne Überschneidung der Mitwirkenden. Protokollieren Sie Datensatzversion, Schemaversion, Split-Hash und Benchmark-Ergebnis zusammen mit Ihrem Trainingslauf, damit das Ergebnis reproduzierbar ist.

Evaluierung auf dem Split ohne Mitwirkenden-Überschneidung
from curatrix import Dataset
import numpy as np

ds = Dataset.open("electrical-assembly", version="1.3.0")

# Use the supplied splits — contributor-disjoint by construction
train = ds.split("train")
evaluation = ds.split("eval")

assert set(train.contributors).isdisjoint(evaluation.contributors), (
    "Splits share contributors — evaluation would measure memorised scenes."
)

print(f"Train:  {len(list(train.episodes()))} episodes")
print(f"  Eval: {len(list(evaluation.episodes()))} episodes")

# ── Run your model on the eval split ──────────────────────────────────────
# Your benchmark target was agreed before collection started.
# Record: dataset version, schema version, eval split hash, benchmark result.

benchmark_result = your_model.evaluate(evaluation)  # replace with real call
print(f"Benchmark: {benchmark_result:.4f}")

# Compare against the baseline you locked before collection.
# If the gap is meaningful, use it to scope the next targeted collection round.

Wo die Evaluierung eine Lücke zeigt, nutzen Sie sie, um die nächste gezielte Erhebungsrunde abzugrenzen. Eine Lücke bei Korrektursequenzen etwa übersetzt sich direkt in eine Anfrage nach weiteren Fehler-und-Korrektur-Episoden zu einer bestimmten Teilaufgabe.

tutorial.docsCallout.title

tutorial.docsCallout.description

Mit einem klar abgegrenzten Pilotprojekt starten

Bringen Sie eine Aufgabe mit. Im Gespräch definieren wir Aufnahmeprotokoll, Episodenumfang, Annotationsschema und Lieferformat.

Pilotprojekte starten in der Regel ab rund 25.000 €. Das ist ein Richtwert — endgültiger Umfang und Preis werden nach einem technischen Qualifizierungsgespräch festgelegt.