← Hussain Abuwala

Metadata Enrichment

How IBM watsonx BI understands a dataset, rebuilt twice. IBM, 2024–2026.

IBM watsonx BI answers business questions about a dataset in plain language. Before it can do that, it has to understand every column: a readable name and description, what the column represents (a city, a date, a state), and how it should be used: as a number to add up or average, a category to group by, or an identifier. Producing that understanding is metadata enrichment.

I worked on both versions. The first was built around an existing enrichment service from another IBM product, with our own processing on top. The second replaced that service with our own LLM pipeline.

Java · Node.js · TypeScript · LLMs · Embeddings · RabbitMQ · Kubernetes

Why it matters

Almost every feature of the product reads what enrichment produces:

What enrichment decidesWhere it shows upIf it is wrong
Readable names and descriptionsAnswers, chart labels, searchUsers see cst_unt instead of “Cost per Unit”, and search cannot find the column
What a column holds: a city, a date, a stateFinding the right column for “sales by state”; time on a chart’s x-axis“Jan 2020” is treated as plain text, so there is no trend over time
Number or categoryWhich columns are added up and which are grouped; which chart is suggestedPostal codes get added up, and the wrong chart is suggested
Sum or averageTotals in answers; which numbers can share a chart“Total price per kg”, a confident wrong number
How strongly columns relate to each other“Why” questions, such as why revenue fell: finding the columns most likely to explain itThe explanation points at a column that has nothing to do with it, such as an ID or a budget column
Prepared sample valuesMatching the words in a question to the values stored in the data“New York” does not find “NYC”, so the filter is missing and the answer covers everything

A mistake in enrichment does not stay in enrichment. It shows up as a wrong answer, a wrong chart, or a search that finds nothing.

The problem

The first version had three problems: it was expensive, at $5.32 to enrich one data asset; it was slow; and it misread many columns. Most accuracy problems came from two sources: matching values against fixed lists and patterns, and relying too much on column names.

ColumnWhat it holdsFirst versionCorrect
zip5, plz_deUS and German postal codesa number to add upa category
on_time_flg0 or 1a number to add upa category
salary_bandsalary tiersa number to add upa category
x_coordx-axis coordinatesa number to add upa category
price_per_kg, speed_mphrates per unitsummedaveraged
city_codeNYC, LA, CHInot recognizeda city
opening_dateJan 2020, Feb 2020not recognizeda date
region_nameUS statesa country or regiona state

These matter because they change answers. Adding up postal codes, or summing prices per kilogram instead of averaging them, gives a user a confident, wrong number.

The solution

A model that reads meaning, not just names

The second version uses an LLM that understands what values mean. It knows NYC is a city and a price per kilogram is a rate, without a list or a pattern for either. It looks at more than the column name: the data type, sample values, and how many distinct values the column has. That is how it tells postal codes from quantities, even though both are numbers.

Smaller prompts instead of one large one

A model often does better when a large task is split into several smaller prompts, each asking for one clear decision. Deciding how a column should be used works this way: simple rules settle the obvious columns first, and the rest go through a few narrow questions in turn.

Wide tables

Some tables have hundreds of columns, too many to handle well in one request. They are split into batches that keep neighbouring columns together. A few batches run at a time, with a short pause between groups so the model service is not overloaded. A one-paragraph summary of the whole table, written from the column names alone, goes with every batch, so each batch knows what the table is about.

Reliable output

Respecting people’s edits

Users can correct the names, descriptions and other details enrichment produces. Enrichment never overwrites a value a user has already accepted or defined.

Rolling it out safely

The first version was already serving customers, so the second could not simply replace it.

Results

First versionSecond version
Cost to enrich one data asset$5.32$0.009
Speed1×6.5×
Accuracy—above 90%

Cost fell 99.8%, which meant $19K in monthly customer savings. Accuracy is measured on a benchmark of test tables from many domains, with the correct answer written down for every column. Each step is scored on its own, and the benchmark is rerun as a regression check after changes.