Here’s a tagging trick that flips the usual approach on its head: instead of asking an AI to pick from your existing tags, you let it invent tags freely, then snap those inventions to your real vocabulary afterward. Simon Willison surfaced the technique on his blog, crediting Doug Turnbull with the idea. Willison reached for it while facing a familiar problem: 1,856 tags on his blog and a pile of old posts he never got around to tagging.
The problem is scale. Willison points out that 1,856 tags is “likely too many to feed to an LLM in one go” and ask which ones fit a piece of content. Stuff that many options into a prompt and the model chokes, or you blow your context window. So the fix is to stop treating this as a classification problem at all.
What stands out here is the reframe. You don’t make the model choose. You make it hallucinate, then you clean up after it with math.
Why this works
Classification forces the model to hold your entire tag list in its head. Hallucination doesn’t. You let the model imagine tags that would fit, which it’s genuinely good at, then use vector embeddings to find the closest real tags in your library. The messy creative step and the precise matching step get separated, and each part does what it’s best at.
The steps
- Skip the vocabulary. Don’t send your existing tags to the model. Turnbull’s method tells the model to “output tags without any details of the existing vocabulary.” This is the counterintuitive core of the whole thing.
- Ask the model to invent tags. Prompt it to generate “novel, never seen before” classifications that fit the content. It’s guessing what tags should exist, not picking from a menu.
- Show it the shape of your tags. This is the key tip. Include a few examples of your tag format so the model’s guesses come out in a structure that matches yours. Willison notes the example “help[s] the model make a more useful guess.” Better-shaped guesses mean better matches later.
- Embed the imagined tags. Run the model’s invented tags through a vector embedding model to turn them into numbers that capture meaning.
- Match against your real corpus. Compare those embeddings to your existing tags and pull the closest concrete matches. The hallucinated tags never ship. They’re just a bridge to the real ones you already have.
The example prompt
Turnbull’s prompt, reproduced exactly, shows the pattern in action for a furniture catalog:
Your task is to create novel, never seen before, furniture, home goods, or hardware classification that best fit a search query. Product classifications might look like:
Furniture / Living Room Furniture / Coffee Tables & End Tables / Coffee Tables
Décor & Pillows / Decorative Pillows & Blankets / Throw Pillows
Furniture / Bedroom Furniture / Dressers & Chests
Kitchen & Tabletop / Kitchen Organization / Food Storage & Canisters
School Furniture and Supplies / School Furniture / School Chairs & Seating / Stackable Chairs
Baby & Kids / Toddler & Kids Bedroom Furniture / Kids BedsHere’s the query to generate classifications for: brown coffee table
Notice the hierarchy in those examples. The model sees the “Category / Subcategory / Product” shape and mirrors it. That’s step 3 doing its job.
Why it matters
This pattern isn’t just for blog tags. Any time you’ve got a large controlled vocabulary and want an AI to map content onto it, the same shape applies: product catalogs, support ticket routing, document libraries, content management systems. Stuffing thousands of categories into a prompt doesn’t scale. Generate-then-embed does.
It also reframes hallucination as a feature, not a bug. The thing we usually try to suppress becomes the engine, with embeddings as the safety net that keeps output grounded in reality.
Next steps
If you want to try this yourself: pick a corpus with a big tag list, grab an embedding model, and start with the shape-example trick from step 3, since that’s what makes or breaks the match quality. Test it on a handful of items first and eyeball whether the matched tags actually make sense before running it across everything. Full details and the original write-up are on Simon Willison’s blog.