01 / DefinitionWhat data enrichment actually means
Data enrichment is adding columns to existing rows that the original source never carried. The new value comes from one of two places: an external provider that already knows it (a lookup), or a model that reads the evidence in the row and decides it (a judgement). Everything else about an enrichment stack — pricing, reliability, verification — follows from which of the two it is doing.
The word arrived with the sales stack: append firmographics to a lead list, wave it at a CRM. That heritage still shapes the tooling, which is why most "enrichment tools" are really lookup brokers with a spreadsheet on top. But the interesting growth since LLMs is on the other side: columns that no provider sells because they require reading — is this supplier a manufacturer or a trader; is this review about durability or sizing; does this contract clause deviate from standard. Judgement columns used to cost an analyst-hour per hundred rows. Now they cost a model call — which is exactly why the verification question got urgent.
02 / The splitLookup and judgement fail differently
Treating the two kinds as one "enrichment" step is how stacks end up verifying the wrong thing. They fail in opposite directions:
| Lookup enrichment | Judgement enrichment | |
|---|---|---|
| Source of value | A provider's database | A model reading the row's own evidence |
| Typical columns | Employee count, funding, tech stack, contact info | Category, risk flag, sentiment, normalised name |
| Failure mode | Stale or missing — the gap is visible | Confidently wrong — the error is invisible |
| Verification | Freshness dates, coverage rates | Acceptance checks against declared rules and pinned answers |
| Cost shape | Per record, per provider | Per token — or flat, if an agent computes it |
A missing employee count announces itself as an empty cell. A supplier mislabelled "manufacturer" looks exactly like one labelled correctly. That asymmetry is the entire reason judgement enrichment needs machinery that lookup enrichment never developed.
03 / LandscapeThe 2026 tool landscape, sorted honestly
Three families, three different contracts with you:
- Lookup brokers. Clearbit-style APIs and their aggregators: you send a key (domain, email), they return what they know. Excellent when the value is a purchasable fact; useless for judgement columns. Verify freshness and coverage, not correctness.
- AI spreadsheets. Clay-style canvases where each enrichment is a column formula, some backed by lookups, some by prompts. Superb for interactive prospecting by a person at the keyboard. The contract is interactivity, not production: runs live in the sheet, acceptance is your eyeball, and re-running at ten times the volume re-runs the bill.
- Agent-run production lines. The pipeline holds tables server-side; your coding agent pulls batches, computes judgement columns on the subscription it already runs on, and submits results through acceptance checks. The contract is the inverse of the spreadsheet's: nothing is interactive, everything is accounted. This is the shape Tablize ships, and the shape any team converges on once enriched columns feed something downstream that matters.
Enriching 200 leads for Tuesday's outreach? A spreadsheet is the right tool and this page is not trying to talk you out of it. The line earns its overhead when the enriched column is an input — to a filter, a model, a report — and someone will eventually ask how row 3,187 got its value.
04 / The gapEnriched is not the same as trusted
Here is the uncomfortable arithmetic of judgement enrichment. Suppose the model is right 96% of the time — a good number. On a 5,000-row table that is 200 wrong values, distributed invisibly, each one formatted exactly like a right one. If the enriched column drives a filter ("show me manufacturers only"), every downstream consumer inherits those 200 errors silently.
The fix is not a better prompt. It is the same two-layer acceptance machinery any probabilistic production needs:
- Declare the contract first. Type, allowed values, required-ness — stated
before the first batch, checked mechanically on every submission. A value of
"probably manufacturer"in an enum column should be refused by a rule, not caught by a reviewer three weeks later. - Pin answers for a sample. Take a slice of rows, decide their correct values up front, and hide them inside normal batches. A submission that misses pinned answers is refused wholesale. This catches the failure declared checks cannot see: well-formed, wrong.
With both layers, "the table is enriched" becomes a statement with evidence: every accepted value passed the contract, and the batches it arrived in survived spot-checks. Without them it is a mood.
05 / OperationAn agent-run enrichment workflow
Concretely, with a coding agent driving and the line keeping the books:
# the source table is already on the line, append-only
tablize batch pull supplier-category --size 25
→ 25 rows · contract: {category: manufacturer | trader | unclear}
# the agent reads each row's evidence, judges, submits
tablize batch submit supplier-category ./answers.json
→ 23 accepted · 2 refused (1 enum violation · 1 golden miss)
# downstream reads the consumption face — accepted values only
tablize export supplier-listings --accepted --format csv
Three details to notice. The agent never holds the whole table — batches keep context small at any scale. The refused rows are recorded, not retried into silence; attempt #2 lands on the same ledger as attempt #1. And the export at the end is the point of the exercise: enriched values as real columns, joined to their source rows, consumable by tools that never need to know a model was involved.
06 / FAQQuestions that come up
Is enrichment the same as cleaning?
No — cleaning corrects or removes what is already there; enrichment adds what never was. They compose in one direction: clean first, then enrich, because enriching a dirty table multiplies the cost of every duplicate and malformed row already in it.
Lookup API or LLM — how do I choose per column?
Ask whether the value exists as a purchasable fact. Employee count: yes, buy it. "Is this supplier actually a manufacturer": no provider knows; a model must read and judge. Columns split cleanly once you ask the question — and mixed stacks, lookup for facts plus model for judgement, are the normal end state.
How accurate is LLM enrichment?
Column-dependent, typically 90–98% on well-specified judgement tasks — which is precisely why acceptance machinery matters: at 5,000 rows even 96% means 200 silent errors. Accuracy is a property to measure per column with pinned answers, not a number to take from a vendor page (including this one).
How do I keep enriched columns from going stale?
Enrichment is not an event, it is a standing edge. New rows arrive and need the same columns; sources change and old values age. A line that re-pulls un-enriched rows as they land keeps the column continuous; a one-off script leaves you re-running the project every quarter.
What does it cost at volume?
Per-token APIs price judgement per row, forever. The batch-pull pattern moves computation onto the flat-rate subscription your coding agent already runs on — the marginal cost of enriching another thousand rows becomes wall-clock time, not a new line item.
Adjacent reading, same production-line lens: