Writing
From 0.51 to 0.96: Engineering a RAG Pipeline That Actually Tags Content Correctly
An LLM will tag your content, and the output will look great. Confident, plausible, well-formatted, right most of the time you spot-check it. That feeling — “this looks right” — is the single most dangerous thing in applied AI. A result can look right and still be wrong, and you can only defend the parts you’ve actually checked.
We had an automated system tagging a large catalog of content against a hierarchical standards taxonomy — the kind of work a team of experts would otherwise do by hand, item by item, for months. The interesting engineering wasn’t getting a model to produce tags. That’s easy. It was being able to say, with a number, how good the tags actually were — and then move that number on purpose. Almost everything that mattered followed from taking measurement seriously.
You cannot improve what you can’t measure against
The unglamorous first step was building a human-labeled gold standard: a set of items the content experts had tagged by hand, that we could hold every version of the system up against. Without a ruler, “accuracy” is a vibe. You can tune prompts for a week, feel like it’s better, and have no idea whether you improved the system or just changed which items it got wrong.
Building that gold set is tedious and political and gets skipped constantly — and skipping it is why so many LLM features ship on “looks right” and quietly underperform. The ruler came first. Everything after this is only meaningful because we had something to measure against.
Put the decision on rails
Here’s the design choice that made the model’s judgment both better and measurable: we didn’t ask the LLM to decide the tag on its own.
The naive approach is to hand the model an item and ask, open-ended, “which standard does this map to?” Now the model is predicting from the entire universe of possibilities out of its own memory — free to be confidently wrong, free to invent a tag that doesn’t exist, and very hard to evaluate because the failure modes are unbounded.
Instead we put the decision on rails. First retrieve a small set of candidate tags for the item — validated against the real taxonomy, so every option is a real thing. Then the model’s job is no longer “generate the answer,” it’s “judge these specific candidates against the item, using explicit guidance about how the content works.” A constrained choice from a vetted shortlist is a fundamentally easier and more reliable judgment than open-ended recall — and, critically, it’s one you can measure, because the space of possible answers is known and finite.
That two-stage shape — retrieve, then judge — also splits accuracy into two numbers you can measure independently. And that’s where the real diagnosis started.
- Embedding similarity
- Concept-mediated
- LLM-proposed → validated
Accuracy is two numbers wearing a trench coat
End-to-end accuracy factors cleanly:
accuracy = retrieval_ceiling × judge_conversion
- Retrieval ceiling — how often the correct tag is anywhere in the candidate set. A hard cap: if the right answer was never retrieved, no prompt, no bigger model, no cleverer judge can recover it.
- Judge conversion — given the right answer is in the set, how often the judge picks it.
Measured separately, the story changed completely. Our retrieval ceiling was 0.51. For roughly half of all items, the correct tag was never even a candidate — the judge never had a chance. We’d been tuning the judge while the retriever silently capped the whole system at a coin flip. You only see that if you measure the factors, not just the outcome.
Raising the ceiling
Once retrieval is the villain, the work is clear: get the right answer into the candidate set more often. We attacked it with a multi-pathway retriever, each pathway covering the others’ blind spots.
- Embedding similarity, done right. The baseline used a small, general embedding model and embedded the wrong text on the item side — a description of the item’s interface and mechanics rather than the concept it assessed. Embedding the concept instead, using a stronger embedder, and widening the candidate pool all lifted the ceiling.
- Concept-mediated retrieval. Items were annotated with a controlled vocabulary of underlying skills, and those skills map to taxonomy entries — a second, structured path that doesn’t depend on surface-text similarity, useful exactly where embeddings are weakest.
- LLM-proposed candidates. For whole regions of the taxonomy, embeddings were effectively dead. So we let a cheap model propose a few candidate tags from the item — then validated every proposal against the real catalog before it was allowed in. The model knew answers the embeddings hid; validation means it can’t invent one that doesn’t exist. Propose, validate, union.
The reason this went fast: the retrieval ceiling is measurable without the judge. “Was the right answer in the candidate set?” is a set-membership check. We could change the retriever and re-measure the ceiling across the whole evaluation set in minutes, without spending a cent on judge calls — and only run the full pipeline once the ceiling actually moved. Cheap measurements are the ones you run often.
Stacked together, the pathways took the ceiling from 0.51 to 0.96.
The judge, and knowing when to abstain
With a real ceiling, the judge finally mattered — and because its decision was on rails, we could make it disciplined:
- Explicit guidance, not vibes. The judge evaluates each candidate against how the content actually works, following stated rules — not a generic sense of “relevance.”
- Hierarchical partial credit. A wrong tag and a nearly right one (correct concept, wrong grain) are different failures; scoring them the same hides where the system is off by a hair versus off by a mile.
- Confidence bands and abstention. The judge reports confidence, and the pipeline only auto-applies tags above a threshold — below it, it declines and routes to a human. The number that matters is accuracy in the band you’d ship unattended, not accuracy averaged over guesses you’d never trust.
The model is a tool; the fundamentals are data
Underneath all of this is a conviction I bring to every AI project in data and analytics: the model is only as good as the foundation it stands on. A tagging LLM is a tool — a genuinely capable one — but it sits on top of fundamentals a language model doesn’t change, and the most important of those here was the gold standard itself.
Your measurement is only ever as trustworthy as the labels you measure against. A gold set that’s inaccurate, incomplete, or inconsistently applied doesn’t just add a little noise — it can make a strong system look weak or a weak one look fine, and leave you unable to tell which. So the work that mattered most wasn’t in the prompt or the model; it was in making the gold standard accurate and consistent enough that the numbers it produced could actually be trusted.
This is the part teams skip when they’re excited about the AI, and it’s exactly where projects like this quietly break — not because the LLM failed, but because nothing underneath it was solid. Grounding in real, well-curated data isn’t a box you check once. It determines whether the model on top is worth anything at all.
What actually moved the needle
From a coin flip to a production capability — retrieval ceiling 0.51 → 0.96, and a judge converting most of what retrieval now surfaced, for true tagging accuracy of 0.89 — replacing a manual process that took a team of experts months. None of it came from a cleverer prompt. It came from three unglamorous commitments:
- Build the ruler first, and make it accurate. A human-labeled gold standard is the foundation; every number you report is only as good as it is.
- Put the decision on rails. Don’t ask a model to freely decide; constrain it to a validated shortlist and a guided judgment. Easier for the model, and measurable for you.
- Measure the factors, not just the outcome. Decompose accuracy to find the real cap — ours was retrieval, and no amount of judge-tuning would have found it.
An LLM is a tool, and a powerful one. But the fundamentals of good data work don’t disappear because you added it to the stack — they matter more. The output looks right by default; that’s the trap. The work is building the grounded foundation and the measurement that tell you whether it actually is.