Every marketplace starts with the same unpleasant discovery: the product data you ingest from vendors is not the product data you can sell with. Titles are inconsistent, attributes are missing, categories don't match yours, and the description — if there is one — is in the wrong language. Product enrichment is the layer that fixes this, and it is the single highest-leverage place to apply AI in commerce. This is how we do it on a live multi-vendor marketplace, including the parts that went wrong.
What "messy vendor data" actually looks like
Textbook articles about product data enrichment show a tidy before/after. Reality is stranger. Real examples from feeds we've ingested:
- Brands that are numbers. One vendor's platform exported the manufacturer field as an internal option ID, so products proudly announced they were made "by 2822". Any pipeline that trusts fields blindly will publish that.
- Attributes hiding in prose. Serving size, net weight, capsule count — present in the description paragraph, absent from the structured fields where search and filters need them.
- Category schemes that don't align. Five vendors means five taxonomies. "Recovery" for one shop is "Amino acids" for another and "Sport nutrition > Other" for a third.
- Language soup. An Estonian title, an English description, a Russian flavor name — sometimes in the same product.
- Variant chaos. The same protein in six flavors and three sizes arrives as eighteen unrelated products, flooding search results with near-duplicates.
None of this is the vendors' fault — their data was structured for their own shop, not for a unified catalog. But a marketplace lives or dies on catalog coherence: search quality, filters, comparison and trust all sit downstream of this data.
Rule one: deterministic first, AI second
The most important design decision in our enrichment pipeline: never ask an LLM for anything you can compute. Before any AI call, every product passes through a chain of deterministic steps — around a dozen in our production pipeline:
- Normalization — local-language terms mapped to canonical values (the Estonian pulber becomes
powder; a hundred-odd flavor spellings collapse to a controlled list). - Unit parsing — weights, volumes, serving sizes and counts extracted from titles and descriptions with parsers, not prompts.
- Derived math — servings per package, price per serving, price per 100g: computed, never generated.
- Variant grouping — flavor/size families detected and collapsed under one parent, so search shows one product instead of eighteen.
- Conflict detection — a step that compares what the deterministic passes found against what the AI later claims, and flags disagreements instead of silently trusting either side.
This split matters for three reasons. Deterministic steps are free, so they run on every sync. They are repeatable, so a bug fixed is fixed everywhere. And they shrink the LLM's job to the part it's genuinely good at — language — which makes the AI both cheaper and safer.
A useful smell test for any enrichment vendor: ask what happens to "price per serving". If the answer is "the model calculates it", walk away. A model that computes arithmetic will eventually compute it wrong, and a customer comparing €0.42 to €0.57 per serving deserves arithmetic, not autocomplete.
What the LLM adds — and in which languages
After the deterministic pass, the LLM runs with temperature zero and a strict JSON schema, in two focused calls per product:
Call one fills structural gaps and search fuel: product form, flavor, missing serving data (only where parsers failed), goal and diet tags, key ingredients — plus 5–15 search synonyms per product and a scored mapping of the product to customer goals (with a confidence value per goal, so downstream features can ignore low-confidence guesses).
Call two writes the customer-facing content: a proper product description, a form-aware usage guide (capsules get "take with water", powders get "mix with milk or water" — a small thing customers notice), a "who is this for" section derived from the goal scores, ingredient highlights grounded strictly in the extracted ingredient list, an SEO meta description, and a short FAQ.
Crucially, every text field is generated natively in each storefront language — in our case Estonian, English and Russian — in the same structured pass. Not written once and machine-translated: generated per language. The difference shows up in two places. The copy reads like it was written by a local, and the search synonyms match how people actually type. An Estonian shopper looking for plant-based protein types taimne proteiin; a translation engine would never have put that phrase into the index. We cover the search side of this in Marketplace search that converts.
Two more enrichment tricks that earn their keep:
- Label OCR with a sanity gate. A vision model reads nutrition-facts panels off product photos to recover macros the feed never included — but a coherence check (do the macros add up? is the energy value plausible?) gates what gets published. Vision models misread labels confidently; the gate catches them.
- An AI-readable summary at zero cost. Alongside the human-facing copy, a deterministic step assembles a fact-dense summary paragraph per product — built for LLMs and answer engines to consume, generated without any API call. As more shopping starts inside AI assistants, this is the field they quote.
Guardrails: what the model is not allowed to say
In a regulated category, generated copy is a liability program unless you constrain it. Our guardrails live in three layers:
- Constrained generation. For supplements, prompts whitelist EFSA-authorized phrasing — "contributes to normal muscle function", never "boosts", "cures" or "prevents". Diet claims like vegan or gluten-free may only appear when the corresponding data tag exists; the model is never allowed to infer them from the product name. Health-adjacent copy follows an inclusivity rule — audience-specific medical claims get reframed into what the ingredient actually does.
- Post-generation validation. Separate validators re-check the output: FAQs are validated against product specs, descriptions are scanned against a forbidden-claims pattern list. What fails, regenerates or falls back to safe copy.
- Fail closed. When the pipeline can't substantiate something, the field stays empty. An empty "usage guide" is a minor gap; an invented dosage is a real problem. The same fail-closed principle governs our pricing display — under the EU Omnibus rules, a discount badge without a provable prior price simply doesn't render.
Swap the specifics for your vertical — cosmetics claims, electronics safety marks, toy age grading — and the architecture stays identical: whitelist what may be said, validate what was said, and prefer silence to invention.
Classification: making 3,000 products browsable
Enrichment fixes individual products; classification fixes the store. When our marketplace grew from supplements into equipment — at one point nearly half the catalog was gear — vendor categories stopped being navigable. The fix was a customer-first taxonomy (department, activity, product type, use case) applied by an AI classifier across every product, with the crucial property that the taxonomy was designed for shoppers first and the classifier mapped products into it — not the other way around.
The operational lesson: budget for reclassification as a recurring event, not a launch task. New vendors arrive with new category schemes; a marketplace that can re-classify its whole catalog cheaply (see caching, below) can absorb them without a data-cleanup project each time.
Caching and cost: a full catalog pass for ~$1
The naive enrichment design re-sends every product to a large model on every sync, and its costs grow with catalog size times sync frequency. Ours is engineered so the steady-state AI cost is near zero:
- Content-hash caching. Every AI result is cached against a key of model + pipeline version + a hash of the relevant input fields, with a long TTL in durable storage. The same product with the same data never pays twice — across re-syncs, reindexes, even infrastructure rebuilds.
- Change detection that understands relevance. A price change or stock update doesn't touch AI-relevant fields, so hourly syncs skip enrichment entirely. Only content-relevant changes — a new description, a changed ingredient list — trigger a full re-enrichment of that product.
- Right-sized models. Gap-filling and copywriting run on small, cheap models; temperature zero and strict schemas make small models reliable. Large models are reserved for judging and evaluation, not production volume.
- Rate limiting and attribution. A token-budget rate limiter with backoff keeps batch runs polite, and every API call is attributed to the feature that spent it — so "what does enrichment cost us?" is a query, not a guess.
The result, concretely: a full AI enrichment pass across a roughly thousand-product catalog — every product, every language, every field — logs at about one dollar of API cost. With caching, the marginal cost of a routine re-sync rounds to zero. Enrichment being cheap is not a nice-to-have: it's what makes the guardrails affordable, because you can afford to regenerate whatever validation rejects.
Two failures worth learning from
Honest enrichment content should include the misses. Two of ours:
The kimono that became a supplement. A martial-arts uniform from a newly onboarded equipment vendor was enriched with serving sizes and dosage advice — "Judo Capsules", per-serving pricing included. Root cause: the product was enriched before category-aware gating existed, and later re-runs happily reused the cached wrong answer. Two fixes: enrichment profiles now branch by product category (gear never gets supplement fields), and cache entries can be selectively invalidated so a fixed pipeline doesn't keep serving its old mistakes. Lesson: your cache preserves your bugs exactly as faithfully as your successes.
The brand called 2822. The numeric-brand incident from the intro wasn't caught by the LLM — the model dutifully wrote fluent copy about a brand named "2822". Deterministic validation (reject numeric brand values; resolve platform option IDs to labels at ingest) fixed it permanently. Lesson: an LLM will not save you from garbage input; it will eloquently amplify it.
Key takeaways
- Deterministic first, AI second — parse and compute everything you can for free; let the LLM handle only language.
- Generate each language natively, with search synonyms — translation produces copy nobody searches for.
- Guardrails are three layers: constrained prompts, post-generation validators, and fail-closed defaults.
- Cache on content hashes + detect relevant change, and a full catalog pass costs ~$1 instead of scaling with sync frequency.
- Category-aware profiles and input validation prevent the two classic failures: enriching gear as food, and eloquent copy about garbage data.
Frequently asked questions
What is AI product enrichment?
How much does it cost at catalog scale?
Can you trust an LLM to write product content?
Why not just machine-translate the descriptions?
Your vendors' data, made sellable.
Enrichment is one layer of the managed marketplace we run for brands with an audience. See the whole picture.
Request early access Read the marketplace guide →