Blog/Web engineering

LLM product data enrichment: attributes, evidence and review

Grounded LLM enrichment for PIM attributes and copy: source spans, schema-checked output, confidence routing, provenance and cost per 1,000 SKUs.

··12 min read

  • Product data enrichment
  • PIM
  • Structured outputs
  • Human review
  • Provenance
Cover diagram of a product data pipeline: source documents, grounded extraction, confidence routing and a human review queue.

Key takeaways

  • Extraction is not generation: every value written to the PIM must point to a span in a source document, and a value without one is not written.
  • Constrain the output with a schema, then check numeric ranges and units in your own code, because the structured-output subset cannot express them.
  • Route each field, not each SKU, by confidence and grounding, and store provenance with every written value so any claim traces back to its sentence.
  • Evaluate per attribute on a frozen golden set, and run every prompt or model change against it before it reaches production.
  • Token cost is the smallest line item; review time and the compliance rules for AI-written catalog text decide whether the pipeline pays off.

Listen to this article

0:000:00

LLM product data enrichment means using a language model to create or lift master data in the PIM: attribute values pulled out of supplier PDFs and datasheets, short and long descriptions for each channel, SEO titles, and tone or language variants. Done carelessly, it produces fluent text that nobody can check. Done as a pipeline, it produces values that each point back to the sentence they came from, plus a review queue for everything else.

This article is the engineer’s version: grounding by construction, schema-constrained output, confidence routing, per-field provenance, field-level evaluation against a golden SKU set, and the cost and compliance boundaries that decide whether the pipeline is worth running. LLM-based PIM data quality covers classification, normalization and deduplication, and supplier data onboarding covers getting price lists and PDFs into the system. This post starts after that intake, where the question is what gets written into the product record and how anyone can tell it is right.

What does LLM product data enrichment cover?

It covers attributes and text that the catalog lacks, or has in an unusable form: technical values such as dimensions, voltage or material, which often sit in a PDF datasheet rather than in the ERP; descriptions in several lengths per channel; SEO titles; and translation or tone variants. It does not cover prices, stock, or anything the ERP owns. Those values come from a system of record, and a model that writes a price into a product text has created a second, unauthoritative price.

  • Attributes: values extracted from the supplied documents, each with a unit and a source.
  • Copy: short and long descriptions, bullet points and SEO titles, generated only from approved attributes.
  • Variants: translations and tone rewrites that keep the same facts. The mechanics of translation are in the LLM translation pipeline.

Before any model runs, a readiness gate decides which SKUs are worth enriching. A SKU is ready when it has a manufacturer part number, a category from the classification, at least one source document that actually contains the attributes, and a channel that will display the result. Skipping the gate produces text nobody can verify, and that is the most expensive kind of text to fix later.

Why extract from evidence instead of generating?

Extraction is not generation. The rule that makes enrichment safe is that every value the pipeline writes must map to a span of text in a source document, and a value without one is not written. Google’s open-source LangExtract library makes this its central guarantee: each extraction maps to an exact character interval in the source, so a reviewer can see it highlighted in place. Its README is candid about the failure mode the rule guards against, which is that models may occasionally extract content from few-shot examples rather than from the input. Ungrounded extractions come back with a null interval, and the documented filter drops them. The library is Apache-2.0 licensed and, per its README, not an officially supported Google product (LangExtract).

Anthropic’s guidance on reducing hallucinations applies the same idea at the prompt level. Allow the model to say that it does not know. For long documents, which its guidance puts above 20,000 tokens, have it extract word-for-word quotes first and reason only from those quotes. Then add a verification pass in which every claim must find a supporting quote or be retracted (Anthropic documentation). Quote-first costs tokens, and it is worth it, because a quote is something a reviewer can check at a glance. A correct answer is often the empty value: if the document does not mention an attribute, the output should lack it, not guess it.

How is the enrichment pipeline built?

The pipeline has five steps: ingest the source documents, extract candidate values with their spans, validate the output against a schema, route each field by confidence, and write the accepted values to the PIM with provenance. Re-running it on the same inputs should produce the same records, so every write is keyed on the SKU, the attribute and a prompt version, and a re-run replaces the earlier candidate rather than appending to it.

Enrichment pipeline with a golden-set gateFive boxes from left to right: sources, grounded extraction with character spans, schema validation, confidence routing with three tiers, and the PIM write with provenance. A dashed arrow runs from a separate box, golden-set re-evaluation, back up to the extraction step, so a prompt or model change triggers a re-run on the golden set before anything reaches production.SourcesPDFs, feedsExtractchar spansValidateJSON SchemaRoute3 tiersPIM writeprovenanceGolden-set re-evaluationgate before any prompt or model changeprompt or model change
The enrichment pipeline: every write carries provenance, and a prompt or model change re-runs the golden-set evaluation before it can go live.

The output schema does most of the policing. Structured-output modes in OpenAI and Azure follow a supplied JSON Schema in strict mode and return a refusal field when a request cannot be satisfied. The supported subset is narrower than full JSON Schema: it bans constraints such as pattern, format, minimum, maximum, minItems and maxItems, requires every property to be listed, needs additionalProperties set to false, and caps a schema at 100 properties and five nesting levels (Microsoft Learn). Check numeric ranges and unit patterns in your own validator after extraction. Structured outputs also do not work with assistants tooling or bring-your-own-data scenarios, and parallel function calls must be disabled if the enrichment step also calls tools.

{
  "type": "object",
  "properties": {
    "attribute": { "type": "string", "enum": ["voltage", "ip_rating", "weight_kg"] },
    "value": { "type": "string" },
    "source_quote": { "type": "string" },
    "confidence": { "type": "string", "enum": ["high", "medium", "low"] }
  },
  "required": ["attribute", "value", "source_quote", "confidence"],
  "additionalProperties": false
}

Keep each attribute as its own small object rather than one wide record per SKU. A failed field then fails alone, and the routing decision can be made per field.

Provenance is the record of where a value came from. For each written attribute, store the value, the source document, the character interval of the quote, the model, and a hash of the prompt. A reviewer or auditor can then go from the product page straight to the exact sentence in the datasheet. The record below is illustrative, not real product data.

{
  "sku": "SKU-1001",
  "attribute": "max_pressure_bar",
  "value": "16 bar",
  "provenance": {
    "source_doc": "datasheet-rev3.pdf",
    "char_interval": [2184, 2199],
    "model": "<model-id>",
    "prompt_hash": "sha256:9c1e...",
    "confidence": "high"
  }
}

How does confidence routing decide what a person sees?

Confidence routing sends each field to one of three outcomes. High confidence with a verifiable quote is approved automatically, medium goes to the review queue, and low or ungrounded values are discarded or shown to a person together with their source. The decision belongs to the field, not the SKU. A product can have twelve attributes auto-approved and one waiting for review, and the interface should show that split rather than hiding the one uncertain value behind an “approved” badge.

Two-tier confidence routing per fieldA cheap batch model reads every field and feeds a per-field confidence check. High confidence goes to auto-approve. Medium confidence goes to a stronger model, and low confidence goes straight to the human queue, which shows the source snippet. Fields that stay low after the stronger model also go to the human queue.Cheap batch modelfull catalogConfidence checkper field, not per SKUAuto-approvehigh confidenceStronger modelmedium: re-check the fieldHuman queuelow: source snippet shownhighmediumlowstill low
Two-tier routing: the cheap model covers the full catalog, and each field, not each SKU, gets its own routing decision.

The two-tier variant keeps cost down. A cheap batch model runs over the full catalog. Only fields marked low or medium escalate to a stronger model, and only what is still uncertain after that reaches a human. I use the same shape in my own work: the jev-decide skill I use returns typed decisions with a confidence value and routes low-confidence cases to a person, which is the pattern an attribute review queue needs.

How does enrichment get into Pimcore?

The write path should go through the PIM’s own API surface, not a database shortcut. Pimcore’s Datahub is the documented integration layer: a GraphQL API by default, several endpoints per use case, configuration to transform the data, and workspace and schema definitions that restrict what each endpoint exposes. For an enrichment service that restriction is useful, because it lets you expose exactly the attributes the service may write and nothing else (Pimcore Datahub).

Pimcore also ships automation inside the PIM. Its Copilot actions run asynchronously in the background, can have several steps and user inputs, and are triggered manually or by a scheduler. A job overview lets operators track, abort and restart long runs (Pimcore Copilot). For a bulk backfill of a catalog that job view matters more than the model, because a run that fails halfway through must be restartable.

Use batch APIs for the bulk pass and asynchronous per-object jobs for the daily flow. Where a batch rate is published, the table below shows it at half the standard rate, but batch jobs are asynchronous, so a new SKU waiting for its description should take the online path. Name the owners as well: who approves a review item, which attributes lock after approval, and what re-runs when a prompt version changes. Those are workflow decisions, and the PIM is where they get enforced.

The read side, where the same catalog answers customer questions, is covered in RAG over product catalog data, and the ERP boundary in Pimcore and ERP delta sync.

What does enrichment cost per 1,000 SKUs?

Token cost is the smallest line item, but it is the one you can calculate exactly. Assume 2,500 input and 500 output tokens per SKU, so 1,000 SKUs are 2.5 million input and 0.5 million output tokens. The cost is input tokens times the input price plus output tokens times the output price, divided by one million. Prices are as of October 2026: Google’s from its Gemini API pricing page, and the Claude and GPT rates as listed on OpenRouter, not the vendor pages.

ModelInput $ per 1M tokensOutput $ per 1M tokensStandard, per 1,000 SKUsBatch, per 1,000 SKUsRate source
Gemini 3.5 Flash-Lite0.302.50$2.00$1.00Google pricing page
Gemini 3.8 Flash0.753.75$3.75$1.88Google, through 31 Dec 2026
Claude Haiku 5.50.100.50$0.50$0.25OpenRouter
GPT-5.6 Luna0.201.20$1.10$0.55OpenRouter
DeepSeek V4.1 Flash0.06480.144$0.23not listedOpenRouter

Worked example: Gemini 3.5 Flash-Lite in batch mode is 2.5 × $0.15 plus 0.5 × $1.25, which is $1.00. The same job on Claude Haiku 5.5 at standard rates is 2.5 × $0.10 plus 0.5 × $0.50, which is $0.50. Substitute your own token counts, since they are the assumption that moves the answer most. A three-pass extraction over the same document roughly triples the input side: if each pass sends the full 2,500 input tokens and the output stays at 500, Claude Haiku 5.5 at standard rates goes from $0.50 to $1.00 per 1,000 SKUs. Gemini 3.8 Flash is listed at $0.75 and $3.75 per million tokens through 31 December 2026, and Google lists $1.50 and $7.50 from 1 January 2027.

The token bill is rarely the real cost. Review time is. If r is the share of fields routed to review and t is the minutes a person needs per reviewed field, labour per 1,000 SKUs is 1,000 × r × t minutes, before any rework. Halving the review share usually buys more than switching to the cheapest model, which is why routing thresholds deserve as much tuning as the prompt.

How do you evaluate enrichment and run the review queue?

Evaluate on a frozen golden set of SKUs with human-verified values, scored per field: precision, recall and exact-match accuracy for each attribute, plus a check that every accepted value has a quote that resolves to its source. Averages hide regressions in one attribute, so report per attribute. Run every prompt or model change against the golden set before production, and a regression on any attribute blocks the change. The document-extraction literature helps with vocabulary: DocILE, for example, has 6,700 annotated business documents across 55 annotation classes, plus line item recognition. Its documents are invoices and orders rather than industrial datasheets, and I did not find a verifiable published accuracy figure for LLM extraction from datasheets. Set targets from your own golden set, not from a paper (DocILE).

  • The source is visible: the highlighted quote sits next to the proposed value, not behind a link.
  • The diff is visible: the current PIM value and the proposed value sit side by side.
  • Rejection has reasons: one click for “not in source”, “wrong unit”, “wrong variant” or “ambiguous”, so the reasons feed the next evaluation.

Rejections are evaluation data for the golden set and the prompt, not just closed tickets. Route each rejection reason back into the evaluation so the same error stops recurring.

Which rules apply to AI-written catalog text?

The short answer is that it depends on what the text is and where it is published. This post is not legal advice. For catalog text in the EU, three sets of rules matter, and the specifics belong with counsel.

EU AI Act, Article 50, applies from 2 August 2026. Its text-disclosure duty in paragraph 4 covers AI-generated text published with the purpose of informing the public on matters of public interest. It does not apply where the content has undergone human review or editorial control and a natural or legal person holds editorial responsibility, and that exemption has conditions. Catalog copy for your own shop is not automatically text published to inform the public on matters of public interest, but that classification is a judgment for counsel, not a blanket conclusion (Article 50).

The Unfair Commercial Practices Directive, as amended by Directive (EU) 2024/825, applies from 27 September 2026. It adds per-se banned practices, including generic environmental claims without demonstrated recognised excellent environmental performance, and claims based on GHG offsetting (EUR-Lex). An LLM that “improves” a description by adding “eco-friendly” or “climate neutral” has created a legal problem, not a better sentence. Put the prohibition in the prompt and in the validator: a banned-phrase list is a cheap guard, and the attribute schema should have no green-claim field unless a source document supplies one.

Search quality is the third. Google’s spam policies name the risk directly as scaled content abuse: using generative AI or similar tools to generate many pages without adding value for users, and translating or rewording content to mass-produce pages. The consequence can be site-level demotion or a manual action. As of October 2026 the policy names the risk directly, so check the current wording before publishing at scale (Google Search Central). Enrichment that adds verified attributes adds value; enrichment that multiplies thin pages from the same attributes does not.

When should you not use an LLM for enrichment?

Do not use it when the source documents do not contain the value. The model can only ground what is written down, so a missing spec should be a gap in the report, not an invented number. Avoid it for safety, medical or compliance specifications, where a wrong value has consequences you cannot review in time. Skip it for very small catalogs, where a person writes the copy faster than the pipeline can be built and evaluated, and when a cleaner ERP or supplier feed would solve the problem first. These are trade-offs rather than prohibitions, and the evidence test decides most of them.

Before go-live, check these items:

  1. A frozen golden set with targets per attribute, agreed with the people who own the catalog.
  2. A grounding check: no write without a quote that resolves to a source interval.
  3. Schema and range validation in your own code, not only in the model’s output mode.
  4. Routing thresholds per field, tuned on the golden set, with a review queue that shows source and diff.
  5. Provenance stored with every written value, and a rule for what re-runs on a prompt or model change.
  6. Cost per 1,000 SKUs calculated with your token counts and checked against the labour formula above.
  7. A compliance review of AI disclosure, environmental claims and search policy, signed off before the first public batch.

If you are building this for a B2B catalog, see my B2B e-commerce work. An enrichment path is only as trustworthy as the evidence it reads, so start there.

Sources

  1. Google LangExtract, GitHub README (v1.6.0)
  2. Anthropic: reduce hallucinations
  3. Microsoft Learn: Azure OpenAI structured outputs (updated Aug 2026)
  4. DocILE: document information localization and extraction (ICDAR 2023)
  5. Pimcore docs: Datahub
  6. Pimcore docs: Copilot
  7. Google Search Central: spam policies
  8. EU AI Act, Article 50 (artificialintelligenceact.eu)
  9. EUR-Lex: Directive (EU) 2024/825 amending the Unfair Commercial Practices Directive
  10. Google AI for Developers: Gemini API pricing
  11. OpenRouter: models API (rates as listed, Oct 2026)

Frequently asked questions

How do you stop an LLM from inventing product attributes?

Require every value to carry a quote that resolves to a character interval in the source document, and drop anything that does not. Allow an empty value when the document does not mention the attribute, and run a verification pass in which each claim must find a supporting quote or be retracted.

How much does LLM enrichment cost per 1,000 SKUs?

At 2,500 input and 500 output tokens per SKU, the token cost is about $0.23 to $3.75 per 1,000 SKUs at standard rates in the October 2026 listings used here. Batch rates roughly halve the figure where a batch rate is published. Review time usually costs more than the tokens.

What is confidence routing in product data?

Each field goes to one of three outcomes: high confidence with a verifiable quote is approved automatically, medium confidence goes to a review queue, and low or ungrounded values are discarded or shown to a person with their source. The decision is made per field, not per SKU.

Does the EU AI Act require labels on AI-written product text?

Article 50 sets a text-disclosure duty for AI-generated text published to inform the public on matters of public interest, with an exemption where human editorial responsibility applies. Whether catalog copy falls inside it is a question for counsel, not a blanket answer.

Can Pimcore receive LLM-generated attributes?

Pimcore Datahub is the documented integration layer, and its endpoints can be restricted by workspaces and schemas, so an enrichment service can be limited to the attributes it may write. Pimcore Copilot can also run background jobs with a job overview to track, abort and restart them.

Sounds like what you need?

Tell me about your project or role – I’d love to hear from you.