Skip to content

Migrating to the Labeling Engine

Move icl_labeling, judge_calibration, pre_annotation and Solo Mode configs to the labeling engine with potato label migrate-config, and see what changes once you do.

Potato's older machine-labeling features keep working in 2.11, and nothing changes behavior until you add a labeling_engine block. Three keys now print an informational note at startup that names their labeling engine equivalent, and they are planned for removal in 3.0. The notes go to stderr, start with NOTE:, and are not warnings, so potato validate --strict does not fail on them.

The table lists the three keys and what each becomes:

Older keyEngine equivalent
icl_labelingan llm source, with a threshold_legacy contract for the old rule and a selective_risk contract beside it
judge_calibrationjudge sources with k_sample confidence, whose blind sample becomes calibration requests
pre_annotationa static source

Solo Mode, judge alignment and the interactive AI assistant (ai_support) are not deprecated. Solo Mode is one expert working with an LLM through its own interface, and judge alignment is a report. When the engine is on, both also write their model predictions into the engine's store, so the engine can calibrate and certify them.

potato label migrate-config

potato label migrate-config translates the older keys into a labeling_engine block:

bash
potato label migrate-config config.yaml --out config-engine.yaml

The command reads the YAML without loading any data, adds an equivalent labeling_engine block, and writes the result with a header of notes that explain each translation. It writes the block with enabled: false, so the translated config behaves as the original did until you turn the engine on. Read the notes, check the sources and contracts, then set enabled: true and assignment_strategy: engine. The command exits with an error when the config already has a labeling_engine block, or when there is nothing to translate.

Translation table

Each older block maps to engine sources, contracts and human settings as follows:

Older blockSourcesContractsHumans
solo_mode with confidence_routing.tiersone source per tier, in tier orderselective_risk per one-of-N scheme, error: 1 - end_human_annotation_agreementpools: [solo]
solo_mode with labeling_modelsone source per model, and the first is the cascadeas abovepools: [solo]
solo_mode.juryone source per juror, plus a jury source as the cascadeas above
icl_labelingthe ai_support endpoint as an llm sourcethreshold_legacy at the old confidence_threshold, and selective_risk at 10%calibration_rate = the old verification sample_rate
judge_alignmentthe judge endpoint as a judge source (with the rubric when there is one scheme)no_worse_than_human, epsilon: 0.15, per judged schemeoverlap: 0.3
judge_calibrationeach model as a judge source with k_sample confidencesampling.sample_size → budgets.human_labels
pre_annotation with field or predictions_filea static source, first in the cascade
active_learning.llman llm source
ai_budget.cap_usdbudgets.model_usd

Behavior changes after migration

The engine treats human labels differently from the older features, and the notes in the translated config say where. Expect four changes:

  • Fixed thresholds become tested ones. Solo Mode's routing thresholds and icl_labeling's confidence threshold accepted machine labels above a fixed number. selective_risk chooses the threshold on dev labels and accepts only what passes a test on held-out labels, so expect fewer labels accepted at first, with a stated error bound on the ones that are.
  • Verification samples become uniform. icl_labeling verified the least-confident predictions first, which finds errors quickly and gives a biased accuracy estimate. Engine calibration requests are a random sample with recorded inclusion probabilities.
  • Inline judging becomes blind. judge_alignment.inline showed the judge's verdict while people labeled, so agreement was measured on anchored labels. Engine calibration requests never show a machine answer.
  • Pre-annotations are tested before they are trusted. A static source's labels are accepted only where a contract certifies them, and elsewhere people see them on verify requests.

Further reading

For implementation details, see the source documentation.