Vibe Engines
YouTube

Vibe Engines is free, interactive AI engineering & system design — runs in your browser. Pick a learning path

AI System Design

Design a Data Labeling Platform

Step 1 / 9

Learn AI system design by building a human annotation platform like Scale AI or Labelbox — sourcing labels FROM PEOPLE, not generating them programmatically (see Synthetic Data Pipeline for that).

The numbers to beatfixed budgetsame labeling costuncertainty-rankednot randommore model improvementper label spent

The whole design, in writing

Every step of the build above, written out: the problem each piece solves, the option that was taken and the ones that were not, the numbers, and how it fails in production.

The big idea

The label IS the ground truth — so its quality is everything

A labeling platform's entire output — a human's judgment call — becomes treated as objective truth for training a model. If that judgment is careless, biased, or simply wrong, the model learns exactly that mistake, silently, at scale, often not discovered until the trained model itself misbehaves.

Requestersubmits data to labelLabelerworks through tasks
New in this step: Requester, Labeler.

We'll build quality control as a first-class system, not an afterthought: redundancy and consensus, secret gold-standard checks, skill-aware routing, and active learning to spend a limited labeling budget where it actually improves the model most.

What the new pieces do

Requesterclient
An ML team with a pile of unlabeled data, needing accurate human labels to train or evaluate a model.
Labelerclient
A human annotator — ranging widely in skill, attention, and honesty — whose judgment becomes training-data ground truth.

Step 1 · The baseline

One labeler, trusted outright

Simplest version: each item goes to exactly one labeler, and their answer is taken as the final, correct label with no further checking. What's the risk?

Requestersubmits data to labelLabelerworks through tasksLabeling APIjob intake
New in this step: Labeling API.

Every item gets exactly one labeler's answer, trusted as ground truth with no verification. What's the risk?

  1. Individual labelers vary hugely in skill, attention, and honesty — some rush, some misunderstand ambiguous instructions, and a small minority may click through carelessly or dishonestly for volume-based pay — none of which a single unverified answer can detect.

  2. With no redundancy or verification, there is no way to distinguish a careful, correct label from a rushed or wrong one — every single labeler's errors flow straight into what the model will later treat as fact.

  3. This risk exists at any scale — even a small, carefully-selected batch can be corrupted by one inattentive labeler with zero verification in place; scale just determines how MUCH bad data accumulates, not whether the underlying risk exists.

With a single, unverified labeler per item, there's no mechanism to catch a careless, confused, or dishonest answer — it becomes permanent, trusted ground truth. Quality control has to be designed in from the start, not bolted on after a model trained on bad labels starts misbehaving.

Why this piece earns its place

The baseline is worth building deliberately, because it is where every labeling effort actually starts: a spreadsheet, a contractor, and a column of answers. The expensive gap in it is not the missing quality control, it is the missing provenance. If the only thing written down is the final answer, then the day you discover a labeler was careless you cannot ask which items they touched. You cannot re-label a subset, you cannot down-weight their work, and you cannot tell a requester whether the batch they already trained on is clean. So even in the naive version, store each answer as its own row — item, labeler, submitted-at — rather than a cell you overwrite, and store the answer exactly as the person gave it rather than a tidied or collapsed version. Raw answers are what let you recompute a result later under a rule nobody had thought of yet; a value normalized at write time has already thrown that away. Every later piece of this design reads those rows. It is the cheap thing to add now and the one thing that cannot be reconstructed afterwards, because the data you would need in order to reconstruct it was never written down.

What the new pieces do

Labeling APIgateway
Accepts labeling jobs and routes work to labelers — starts naive (one labeler, one answer, trusted outright).

Step 2 · Redundancy and consensus

Ask more than one person

Fix Step 1 by sending each item to multiple labelers independently and combining their answers. How many, and what happens when they disagree?

Task Queuerouted + redundantConsensus Engineagreement + QCLabel Storefinal, agreed labels
New in this step: Task Queue, Consensus Engine, Label Store.

Multiple labelers see the same item independently. How should their answers combine into a final label?

  1. Collecting multiple opinions and then discarding all but the first defeats the entire purpose of redundancy — you're back to trusting one unverified labeler, just with wasted extra labeling cost on top.

  2. Requiring agreement across several independent labelers filters out individual mistakes — a lone error gets outvoted, while genuine ambiguity (no majority forms) is a real signal that the item itself may be unclear and needs human review rather than an automated tie-break.

  3. Numeric averaging only makes sense for genuinely continuous answers — for categorical labels (is this spam, which object is in this box) there's no meaningful "average," which is exactly why majority agreement, not averaging, is the standard approach.

Introduce a Consensus Engine: route each item to multiple (typically 3-5) independent labelers via the Task Queue, and use majority agreement to determine the final label, stored in the Label Store. Items where no clear majority forms are flagged for additional review rather than resolved by an arbitrary tie-break.

Why this piece earns its place

Independence is not a property labelers have, it is one the platform has to preserve. Two of them on a shared chat channel, or a queue that shows what has already been submitted, and you are paying for several opinions while collecting one. The common version is a model-generated pre-label sitting in the box: it lifts throughput, and it anchors — most people correct an answer in front of them rather than form their own. If you use pre-labels anyway, and most platforms do, record on the label row whether one was shown and what it said, because an anchored answer and a cold one are different measurements and nothing later can separate them if the row does not. The second thing to get right early is the agreement function. Majority is trivial for a category and undefined for the outputs people actually buy. Two boxes drawn around the same car are never identical, so agreement there is an overlap threshold; a transcript has to be aligned first and compared by edit distance before there is anything to vote on. Each of those is a per-task-type decision, not a platform constant, so build consensus as an interface with one implementation per type. Retrofitting that shape later means changing the queue, the store and the pay calculation together.

What the new pieces do

Task Queueevents
Distributes tasks to labelers — with redundancy (multiple labelers per item) and, later, skill-aware routing for harder tasks.
Consensus Engineservice
Aggregates multiple labelers' answers into a final label, and scores each labeler's accuracy against known-correct gold items.
Label Storedata
The durable output: labels the platform has actual confidence in, not just whatever one person happened to click.

Step 3 · Gold-standard quality checks

Measure accuracy in real time, secretly

Consensus catches disagreement, but a group of consistently WRONG labelers who happen to agree with each other would sail right through majority voting undetected. How do you measure whether a labeler is actually accurate, not just consistent with their peers?

Task Queuerouted + redundantConsensus Engineagreement + QCGold-Standard Setknown-correct items
New in this step: Gold-Standard Set.

How do you measure whether a specific labeler is actually accurate, not just agreeing with equally-wrong peers?

  1. Manual expert re-review is valuable but slow and delayed — by the time a review surfaces a problem, that labeler may have already produced a large volume of bad labels in the meantime.

  2. Because gold items look identical to regular tasks from the labeler's perspective, their performance on them is a genuine, unbiased, real-time accuracy signal — a labeler who's careless or dishonest gets caught on the very next gold item they encounter, not weeks later in a batch review.

  3. Volume says nothing about accuracy, and could even correlate with the opposite — a labeler rushing through many tasks quickly for volume-based pay is a plausible source of LOWER accuracy, not evidence of higher trustworthiness.

Maintain a Gold-Standard Set of items with pre-verified correct answers, seeded invisibly throughout normal task queues. The Consensus Engine compares each labeler's answers on these against the known truth, producing a real-time, continuously-updated accuracy score per labeler — independent of whether their peers happen to agree with them.

Why this piece earns its place

Treat the gold rate as a control loop rather than a constant: high while somebody is new, lower once they have a record, raised again the moment their score moves. That only works if gold is injected per labeler at assignment time. Pre-mix it into a batch instead and every labeler on that batch gets the same rate and the same items, which costs you the per-person knob and, before long, the secrecy too. The failure to plan for is a wrong gold item. One item whose stored answer is incorrect inverts the signal: careful labelers who get it right are marked wrong, guessers are marked right, and the platform starts steering work away from exactly the people it should trust. It surfaces as a cluster of otherwise strong labelers all missing the same item, which is why gold needs its own dispute path — a labeler contesting an item is a bug report, not an excuse. Underneath that sits the circularity this whole step has to escape: gold answers are produced by people too, so they have to come off a different production path from normal labels — adjudicated by named reviewers, with their disagreement recorded — or you are grading labelers against the output of a process you already decided not to trust.

What the new pieces do

Gold-Standard Setdata
Items with a pre-verified correct answer, secretly mixed into normal queues — the platform's real-time labeler-accuracy signal.

Step 4 · Skill-based routing

Not every task suits every labeler

Some labeling tasks require real domain expertise (medical imaging, legal document classification); others are simple enough for anyone. Should tasks be assigned uniformly at random across the whole labeler pool?

RequesterLabelerLabeling APITask QueueConsensus EngineLabel StoreGold-Standard Set
The system as it stands at this step. · swipe to pan the diagram

Task difficulty and required expertise vary widely. Assign tasks uniformly at random to any available labeler?

  1. Uniform random assignment ignores that measured accuracy (from gold-standard checks) often varies significantly by TASK TYPE per labeler — someone excellent at simple binary classification may perform poorly on specialized medical imaging, and vice versa.

  2. Skill-aware routing uses the same gold-standard accuracy data already being collected, broken down by task type, to send difficult or specialized work to labelers who've demonstrated real competence on similar tasks — improving overall label quality without needing to hire an entirely separate specialist workforce for every task type.

  3. Restricting ALL work, including simple tasks, to a small expert pool wastes their specialized time on work that doesn't need it and doesn't scale to real labeling volume — routing should match task difficulty to appropriate skill level, not use one team for everything.

Route tasks using each labeler's measured, per-task-type accuracy from gold-standard performance — harder or specialized tasks preferentially go to labelers with a proven track record on similar work, while straightforward tasks remain open to the broader pool. This uses data the platform already collects, rather than requiring a separate skill-certification process.

Why this piece earns its place

Routing is only as good as the task type it routes on, and that string usually arrives from the requester. If every job lands tagged with one broad type, the router has one bucket, per-task-type accuracy collapses back into a single number, and skill routing quietly degrades into routing by general reliability while the dashboard still reports it as on. So the taxonomy belongs to intake rather than a free-text field, and it has to be stable: renaming a type resets every accuracy history attached to it and the router starts from nothing without anything failing. Routing is also a scheduler, and a scheduler serves more than one objective. Push quality hard enough and the proven labelers for a type become the bottleneck — the specialized queue backs up while the general pool sits idle, and the requester experiences your quality improvement as a missed deadline. Watch queue depth per skill bucket, not just per queue, and alert on the gap between them. Finally, the skill threshold belongs in the job spec, not the platform config: one requester wants only proven labelers on medical imaging and another wants volume at a deadline, and those are two requests, not two deployments.

Step 5 · Active learning

Spend a limited labeling budget where it matters most

Labeling is expensive and budget is finite. With a huge pool of unlabeled data and only enough budget to label a fraction of it, which examples should be labeled first?

Task Queueskill-routed + redundantConsensus Engineagreement + QCLabel Storefinal, agreed labelsGold-Standard Setknown-correct itemsActive Learnerprioritizes by uncertainty
New in this step: Active Learner.

A limited labeling budget can only cover a fraction of the available unlabeled data. Which examples should be prioritized?

  1. Random sampling spends budget uniformly, including on examples the current model already handles confidently — where a new label teaches the model little it doesn't already effectively know, wasting scarce labeling budget relative to a smarter selection.

  2. An example the model already predicts confidently and correctly teaches it almost nothing new when labeled; an example where the model is genuinely unsure is exactly where a ground-truth label resolves real uncertainty and drives the most learning per label spent — this is the core insight behind active learning.

  3. Optimizing for LABELER speed/ease, rather than for how much the resulting label actually improves the MODEL, targets the wrong objective entirely — cheap-to-label and high-information-value are not the same property.

Add an Active Learner: it evaluates the current model's confidence across the unlabeled pool and prioritizes the examples it's most UNCERTAIN about for the next labeling round, rather than sampling randomly. This concentrates a fixed labeling budget on exactly the examples that will improve the model the most.

Why this piece earns its place

Active learning puts a model inside the platform, and a loop with a model in it needs a clock. Uncertainty is computed against one model version, so a round has to pin that version, label against it, retrain, then re-score. Let the cadence slip and a batch chosen before the last retrain is answering a question the current model no longer has — and that failure is invisible, because the labels come back correct, they are simply not the ones you would buy today. The cost that gets left out of the plan is inference across the whole unlabeled pool. It scales with the size of the pool rather than with the budget, which means the bill is set by the data you are not labeling, and it is why scoring normally runs against a sample of the pool or a cheaper proxy model instead of everything, every round. One more piece of state: the evaluation set has to be drawn and frozen outside this loop, from production traffic, before selection starts. Once uncertainty picks the queue, anything measured on the labeled pool is reporting how the model does on its own hardest cases, which is not the number anybody asked for.

  • fixed budgetsame labeling cost
  • uncertainty-rankednot random
  • more model improvementper label spent

What the new pieces do

Active Learnerservice
Decides which UNLABELED examples enter the queue next — prioritizing whatever the current model is least confident about, not a random sample.

Step 6 · Throughput at scale

Millions of tasks, a large distributed workforce

At real scale, tasks need to reach a large labeler pool efficiently, and a labeler who claims a task but never finishes it shouldn't create a silent bottleneck.

RequesterLabelerLabeling APITask QueueConsensus EngineLabel StoreGold-Standard SetActive Learner
The system as it stands at this step. · swipe to pan the diagram

The Task Queue load-balances distribution across the active labeler pool and applies a claim timeout: if a labeler claims a task but doesn't complete it within a reasonable window, it's automatically released back to the queue for reassignment — preventing an inactive or stuck labeler from silently holding up throughput on items nobody else can pick up.

Why this piece earns its place

The timeout is most of the design here, and it is a human number rather than a machine one. Pick a single window and you either yank a dense document out from under somebody still reading it or leave an abandoned claim parked for the rest of a shift. That is why the open task page heartbeats — the queue reclaims on silence rather than on a duration it guessed in advance — and why any fixed fallback window is a property of the task type, not of the platform. Then plan for the late finisher, because reclaiming a task means it can be answered twice. Completion has to be idempotent on the pair of item and labeler. An answer that lands after consensus has closed is recorded and paid, but it does not quietly re-open the vote: a delivered label changes only through an explicit, versioned revision that appends rather than overwrites, so a requester who exported yesterday can see exactly what changed and why. And a released task must never go back to somebody who already saw it, the person who abandoned it included. Two answers from one person are not two independent opinions, and a majority assembled out of them is not a majority.

Step 7 · Align pay with quality

Purely per-task pay incentivizes rushing

If labelers are paid strictly per completed task, what behavior does that incentivize, and is it the behavior the platform actually wants?

RequesterLabelerLabeling APITask QueueConsensus EngineLabel StoreGold-Standard SetActive Learner
The system as it stands at this step. · swipe to pan the diagram

Tie compensation partly to measured accuracy (from gold-standard and consensus-agreement scores), not just raw task volume. A labeler who rushes through tasks carelessly for volume now measurably earns less than one who's careful and accurate — aligning individual financial incentive with the platform's actual goal (correct labels), rather than rewarding a behavior (speed alone) that works against it.

Why this piece earns its place

The moment accuracy sets pay, a statistic becomes somebody's income, and it has to survive that. Scores are noisy and they lag, so pay on a trailing window with a guaranteed base plus a quality bonus, never a bare multiplier — a genuinely hard batch or a thin week cannot be allowed to zero out somebody's earnings while the platform works out whether the dip is real. It also has to be explainable and disputable. A labeler who cannot see why they earned less has no way to improve and every reason to leave, and the ones with options leave first, which selects against exactly the people the scheme exists to keep. The specific hole to close is selection. If accuracy is scored per item and labelers can skip freely, the paying move is to take the easy items and abandon the hard ones — every individual score rises, the aggregate reads as a quality win, and the hardest queue starves. Score accuracy relative to item difficulty, or stop making skipping free. And note what this does to Step 3: the gold rate now moves earnings, so it stops being a knob anyone can retune quietly.

Step 8 · The sharp edges

Gaming the gold set, and evolving guidelines

Two real-world pressures: a sophisticated bad-faith labeler trying to identify and specifically get gold items right while still rushing everything else, and labeling guidelines that legitimately evolve mid-project, potentially invalidating earlier labels made under the old rules.

RequesterLabelerLabeling APITask QueueConsensus EngineLabel StoreGold-Standard SetActive Learner
The system as it stands at this step. · swipe to pan the diagram

Detect gaming attempts via behavioral signals beyond raw accuracy — response-time patterns (suspiciously fast answers on hard-looking items, or a labeler who's slow on gold items specifically and fast on everything else) can reveal an attempt to specifically identify and game known-answer items. For evolving guidelines, version labeling instructions explicitly, and when a schema/guideline changes meaningfully, flag earlier labels made under the OLD version for targeted re-review rather than silently treating old and new labels as equivalent.

Why this piece earns its place

The versioning detail that decides whether any of this works is where the guideline version gets written. Stamp it on every label at write time, taken from the instructions the labeler actually had open. Reconstructing it afterwards from a timestamp fails the moment a rollout is gradual or per-requester, and that is the normal case — nobody swaps a guideline for an entire workforce at one instant. The consequence people miss is that a guideline change invalidates the gold set too. Those known-correct answers were settled under the old rules, so until gold is re-reviewed you are grading labelers against a rulebook they were never given, and the accuracy scores feeding routing and pay drift together while every dashboard stays green. Re-review gold first, labels second. And put the version in the export, so the team training on the batch can drop or down-weight old-rule labels themselves. The platform making that call silently is how a model ends up trained on two definitions of one class with no record that they ever differed.

You did it

You just designed a data labeling platform.

RequesterLabelerLabeling APITask QueueConsensus EngineLabel StoreGold-Standard SetActive Learner
The finished design, end to end. · swipe to pan the diagram

Everything you assembled, in order

  • A single, unverified labeler's answer becomes permanent, trusted ground truth with no way to catch a careless or wrong label — quality control has to be designed in from the start.
  • Multi-annotator consensus catches individual outlier errors that a single labeler's answer never would.
  • Secretly-mixed gold-standard items measure real accuracy in real time, catching correlated group error consensus alone would miss.
  • Skill-based routing sends harder or specialized tasks to labelers with proven track records, using accuracy data already being collected.
  • Active learning prioritizes labeling the examples the current model is most uncertain about, extracting far more model improvement per label than random sampling.
  • A claim timeout on the task queue prevents an inactive labeler from silently bottlenecking throughput.
  • Tying pay partly to measured accuracy, not raw volume, aligns labeler incentives with actual label quality.

Where an interviewer pokes next

Getting the boxes right is the easy half. These are the questions that separate a candidate who drew the diagram from one who has run the thing. Answer each one out loud before you open it.

  1. Why is this different from Synthetic Data Pipeline?

    Synthetic data generation produces training examples PROGRAMMATICALLY — a model (or a bootstrapping process) generates data, with no human judgment involved at the point of creation. A data labeling platform is the opposite: the entire value proposition is HUMAN judgment on real (often ambiguous) examples, which introduces an entirely different set of problems — individual human error, inconsistency between people, incentive design, and quality measurement — that simply don't exist in a purely programmatic pipeline. Both are ways to produce training data, but they solve genuinely different problems.

  2. How many redundant labelers per item is actually the right number — why not always use, say, 10?

    More redundancy catches errors more reliably but costs proportionally more — 10 labelers per item is 10x the labeling cost of 1, which is rarely justified for straightforward tasks with typically high inter-labeler agreement. The right number is usually chosen per task DIFFICULTY: simple, unambiguous tasks might use just 2-3 labelers (cheap, and disagreement is rare and clearly resolvable), while genuinely ambiguous or high-stakes tasks (medical, legal) might justify 5+ to be confident in the consensus. This is itself a tunable parameter, sometimes even set dynamically per item based on how much labelers actually disagree on similar past items.

  3. Could active learning introduce its own bias — could it systematically avoid labeling certain types of examples?

    This is a genuine, known risk: if active learning ALWAYS prioritizes what the model is currently uncertain about, and the model has a systematic BLIND SPOT (confidently wrong about some category it has literally never seen enough of), pure uncertainty-based selection might never prioritize that category, since the model isn't "uncertain" about something it's confidently, silently wrong about. Real active-learning systems typically blend uncertainty sampling with some baseline of diversity/coverage sampling (ensuring the labeled set still spans the space reasonably, not just chases current uncertainty) specifically to guard against this failure mode.

  4. How would gold-standard quality control need to differ for a task with genuinely subjective answers, where there isn't one single correct answer?

    For subjective tasks (rating the tone of a piece of writing, for example), a single fixed "gold answer" doesn't really apply the same way it does for objective tasks (is this a stop sign). The typical adaptation is using gold items with a KNOWN, expert-established consensus or acceptable range rather than one exact answer, and measuring a labeler's accuracy as "within the expert-agreed range" rather than exact match — or, for genuinely subjective work, leaning MORE heavily on inter-labeler agreement (Step 2) as the primary quality signal, since "agrees with many independent others" is a more meaningful measure of quality than "matches one fixed gold answer" when the task itself doesn't have a single objectively correct response.

  5. What's the risk of skill-based routing creating a feedback loop where certain labelers never get a chance to prove themselves on harder tasks?

    This is a real cold-start problem: if routing strictly requires a proven track record on a task TYPE before assigning more of that type, a labeler who's never been given a chance on medical imaging can never accumulate the accuracy history needed to be trusted with medical imaging — a closed loop that locks in the current labeler pool's specialization rather than letting new talent emerge. The standard mitigation is deliberately routing a small, bounded fraction of harder tasks to promising but unproven labelers (perhaps those with strong accuracy on adjacent or generally difficult tasks) specifically to build their track record, rather than routing purely by existing proven history alone.

Check yourself — the answers, and why

Nine steps in, these are the calls you should be able to make cold. Pick one, then read why.

  1. A single, unverified labeler's answer is risky as ground truth because…

    With no redundancy or check, there's no way to distinguish a careful correct answer from a rushed or wrong one.

  2. Gold-standard items work as a quality signal because…

    A labeler can't game a check they can't distinguish from normal work, unlike a review process they might anticipate.

  3. Active learning prioritizes labeling…

    Examples the model already handles confidently teach it little when labeled — uncertain examples carry the most learning value.

  4. Multi-annotator consensus catches individual errors but can miss…

    Agreement alone doesn't guarantee correctness — a gold-standard check catches what pure consensus can't.

  5. Tying labeler pay partly to measured accuracy (not just task volume) is meant to…

    Compensation schemes optimize for whatever they measure — accuracy-linked pay redirects incentive toward the platform's real goal.

How you’d open this design in an interview

Before any boxes: agree what it must do, pin the qualities that shape everything, then build — naming each trade-off as you make it. The walkthrough above is that exact order.

What it must do

Agree on these before drawing a single box.

  • Intake jobs: accept a requester’s pile of unlabeled data and route tasks out to human labelers.
  • Consensus: send each item to several independent labelers and combine their answers by majority agreement.
  • Measure accuracy: secretly mix gold-standard items with known-correct answers into each labeler’s queue and score them in real time.
  • Route by skill: send harder or specialized tasks to labelers with a proven track record on similar work.
  • Prioritize the budget: use active learning to label the examples the current model is most uncertain about first.

The qualities that shape everything

Each one names the mechanism that buys it.

Catch an individual labeler’s error
Each item goes to 3-5 independent labelers and majority agreement decides the final label, so a lone mistake gets outvoted instead of becoming ground truth.
Catch correlated group error, measure real accuracy
Gold-standard items with known-correct answers are secretly mixed into every queue, giving a real-time, unbiased per-labeler accuracy signal consensus alone is blind to.
Match task difficulty to demonstrated skill
Per-task-type accuracy from gold performance routes harder or specialized tasks to proven labelers, reusing data the platform already collects.
Maximum model improvement per label spent
The active learner ranks the unlabeled pool by the current model’s uncertainty, concentrating a fixed budget on the examples that teach the model most.
An abandoned task doesn’t stall throughput
The task queue applies a claim timeout — a claimed-but-unfinished task is auto-released back to the pool for reassignment.
Incentives aligned with quality, not speed
Compensation is tied partly to measured accuracy, not raw volume, so rushing carelessly measurably earns less than careful work.

The trade-offs you say out loud

Senior signal isn’t the boxes — it’s naming what you gave up and why it was the right price.

Majority agreement across 3-5 labelers over trust the first answer received

One unverified labeler is back to square one — no way to tell a careful correct label from a rushed wrong one. Majority outvotes a lone error, and a no-majority item flags genuine ambiguity for review instead of an arbitrary tie-break.

Secretly-mixed gold-standard items over periodic manual expert re-review

Manual re-review is slow and delayed — a labeler produces a large volume of bad labels before it surfaces. Gold items, indistinguishable from real tasks, catch a careless or dishonest labeler on the very next one, in real time.

Skill-based routing on measured accuracy over assign tasks uniformly at random

Random assignment ignores that measured accuracy varies by task type per labeler. Routing reuses the gold-standard data already collected to send specialized work to the proven — no separate specialist workforce required.

Uncertainty-based active learning over a uniform random sample of unlabeled data

Random sampling spends the same fixed budget on examples the model already handles confidently, teaching it little. Prioritizing what the model is genuinely unsure about extracts far more improvement per label spent.

The answer, out loud

What a strong answer to “Design a Data Labeling Platform” sounds like, first question to last trade-off. It is about 7 minutes of talking; the whiteboard and the interviewer fill the rest of the 45. Read it aloud once, then close the page and give it yourself.

  1. 0-3 min

    What this platform actually produces

    I'd start by naming the thing that makes this different from most services. The output isn't a page or a prediction, it's ground truth. Whatever a human clicks here gets treated as objectively correct by every model trained on it downstream. So if a labeler is careless, or misreads an ambiguous instruction, the model learns that mistake exactly, silently, at scale, and nobody finds out until the trained model itself starts misbehaving. That reframes the whole design for me. The interesting problem isn't moving tasks around — that part is a queue. It's proving the judgment coming back is any good, which means quality control has to be first-class in the architecture, not bolted on later.

  2. 3-8 min

    Start from the naive version on purpose

    So I'd draw the naive version first. A requester submits a pile of unlabeled data to a labeling API, the API hands each item to one labeler, and that answer becomes the label. It's a reasonable place to start and it's broken in one specific way: nothing in it can tell a careful correct answer apart from a rushed wrong one. Nothing errors, the batch looks complete, and the bad labels are permanent. Everything I add from here is really answering that same question — how do we know?

    Built in step 1: One labeler, trusted outright
  3. 8-14 min

    Ask several people, independently

    The first fix is redundancy. Send each item to several independent labelers, three to five, and let majority agreement decide the final label that goes into the label store. That turns a lone mistake from something invisible into something outvoted. I'd be deliberate about the no-majority case: I wouldn't tie-break it, I'd route the item for review, because disagreement usually means the item itself is ambiguous, and that's information about my data rather than about my people. And I wouldn't average answers — for a categorical label there's no meaningful average to take.

    Built in step 2: Ask more than one person
  4. 14-20 min

    Measure accuracy, not just agreement

    Consensus has a hole in it, and I'd rather raise it than have the interviewer find it. It catches an individual outlier, but a group of labelers who are all wrong in the same way agree with each other perfectly and sail straight through the vote. Agreement isn't accuracy. So I'd add a gold-standard set: items where we already know the correct answer, seeded secretly through everyone's normal queue so they're indistinguishable from real work. Now I have a per-labeler accuracy signal in real time — somebody who starts rushing gets caught on their next gold item, not in a review weeks later.

    Built in step 3: Measure accuracy in real time, secretly
  5. 20-26 min

    Reuse that signal to route work

    That gold data buys me a second thing almost for free. Break each labeler's accuracy down by task type and it becomes a routing signal. Medical imaging and simple binary classification aren't the same job, and somebody excellent at one can be poor at the other. So harder or specialized tasks preferentially go to labelers with a proven record on similar work, while straightforward tasks stay open to the broad pool. The reason I'd reach for this over hiring a separate specialist workforce per task type is that the platform is already collecting the data — it's one measurement serving two purposes.

    Built in step 4: Not every task suits every labeler
  6. 26-32 min

    Spend the budget where it teaches most

    Then the budget question, which is where the money actually goes. There's far more unlabeled data than budget, so which examples get labeled first? A uniform random sample spends the same money on examples the current model already handles confidently, and a label there teaches it very little. So I'd add an active learner that ranks the unlabeled pool by the current model's uncertainty and feeds the most uncertain examples into the queue. Same fixed budget, considerably more model improvement per label spent.

    Built in step 5: Spend a limited labeling budget where it matters most
  7. 32-36 min

    Keep the queue moving at scale

    Two things make it survive contact with real people, and the first is purely operational. At real scale the queue is load-balancing across a large distributed workforce, and somebody will claim a task, get pulled into something else, and never come back. Without a claim timeout that item just sits claimed — nobody else can pick it up, nothing errors, and the job is quietly slower than it should be for a reason that shows up nowhere. So a claim that goes quiet gets released back to the pool and reassigned.

    Built in step 6: Millions of tasks, a large distributed workforce
  8. 36-40 min

    Pay for the thing you want

    The second is incentives. If pay is purely per completed task, I'm paying for speed and then running quality control to undo it. So I'd tie part of compensation to measured accuracy — scores the platform already computes from gold items and consensus agreement — so careful work earns more than rushing. Any pay scheme optimizes for whatever it measures, so I'd rather measure the thing I actually want.

    Built in step 7: Purely per-task pay incentivizes rushing
  9. 40-43 min

    The sharp edges I would raise myself

    I'd bring up the sharp edges rather than wait to be asked. A sophisticated labeler can work out which items are gold and be careful on exactly those while rushing everything else, and accuracy alone can't see that — so I'd look at behavioral signals like response-time patterns, somebody slow on gold-looking items and fast on the rest. And guidelines genuinely change mid-project. That means versioning the instructions explicitly and flagging labels made under the old ones for targeted re-review, rather than quietly treating old and new labels as equivalent.

    Built in step 8: Gaming the gold set, and evolving guidelines
  10. 43-45 min

    The trade-off, and what I would do next

    To close on the trade-off: every one of these costs money or throughput. Redundancy multiplies the cost of a label. Gold items produce no label at all. Skill routing narrows who is allowed to take a task. I'd expect to tune all three per task difficulty rather than pick one global setting for the platform. With more time I'd close the loop the other way. Everything here judges quality from inside the platform — agreement, gold accuracy, measured skill — but the only real proof it worked is the model trained on the output, so I'd want label quality tied back to how that model behaves.

What this teaches

Learn AI system design by building a human annotation platform like Scale AI or Labelbox — sourcing labels FROM PEOPLE, not generating them programmatically (see Synthetic Data Pipeline for that). An interactive guide covering why a single annotator's answer can't be trusted as ground truth, multi-annotator consensus, secretly-mixed gold-standard items that measure labeler accuracy in real time, skill-based task routing, active learning to prioritize which unlabeled examples are actually worth labeling next, and aligning labeler pay with measured quality, not raw volume.

Key takeaways

  • A single, unverified labeler's answer becomes permanent, trusted ground truth with no way to catch a careless or wrong label — quality control has to be designed in from the start.
  • Multi-annotator consensus catches individual outlier errors that a single labeler's answer never would.
  • Secretly-mixed gold-standard items measure real accuracy in real time, catching correlated group error consensus alone would miss.
  • Skill-based routing sends harder or specialized tasks to labelers with proven track records, using accuracy data already being collected.
  • Active learning prioritizes labeling the examples the current model is most uncertain about, extracting far more model improvement per label than random sampling.
  • A claim timeout on the task queue prevents an inactive labeler from silently bottlenecking throughput.
  • Tying pay partly to measured accuracy, not raw volume, aligns labeler incentives with actual label quality.

Concepts covered

  • The label IS the ground truth — so its quality is everything
  • One labeler, trusted outright
  • Ask more than one person
  • Measure accuracy in real time, secretly
  • Not every task suits every labeler
  • Spend a limited labeling budget where it matters most
  • Millions of tasks, a large distributed workforce
  • Purely per-task pay incentivizes rushing
  • Gaming the gold set, and evolving guidelines
RUN IT YOURSELF

Two annotators who never read an item agree 96% of the time

One skewed labeling queue, five annotators, three of them rushing — and the whole quality-control argument of this page as arithmetic. It prints raw percentage agreement beside the rate that pair would have hit by chance and Cohen's kappa, then settles the final label three ways (plain majority, weighted by gold accuracy, weighted by gold kappa) and scores each against ground truth. Change N_CARELESS from 3 to 2, hit Run, and watch the majority vote come back from the dead.

HOW TO READ THE CODE — 5 IDEAS
  1. The two rushing annotators agree 0.963 of the time — more than the two careful ones at 0.897 — and the middle column says why: 0.962 of it is chance. Two independent raters agree at 1 - 2p(1-p) on their marginals alone, so a reflex that clicks one label 98% of the time is self-consistent for free (step 2).
  2. Careful work spreads labels across both classes — a 5% error rate lands on either side — so the careful pair's chance rate is only 0.808. Raw agreement pays for concentration, not correctness; that is the ranking inversion, and it has nothing to do with the 6% skew.
  3. Kappa subtracts that chance rate and rescales the remainder, so it is 0 in expectation for any two independent raters and never exceeds raw agreement. It reads 0.039 against 0.460 (step 3).
  4. Every weight is measured on the gold items only (step 3), never on the items it then votes on. Weighting by gold accuracy changes nothing — rushing scores 0.90 there against careful's 0.95–0.98, so the ballot stays a head count. The chance correction is the active ingredient, not the weighting (step 4).
  5. Plain majority survives 2 rushing annotators of 5 and falls off a cliff at 3 — recall on the rare class goes 0.85 → 0.05, while the kappa-weighted vote holds at 1.00 → 0.96. A vote is a head count; a weight is not.
CPython · WebAssembly
built so a rushing or careless labeler gets caught by a gold item, not discovered three months later in a broken model — make the calls, spike a bad labeler, run the gauntlet.
Finished this one? 0 / 65 AI System Designs done
NextDesign a Conversational AI Closest AI system design to this one

Explore the topic

See this alongside everything else on the same subject — handbooks, system designs, challenges and tools, in one place.

More AI System Designs