Verification is the part people skip, and skipping it is how synthetic tasks corrupt scores. Four checks, in this order, each cheaper than the next.
| Check | Cost per item | Catches | Cannot catch |
|---|
| Rule filters (code, regex, schema) | Near zero | Placeholders, leaked spec language, banned phrases, broken JSON, wrong length | Unrealistic tone, wrong policy |
| Real-log pattern checks | Low | Vocabulary drift, impossible context, lengths and sentiment outside observed ranges | Subtle policy errors |
| Human review on a sample | High | Everything the first two miss, including unverifiable commitments | Rare reviewer disagreement |
| Score comparison on held-out real set | Medium | Bias that inflates or deflates the trained system's score | Individual bad items |
Rule filters first. Deterministic checks belong in code, not in a model: valid schema, no leftover template tokens, the hard constraints present as substrings or regexes, sentence length within the range you observe in real traffic. Google's framework calls code-based evaluations the cheapest and most deterministic layer and recommends them for exactly this kind of checkable failure Google Cloud. Expect this step alone to reject a meaningful share of raw candidates, mostly for missing a constraint clause.
Then real-log pattern checks. This is the step that separates synthetic tasks you can trust from synthetic tasks that read like a language model wrote them. Compare each surviving candidate against the distribution of the real slice it is meant to represent: average message length, punctuation habits, presence of filler words, how often the customer mentions an order number, how often anger shows up as profanity versus clipped sentences versus threats to leave. If your fake angry customers all write complete grammatical sentences with an exclamation mark, and your real ones write three words in lowercase, the model will learn nothing useful and the slice score will be meaningless. A simple check: embed candidates and real items, and flag any candidate whose nearest real neighbor is farther away than the 95th percentile real-to-real distance.
Then human review on a sample. Sample 20 to 30 verified candidates per slice and have a domain expert label them as realistic or not, and as correctly specified or not. This is where you find the subtle killer: a candidate that satisfies your stated policy but makes a commitment your business would never honor. LLM judges agree with human reviewers about 85 percent of the time, which is good for monitoring at scale, but that also means roughly one in seven judgments disagrees with a careful human, so a judge alone is not a sufficient gate for admitting new golden items Confident AI. Use the judge to triage volume and humans to settle the boundary.
Then the score comparison. This is the decisive test and it is the one most teams never run. Take your held-out real set (real items, never used in tuning, never touched by generation). Score your system twice: once on real-only items, once on a combined set that includes the new synthetic items. If the combined score moves by more than a couple of points in either direction, your synthetic items are not neutral replacements for the real slice. They are easier, or harder, or they encode the generation model's stylistic biases. Investigate before admitting them.
A worked example with numbers makes the risk concrete. Say your real-only golden set scores 0.82 on your correctness judge. After adding 120 synthetic items for angry refunds, the combined set scores 0.61. That 21-point drop is not new information about your system; your system did not change. It is a measurement artifact: the synthetic angry cases, generated from complete specs with explicit hard constraints, are systematically harder than the real angry cases in your logs, which were often vague and quickly resolved. Admitting them into the headline score would make every future release look like a regression.