I run OneFindMe, an AI product-search front end for
AliExpress. You describe what you want in plain language — in any of 12 languages
— or upload a photo, and it returns the product, similar items, and cheaper
alternatives. It runs entirely on a Cloudflare Worker with an LLM doing the
language work.
This isn't a launch post. It's the three problems that were genuinely hard, the
wrong first solutions I shipped, and what actually fixed them. If you're putting
an LLM in front of a marketplace search API, you'll hit all three.
The stack, briefly
- Cloudflare Workers for the whole API — search, translation, image understanding, caching.
- Claude Haiku for query translation and image identification. I tried Sonnet too, but for this task — short product names and image labels — Haiku was actually the better fit, and it's far cheaper when every search is an LLM call.
- Workers KV as the cache layer.
- A static multilingual front end on Cloudflare Pages.
The core loop is: take a natural-language query in any language → turn it into a
clean marketplace search term → hit the affiliate search API → rank and filter →
return. The interesting failures are all in the "turn it into a clean search
term" step.
Problem 1: the model translated too well
The first version asked the model to "translate this shopping query to English."
It did — beautifully, fluently, and uselessly.
A user searching for a שמלת ערב (evening dress) got back
an elegant formal gown suitable for evening occasions. Grammatically perfect.
It also returned almost nothing from the marketplace, because nobody titles a
product listing in fluent prose. Marketplace sellers write
Women Elegant Evening Party Dress Sexy Backless — keyword soup, not sentences.
The fix was to stop asking for translation and start asking for the 2-3 word
noun phrase a seller would put in a title. The prompt changed from "translate"
to "return the short product name an AliExpress seller would use." Fluency was
the enemy; the model's instinct to produce natural language was exactly wrong for
a keyword search index.
Lesson: when an LLM feeds a keyword system, you don't want its best language.
You want the language of the target index. Prompt for that explicitly.
Problem 2: the model invented category IDs, and they outranked reality
To narrow results, I let the model suggest an AliExpress category ID alongside
the keywords. Category-constrained search returns cleaner results — when the ID
is real.
The model would confidently return category IDs that did not exist. Not
often, but often enough. And a nonexistent category ID doesn't error — it returns
an empty or garbage result set, which then replaced the perfectly good
keyword-only results the same query would have produced. The hallucinated
constraint silently beat the honest fallback.
Two things fixed it. First, a hard allow-list: category IDs the model proposes
are checked against a map of known-good IDs and dropped if unrecognised. Second,
and more important, the keyword search always runs; the category is an
optional refinement layered on top, never a replacement. If the category path
returns nothing, the keyword results are still there.
Lesson: never let a model's optional enrichment silently override your
deterministic baseline. Layer it, gate it, and make the baseline win by default.
Problem 3: cold search was 6-8 seconds, and that was the whole business
An uncached search does real work: an LLM call to build the query, the
marketplace API round trip, ranking, filtering. Cold, that's 6-8 seconds. Users
don't wait 6-8 seconds. The single biggest driver of bounce wasn't relevance —
it was latency on the first search.
The cache helps enormously: every search result is cached in KV for up to 30
days, so a warm search returns in ~200 ms. But you can't cache a query nobody has
run yet, and the first person to search a term pays the full cost.
Two moves cut the perceived wait to near zero without making the search
actually faster:
- Instant bestsellers. The moment a search starts, the UI shows a row of known-good bestseller results for the category while the real search runs behind it. The screen is never empty; the real results swap in when ready.
- Self-warming on unknown terms. When a new keyword is translated for the first time, the translation is saved and the search is pre-cached, so the next person to search that term — and there's almost always a next person — gets the 200 ms warm path.
Neither makes the cold path faster. Both make it invisible. That distinction —
optimising perceived latency instead of actual latency — moved the metric that
mattered more than any relevance tuning did.
Lesson: on a search product, the empty-state-while-loading is a feature, not
a gap. Show something instantly and backfill.
The one I'd warn you about hardest
A subtle one, because it looks like success: don't trust the marketplace's own
"is this product available" signal in isolation. The affiliate API would report
live, purchasable products as gone. Filtering on it alone silently emptied result
pages that should have been full. Availability needs corroboration, not a single
boolean — the same lesson as the hallucinated category, in a different costume:
one unreliable signal shouldn't be allowed to zero out a good result set.
What I'd tell myself at the start
- Prompt for the target system's language, not the user's. A keyword index wants keywords, not prose.
- A model's optional output must never override your deterministic path. Gate it against known-good values; layer it; let the baseline win.
- Optimise perceived latency first. Instant partial results beat a faster spinner every time.
- One signal should never zero out a result set. Corroborate before you filter to empty.
The engine runs in 12 languages now, and every one of those bugs showed up
identically in each. If you're building anything that puts an LLM between a human
sentence and a structured search index, you'll meet all four. Happy to compare
notes in the comments — especially if you've found a better answer to the
cold-search problem than "show bestsellers and pray."
I build OneFindMe — AI product search for
AliExpress by text or image, in 12 languages. It's free; it runs on affiliate
commission at no extra cost to the buyer.
Top comments (0)