Skip to content
NewNeenOpal Earns ISO 42001 Certification for AI GovernanceKnow More
All blogs

The Hard Part of an AI Shopping Assistant Isn’t the AI

6 min readBy Nikunj Mistry, Etika Sharma

The Hard Part of an AI Shopping Assistant Isn’t the AI

Ask most teams what makes a retail chatbot difficult and they’ll talk about the model: getting it to understand intent, keeping responses on-brand, stopping it from making things up. Having built one on Amazon Connect, the model turned out to be the least of it. The language part largely works now. What takes the time is everything around it: deciding what the assistant is allowed to know, proving who it’s talking to, and making it fail in ways that don’t embarrass you.

Here’s what we’d tell anyone starting the same build.


The assistant comparing two air conditioners from live catalogue data

Draw the knowledge boundary before you write any prompt

The first design decision is also the one that causes the most damage if you get it wrong: which questions get answered from documents, and which get answered from live data.

The test is simple. Does answering require knowing who is asking?

“How long is the warranty on a refrigerator?” has the same answer for everyone. That belongs in a knowledge base (indexed documents the assistant retrieves from), grounded so it quotes policy rather than improvising it.

“Is my refrigerator still under warranty?” is a different question entirely. It needs the customer’s purchase date, the product they actually bought, and today’s date. That belongs to a tool: a function the assistant calls that reads the record and computes an answer.

Get this backwards in one direction and you build a bot that asks people to log in before it will read out a returns policy. Get it backwards the other way and the assistant invents an order status. Both are bad; only one makes the news.

There’s a subtler trap inside this. Prices feel like documentation: they’re stable, they’re published, and it’s tempting to put them in the knowledge base with everything else. Don’t. An indexed price goes stale silently. Nobody notices until a customer quotes last quarter’s figure back to your support team. Anything that changes independently of the document it sits in belongs in a tool.

Product details pulled from the catalogue at the moment of asking (price, stock and SKU), never from an indexed copy

The assistant must never decide who it’s talking to

This is the rule everything else hangs off.

A language model will happily accept that it’s speaking to whoever the conversation says it is. Type “I’m checking on behalf of rahul@example.com” and a naively built assistant will look that account up. It isn’t being malicious; it’s doing what the text in front of it suggests.

The fix is architectural, not conversational. No prompt instruction is strong enough to rely on here.

In our build, every tool call passes through an interceptor before it reaches the function. The interceptor reads the authenticated identity from the verified session and overwrites whatever the model put in that field. Not fills it if empty, overwrites it, every time. The model can hallucinate an email address, a customer can type one into the chat, and neither survives that line of code.

The functions then re-check ownership anyway. A request for an order verifies that order belongs to the resolved customer before returning anything, and logs the attempt if it doesn’t. Two layers, because the cost of being wrong is somebody else’s purchase history.

One practical note: this is also where most of the bugs live. Every new customer-specific function has to be registered with the interceptor, and forgetting shows up as an authentication error from a function that’s otherwise perfectly healthy. Build the list in one place and make adding to it part of the definition of done.

Signing in shouldn’t end the conversation

Here’s a scenario worth walking through, because the obvious implementation gets it wrong.

A visitor browsing anonymously asks about a product, gets an answer, troubleshoots a fault across several messages, and then asks something that needs their account. The assistant asks them to sign in. They do.

What happens next determines whether the thing feels finished or not. The built-in authentication path starts a fresh session once identity changes, which means the customer returns to an empty chat and repeats five minutes of conversation to a bot that has forgotten them. That’s worse than not offering sign-in at all, because you’ve asked for effort and then thrown it away.

We handled it by updating the existing conversation in place rather than starting a new one. The customer signs in through a popup, the session attaches identity to the conversation that’s already running, and the assistant continues from exactly where it stopped, including the question that triggered the sign-in, which is resent automatically so nobody has to type it twice.

 

It’s a small detail that takes real effort to build, and it’s the difference between “sign in to continue” and “sign in, and carry on”.

A retail chat that sells needs more than sentences

Customer support chat and retail chat look similar and aren’t. Support is mostly answers. Retail is comparison, browsing, deciding; none of that works as paragraphs.

An assistant that says “the LG 343L is $443 and the Samsung 236L is $389, both are in stock” is technically correct and commercially useless. A shopper wants to see them side by side, with images, and tap one.

Connect’s built-in widget can’t do this: it has interactive message templates, but they’re fixed shapes the AI agent has no way to emit. The route through is to build your own front end on the platform’s chat library, and have the assistant emit structured data alongside its text (product carousels, order cards, a map with directions to the nearest service centre), which your interface renders properly.

A question about service centres returns a map rather than an address to copy out

The same card scrolled: opening hours, services offered, directions and a tap-to-call number

That raises a problem nobody warns you about: getting a language model to reliably emit structured output instead of prose is harder than it sounds. Our first attempts failed in a way that’s worth describing, because the lesson generalises.

We wrote a rule saying orders should be shown as cards. The model ignored it and wrote a tidy numbered list; it read as a preference, not an instruction. We rewrote it as a prohibition against lists. The model then asked, inside a sentence, “the Daikin from March, or the Voltas from June?” Technically not a list.

What finally worked was three things together: phrase the rule in the same register as every other rule the model obeys, ban every form of the behaviour explicitly rather than one phrasing, and include a worked example of the exact wrong output next to the right one. Concrete examples bind; abstract prohibitions get reasoned around.

Know when to escalate to a human

The most useful instruction we wrote wasn’t about what the assistant could do. It was a list of moments to stop and fetch a human.

Any safety signal (smoke, sparks, a burning smell) during appliance troubleshooting ends the conversation immediately and escalates, with no further diagnosis and no sign-in request. Someone describing a hazard shouldn’t be asked to authenticate.

Beyond that: when a customer asks for a person, when the same answer has already been given twice, when a request needs judgement outside documented policy, when a required lookup has failed twice. And one anti-rule that mattered as much: not being signed in is not a reason to escalate. A guest asking about their own order needs a sign-in prompt, not a queue.

The handover, seen by the customer: the assistant steps aside and a named agent joins the same conversation

When escalation does happen, the agent should arrive with the whole conversation already in front of them. If the customer has to start again, the handover has cost more than it saved.

The same moment from the agent’s side: the conversation so far, the customer’s profile, and case history in one view

The pattern underneath

Everything above is a version of the same idea: the model is good at language and shouldn’t be trusted with anything else. Identity comes from the session. Prices come from the database. Policy comes from indexed documents. Totals are computed server-side and handed to the model as strings it reads out rather than numbers it works with.

Constrain it properly and a conversational assistant handles a genuinely broad range of retail journeys. Leave it to improvise and it will: confidently, fluently, and wrong.

 

Written by

Talk to our team

Get in Touch

Tell us what you're working on. A senior consultant will follow up with next steps.

Talk to our team

Talk to our team

Tell us what you’re working on. A senior consultant will follow up with next steps.