Most "AI chatbots" bolted onto stores are a thin wrapper around a general-purpose model — and it shows the moment a customer asks something real. A custom AI shopping assistant is a different animal: grounded in your live catalog, fenced by guardrails specific to your category, measured like a product feature. We run two of them in production — a free-form chat coach and a structured program builder — and this article is the architecture, the failures included.
Two shapes of assistant: chat and guided flow
We ship the assistant in two forms, and the distinction matters more than the model behind them.
The guided flow (our "program builder") asks the shopper a few structured questions — goal, constraints, budget — and composes a plan: a set of real, in-stock products, each with a one-line reason it's in the plan, plus warnings where items conflict. Its output shape is fixed, which makes it easy to guardrail, easy to render beautifully, and measurably good at converting the shopper who arrives thinking "I don't know what I need."
The chat coach handles the long tail: "what's the difference between these two?", "is this okay with my medication?" (see refusals, below), "what's cheaper but equivalent?". It streams responses and runs a function-calling loop — the model can call a dozen named tools (catalog search, conflict check, cheaper-equivalent lookup, cart operations, delivery info, an evidence lookup for health claims) over several rounds before answering.
Both shapes share everything below the surface: the same tools, the same guardrail chain, the same cost ledger. Build that layer once; the UIs on top are cheap.
Grounding: the model never answers from memory
The cardinal rule: the assistant may only reference products that came back from a tool call. Search results, prices, stock, delivery estimates — all fetched live, per conversation turn. The model's job is to reason over those results and explain them in the customer's language; it is never the source of facts. When a tool returns nothing, the honest answer is "we don't carry that" — which, as we argued in the search article, converts better than a confident hallucination anyway.
For health-adjacent claims we go one step further: an evidence-lookup tool retrieves citations from a vetted corpus, and claims that can't cite, soften or drop. The same fail-closed philosophy as our enrichment guardrails — silence over invention.
Our worst assistant bug wasn't a hallucination — it was a data contract. A candidate filter referenced a field that didn't exist in the catalog documents (it belonged to a different schema), so the filter silently matched nothing and the builder had zero products to recommend. The model did its job perfectly over an empty list. Ground truth cuts both ways: the assistant is only as real as the pipeline feeding it, so test the data contract with production-shaped documents, not fixtures.
The guardrail chain, layer by layer
Guardrails work as a chain, not a single filter — each layer catches what the previous one can't see:
- Safety pre-classifier, before any LLM call. A fast, deterministic check against a curated topic list — in our category: eating disorders, advice for minors, medication interactions, pregnancy, banned substances. These short-circuit to a safe, helpful refusal without the main model ever seeing the message. Cheapest layer, highest stakes.
- Scope classifier. A supplements coach shouldn't debug your code or discuss politics. Off-topic requests get a friendly redirect, which also neuters most prompt-injection attempts — an injected instruction can't do much when the whole conversation gets classified out of scope.
- Input sanitation. Strip markup, cap lengths, normalize the weird things people paste.
- Output validation. After generation, before the customer sees it: a claim validator (regulated-phrase list for EFSA compliance, prescription-drug name detection), a brand-leak scanner (don't recommend competitors' stores), and prompt-extraction detection (attempts to make the bot reveal its instructions get caught on the way out, too).
- Privacy plumbing. PII redaction before anything is logged or forwarded to analytics, and a retention clock that purges conversations on schedule. GDPR is a design input, not a legal review at the end.
- Economic guardrails. Per-request cost ledger, per-session rate limits, a capped tool-call loop (a model that wants a fifth round of tool calls is lost, not thorough). An assistant without a cost ceiling is a denial-of-wallet endpoint.
Refusals are a feature — type them
When the assistant declines — safety topic, out of scope, rate limit — the refusal is not an apology paragraph; it's a typed response with a category, and the UI renders each category differently: a safety refusal gets a supportive message and, where appropriate, a pointer to a professional; an off-topic refusal gets a nudge back to what the assistant can do; a rate limit gets a plain "try again in a minute". Two lessons from shipping this:
- Standardize the envelope. We once had two different refusal shapes coming from two code paths, and the frontend handled whichever it was tested against. If a refusal is data, it needs one schema.
- Refusal quality is brand quality. The customer who hits a guardrail is disproportionately likely to be vulnerable, frustrated, or testing you — the three audiences where tone matters most.
Structured outputs as testable contracts
Every assistant response that drives UI — a plan, a product list, an estimate — is generated against a strict schema, and here's the practice we'd evangelize to any team: bind the prompt to its parser with a build-time test. In one of our products, the worked example inside the prompt is fed through the actual production parser during the build; if someone edits the prompt in a way the parser can't consume, the build fails. Prompts drift, parsers drift — a contract test is the only thing that keeps them honest with each other.
Two sibling principles from the same playbook:
- Honest uncertainty beats false precision. Where the assistant estimates anything, it produces a range, and missing data renders as absent — never as a fabricated zero. A wrong number is worse than an honest unknown.
- Backfill conservatively. When output validation finds a gap, deterministic repair fills it only on a confident match. "Grilled chicken breast" can inherit chicken-breast data; bare "chicken" can't. The same rule keeps our product enrichment from papering over gaps with plausible fiction.
Shipping prompts like code: canaries and rollback
Prompt changes alter behavior as much as code changes do, so they ship the same way: a new prompt version goes to a canary — a deterministic fraction of sessions routed by hash — bakes for a day against conversion and quality metrics, and rolls back automatically on regression. No "quick prompt tweak" goes straight to 100% of customers, because the tweak that politely improved one answer has a long history of quietly breaking another.
Evaluation: corrections as ground truth, a stronger model as judge
You cannot improve an assistant you don't measure, and the measurements that work are behavioral:
- Log every recommendation with its inputs (fire-and-forget, never blocking the request), so quality analysis is a query over history, not a vibe.
- Treat user behavior as ground truth. Corrections, edits, abandoned plans, items swapped out of a proposed set — each is a labeled example of the assistant being wrong, collected for free.
- Use a stronger model as a blind judge. Periodically, a more capable model re-answers the same requests without seeing the production answer, and the two are compared. This catches systematic drift a dashboard won't — and it prices the upgrade decision: if the judge barely beats production, the bigger model isn't worth its latency and cost yet.
- Watch calibration, not just accuracy. If answers the assistant marked "confident" get corrected as often as ones marked "uncertain", the confidence signal is decorative — and any UI built on it is lying.
Where this goes: your store inside other people's assistants
The next surface for a shopping assistant isn't on your site at all. The same grounding tools that power an on-site coach — search, product detail, compare, cart — can be exposed via the Model Context Protocol (MCP), so third-party AI assistants can browse and buy from the catalog conversationally, rendering real product cards inside the conversation. We've built this pattern against our own commerce stack: the assistant surface changes, but the architecture in this article — tools as the only source of truth, guardrails at the boundary, typed structured outputs — is exactly what makes a catalog safe to expose to someone else's agent. Teams that invested in grounding get agentic commerce nearly for free; teams that shipped a wrapper bot get to start over.
Key takeaways
- Two shapes, one foundation: a guided flow for the undecided, chat for the long tail — same tools and guardrails underneath.
- The model never answers from memory — every product fact comes from a live tool call, and empty results mean an honest "no".
- Guardrails are a chain: pre-classifier → scope → sanitation → output validation → privacy → cost ceiling.
- Type your refusals — one schema, rendered per category; refusal tone is brand tone.
- Bind prompts to parsers with build-time contract tests, ship prompt changes behind canaries, roll back on regression.
- Evaluate behaviorally: corrections as ground truth, a stronger model as blind judge, calibration checks on confidence.
Frequently asked questions
How do you stop the assistant recommending products that don't exist?
Chat assistant or guided quiz — which converts better?
What guardrails does an ecommerce assistant need?
How do you evaluate it in production?
Guided selling, grounded in your catalog.
The assistant patterns in this article run on the marketplace platform we operate for brands with an audience.
Request early access Try the live program builder →