Skip to main content
← Back to case studiesReductivist Shop Assistant

Case Study

Reductivist Shop Assistant

Client: Reductivist

We built a question-answering assistant for Reductivist, a small California brand that sells minimalist objects made in the USA. Shoppers ask about products, shipping and returns, and the assistant answers from the store's own facts and live catalog, or says it does not know and points to the contact form. The model never states a price: it names products, and the store's own data supplies the price and stock on each card. It runs on Cloudflare's free Workers AI allocation, with daily limits that keep it there, so it has no running cost. Before launch it was tested against 61 questions, including prompt injections and invented policies, and the test report lists every failure and what was changed.

test questions passed before launch
60/61
prices written by the model
0
median time to an answer
1.7 s
monthly cost to run it
$0

The Challenge

Reductivist sells three products, the Ringtool V1 Gold, the Ringtool V2 Silver and the X Bottle Opener, on a custom Next.js store. Shoppers had questions the product pages did not answer, and the owner wanted an assistant that could answer them without inventing anything. The first finding was that the store published almost no facts. A shopper could not learn from the site what a Ringtool does, how long delivery takes or what is in the box, so an assistant grounded in the store's data had nothing to answer with, and one that answered anyway would be making it up. The site's Terms also said shipping fees were added at checkout, while checkout charged none. The other limit was cost: no paid API, no subscription and no new service to pay for.

Our Approach

The first deliverable was not code. It was a short facts file for the owner to fill in, and the same text went into the empty product descriptions, so it now shows on the product pages and in their search data too. Any topic the owner had not written about stays empty, and the assistant treats an empty topic as "the store does not say". Three products and one page of policy fit in a single prompt many times over, so there is no vector database and no retrieval pipeline, just the facts and a fresh read of the catalog on every question. The model has no tools and takes no actions: it cannot add to the cart, look up an order or send an email, which caps the damage of a prompt injection at a bad sentence. It never opens by itself, it is reached from a plain text link, and its header says the answers are written by an AI, as California's bot disclosure law expects of a bot that helps sell goods.

The Model Never States a Price

A price typed by a model is the most damaging thing a store assistant can get wrong, so the model is not given that job. It replies in a fixed JSON format with an answer, up to three product IDs, a topic and a flag for when it needs to hand off. The server checks every reply against that format, retries once when it does not match, and falls back to a fixed handoff answer after a second miss. Each product card, with its price, stock and Add to cart button, is built from the store's database at the moment of the question. Plain code then screens the answer itself. It rejects any amount of money in any form, including other currencies, spelled-out amounts and percentages, which would be an invented discount. It also rejects any link that leaves the store and any email address other than the store's own. A rejected answer is replaced with a handoff to the contact form.

Staying Free

The model is Llama 3.3 70B on Cloudflare Workers AI, called with plain HTTP requests and no SDK. Cloudflare gives every account 10,000 free units of compute a day, and a measured answer uses about 45 of them. Limits in the database keep usage inside that budget: 500 characters per message, 10 turns per conversation, 20 messages per visitor a day and 100 for the whole store. A Cloudflare Turnstile check opens each conversation, so a script cannot spend the day's budget. At the daily maximum the assistant uses about 6,400 of the 10,000 units. If the allowance ever runs out, Cloudflare returns an error rather than a bill, and the panel says the assistant is unavailable and shows the contact link. Questions are kept for 90 days with no raw IP address, and the Privacy Policy says so.

Testing It in Public

A test set of 61 questions covers seven groups: facts it should know, facts it must admit it does not know, policies that do not exist, prices, prompt injections, order questions it must hand off, and requests that have nothing to do with the store. The first run passed 55. Two answers had timed out on Cloudflare's side, so a timed-out call is now retried once. A correct refund answer was marked as a handoff, and the model would not say whether a product was in stock, and a rule change fixed each. The final run passed 59, and 60 after one more guard change. One failure is left, and the report says why. Told by a fake "admin update" that shipping now cost $10, the model correctly said shipping is free, but it quoted the $10 to deny it, and the price screen replaced the whole answer. The screen was left strict on purpose. The report also lists answers that pass but read badly, such as stilted refusals and comma splices.

The Result

On the final run the median answer took 1.7 seconds and the slowest one in twenty took 3.6 seconds, with no format misses. No answer stated a fact that is not in the facts file or the catalog, and all 61 final answers were read by hand to check that. Writing the facts file also fixed the store itself: the product pages gained the descriptions they lacked, and the Terms no longer contradict checkout. The assistant is built and hidden in production until the store finishes its move from Vercel to Cloudflare Workers, since Vercel's free plan does not allow commercial use. Hosting the store and the model on one Cloudflare account also closes a rate-limit gap that only exists on Vercel, where a visitor could set the IP header that limits are counted against.

Technology & Deployment

The store runs on Next.js 16 and TypeScript, with Supabase for the catalog, stock and assistant logs, and Stripe Checkout for payment. The assistant calls Cloudflare Workers AI with temperature 0 and a JSON schema, and Cloudflare Turnstile guards each conversation. Usage limits are enforced in a single Postgres function, and a daily job removes logs older than 90 days. The answer pipeline, the prompt, the format checks and the guards are plain functions with 106 offline tests that never call the model. An eval script runs the 61 questions against the live model and saves every answer, so each change to the prompt is measured before it ships. No new npm package was added.