Synthetic Training Data Is a Supply Chain, Not a Shortcut

Synthetic data is often described as a way to escape the cost and scarcity of human annotation. That description is attractive, incomplete, and sometimes dangerous.

Generating more examples is easy to measure. Generating examples that teach the desired behavior, preserve the right edge cases, comply with the product's data obligations, and improve a held-out user task is the real engineering problem.

The useful mental model is a supply chain. A generated record has a source, a transformation, a verification history, a destination, and a risk profile. Treat it as anonymous text in a bucket and a team loses the ability to answer the questions that matter after a failure: Where did this example come from? What property did it add? Which check allowed it through? Is the same problem now present in a million derived records?

That does not make synthetic data a bad idea. It makes it an engineering system rather than a shortcut.

Begin With the Gap, Not the Generator

The first question is not which model should generate the data. It is what the current dataset cannot represent.

Useful gaps are concrete:

  • a rare tool failure that is unsafe to wait for in production;
  • a document format that customers will upload but the team cannot share externally;
  • a language or phrasing variation missing from an otherwise good intent set;
  • an API workflow whose success and failure states can be simulated;
  • a reasoning task where the expected intermediate work can be checked;
  • a code task that can be compiled and tested against a known contract.

Vague gaps produce vague generation prompts. "Make the model more helpful" usually creates a collection of agreeable-sounding answers with unknown coverage. "Create examples where an invoice lookup returns forbidden, not-found, and temporarily-unavailable, then verify that the UI copy never implies a completed action" is a much better specification. It names an interface, a state space, and a failure condition.

This distinction also helps choose the synthesis method. Not every data problem needs a language model.

Use the Cheapest Generator That Preserves the Invariant

Some tasks have invariants that can be expressed directly. A template or simulation is often more reliable than an open-ended model for these cases.

Templates and procedural generation

Templates work well when a document or task has a known structure: invoices, resumes, contracts, configuration files, mathematical expressions, form submissions, or API request payloads. They give the team control over distributions and make expected answers easier to compute.

For example, a frontend team can generate variations of a checkout state without putting real customer data in a prompt. Each synthetic fixture can carry a known stock state, price, locale, error code, and authorized action. The expected UI and server response become testable properties rather than prose to judge later.

type CheckoutFixture = {
  cart: Array<{ sku: string; quantity: number; unitPriceCents: number }>
  payment: 'approved' | 'declined' | 'requires-action'
  inventory: 'available' | 'changed'
  locale: 'en-HK' | 'th-TH'
}

The generator can create many combinations, but the business rules remain deterministic. If inventory changes after the user confirms payment, a test can assert that the interface requests confirmation instead of silently charging an updated price.

Traditional augmentation follows the same principle. Rotating or cropping an image can preserve its label when the task is image recognition. Replacing a word with a semantic equivalent can broaden text variation when the change preserves meaning. These transformations are only useful when their invariant is actually true. Flipping an image can change the meaning of a road sign. Swapping gendered words can expose a bias, but it can also produce an unrealistic or grammatically broken example. A transformation needs domain review, not just a large batch size.

Simulation and self-play

Simulation is useful when the real world is expensive, private, dangerous, or too slow to sample. It can create rare events for robotics, fraud detection, incident response, or tool-using agents. Self-play can produce long sequences of decisions when the system has a stable objective and feedback signal.

The risk is the same in both cases: the simulator defines the world the model learns. A navigation policy trained in a simplified environment may become expert at the simulation's artifacts. A customer-service agent trained only against another model may learn the generator's conversational habits rather than the ways real people express confusion, frustration, or incomplete information.

Use simulation to increase coverage of a specified state space. Keep production evidence and human-reviewed cases in the evaluation set to detect a gap between the simulated world and the one users inhabit.

Model-assisted expansion

Language models are especially useful for transformations whose correctness can be checked afterward:

  • paraphrasing an approved instruction while keeping its intent;
  • translating a task and back-translating it to check for semantic drift;
  • expanding a compact set of seeds into topic and difficulty variations;
  • generating question-answer pairs from an authorized source document;
  • translating code between languages and testing the result;
  • creating tool-use traces from a simulated API and validating each call.

These methods can create useful breadth from a small, high-quality seed set. They also multiply every mistake in that seed set. A flawed rubric, an overbroad prompt, or a source that was not permitted for training can propagate farther and faster than a single manual annotation error.

Generation Must Respect the Interface It Is Training

For agentic systems, it is tempting to generate a transcript where the model behaves like a person navigating a graphical product. That can be the wrong abstraction.

An API-oriented agent needs examples of API-oriented work: a typed operation, allowed parameters, authorization outcomes, rate limits, failure responses, retries, and when to stop. A human might open a browser, paste an order number, inspect a screen, and click a button. A model should usually call a narrow, server-controlled tool and reason over the result.

Training data should therefore distinguish goals from mechanics:

type UpdateAddressAttempt =
  | {
      userGoal: 'change-shipping-address'
      tool: 'proposeShippingAddressChange'
      result: { status: 'needs-confirmation'; preview: AddressChangePreview }
    }
  | {
      userGoal: 'change-shipping-address'
      tool: 'proposeShippingAddressChange'
      result: { status: 'forbidden' }
    }

The model can learn when to request confirmation or explain a denial. The server decides whether the caller is authorized and whether the actual mutation can happen. A synthetic dataset that blurs those responsibilities can train an agent to narrate an action it did not have authority to perform.

This matters to frontend engineers because interface copy is frequently part of the generated record. Do not create a dataset in which every optimistic state becomes a success message. Include pending, retryable, cancelled, and partially failed states. Teach the assistant to expose uncertainty in a way the client can render honestly, and keep the client responsible for the final state transition.

Verification Is a Pipeline of Different Oracles

No single verification technique applies to every synthetic example. A strong pipeline assigns each claim to the most suitable oracle.

Claim made by the recordStronger verification approach
Generated code runsParse, type-check, lint, execute, and run tests
A tool call has a valid shapeValidate against a schema and simulated API contract
A summary reflects an authorized documentCompare against cited source spans and review unsupported claims
A translated instruction preserves intentBack-translate, compare key constraints, and sample human review
A response follows a preference rubricCalibrated judge, randomized candidate ordering, and adjudicated samples
A dataset helps the productEvaluate a held-out workflow with representative users or tasks

The important word is pipeline. A generated coding example can fail static checks, be revised with the compiler output, pass a unit test, and still violate a product contract. The strongest examples combine deterministic checks with a review of semantic intent.

This pattern is visible in sophisticated code-data workflows: generate a problem, generate a solution, run parsers and linters, execute tests, feed failures back to a reviser, and retain only the examples that pass. The loop is useful because it turns a vague language-model claim into a series of checkable properties. It is not evidence that every passing program is the correct training target.

For JavaScript and TypeScript data, a practical gate might include:

  1. Parse the source and reject syntax errors.
  2. Type-check against the intended public API.
  3. Lint for policy violations the model should not learn.
  4. Run unit and integration tests in a sandbox.
  5. Check dependency, license, and secret-scanning policy.
  6. Review a stratified sample for maintainability and task alignment.

The output of each stage should be stored with the record. That turns verification from an opaque boolean into an audit trail.

type SyntheticRecord = {
  id: string
  source: {
    kind: 'template' | 'approved-document' | 'model-output'
    id: string
  }
  transformation: { generator: string; promptVersion?: string }
  checks: Array<{ name: string; version: string; verdict: 'pass' | 'fail' }>
  datasetVersion: string
}

Avoid treating an AI judge as the final stage in this pipeline. Model judges can be useful for fuzzy criteria, but they have their own biases. They may prefer longer responses, a familiar writing style, or the option displayed first. Evaluate the evaluator using human-adjudicated examples, reverse candidate order where comparison is involved, and monitor whether the judge disagrees systematically with the people responsible for the product.

Synthetic Data Needs Distribution Checks, Not Just Row-Level Checks

A record can pass every local test while the collection becomes worse.

Suppose every generated explanation is factually sound but has the same sentence structure. A model trained on the set may become overly verbose or brittle when a user phrases a request differently. Suppose every simulated failure is retryable. The product may learn to retry when a human escalation is the correct action. Suppose a generator prefers high-probability, ordinary cases. Rare but important cases can disappear from the training distribution even though no individual record looks incorrect.

This is the concern behind model-collapse research: repeated training on model-generated material may overrepresent common patterns and underrepresent less probable events. The evidence is not a simple ban on synthetic data. Some studies show useful results from large synthetic components, particularly in focused post-training settings; others show that mixing real data can reduce risk. The unresolved part is what happens across repeated generations and retraining cycles for a particular task.

That uncertainty calls for controls, not a slogan about the perfect synthetic-to-real ratio:

  • keep independently collected, human-reviewed, or production-derived evaluation data separate from the generator's output;
  • measure distribution by intent, language, length, action, source, and consequence of error;
  • protect rare but high-cost cases with explicit quotas or targeted collection;
  • run ablations that compare real, synthetic, and mixed datasets on the same holdout;
  • limit recursive loops until a later generation has evidence of improvement;
  • inspect examples that are unusually similar, unusually confident, or unusually easy for a judge.

The governing question is whether the dataset is becoming more representative of the required behavior, not whether its synthetic percentage looks fashionable.

Provenance Is a Legal and Operational Requirement

Synthetic does not mean origin-free.

An output may be derived from customer data, an internal document, an open dataset with conditions, or a model whose terms restrict how its outputs can be used. It can also carry hidden contamination risk: a generator may have seen benchmark material, copyrighted code, or content that should not enter a commercial training pipeline. The fact that the final record is newly generated does not erase these questions.

Track lineage through the whole chain:

  • source identity and permitted purpose;
  • generation model, version, provider terms, and prompt template;
  • transformations and verifier versions;
  • reviewers and approval criteria;
  • training run and model version that consumed the record;
  • retention, deletion, and remediation path.

This information is useful long before a legal review. When a benchmark becomes contaminated, a provider changes a usage policy, or a customer requests deletion, lineage tells the team which datasets, adapters, checkpoints, and evaluations are affected. Without it, the organization is left with a plausible answer and no way to prove where it came from.

Distillation Is a Comparison Problem, Not a Copying Strategy

Synthetic data is often used to train a smaller student model from a larger teacher. The traditional goal is appealing: retain most useful behavior with less latency, memory, and serving cost.

But a student that resembles a teacher's prose is not necessarily a student that matches the teacher's capability. It may imitate style while failing on factual accuracy, multi-step reasoning, or an uncommon input. This is why a teacher model's output should be a candidate target, not the sole definition of correctness.

Evaluate the student on task outcomes, not only agreement with the teacher. A student can sometimes exceed the teacher on a target workflow when it starts from a stronger base, has better data, or is trained for a narrower task. Conversely, a compact student may be cheaper and much less reliable on a critical slice. Both outcomes are invisible if the only metric is "does it sound like the teacher?"

The same applies when distilling user-facing behavior. Measure latency, cost, tool accuracy, refusal quality, accessibility of the response, and real task completion. Then choose the deployment based on the product's actual constraints.

Treat Generation as an Auditable Experiment

Synthetic data becomes valuable when it lets a team run a disciplined experiment:

  1. Name a missing behavior or coverage slice.
  2. Choose a generation method whose assumptions fit that gap.
  3. Preserve the source and transformation history.
  4. Verify each record with the strongest available oracle.
  5. Inspect the resulting distribution and deduplicate it.
  6. Evaluate against a holdout that the generator did not create.
  7. Promote only the dataset version that improves the intended outcome without unacceptable regressions.

The process has more stages than "ask a powerful model for 100,000 examples." That is exactly why it can scale responsibly. A supply chain has checkpoints because the cost of a hidden defect rises with every downstream transformation.

Synthetic data is not an escape from dataset engineering. It is dataset engineering with a faster multiplier. The teams that benefit from it are the ones that decide what to multiply, prove what survives the multiplication, and keep enough lineage to correct course when it does not.