What the grocery assistant does, and the two things it is actually judged on: how fast it finds something, and whether the money is right.
SmartMarket takes a shopper's own words, finds the products a shop actually stocks, builds a basket, takes the money, and puts the order into the shop's own database in the shape that shop's existing systems already read. The conversation is the shopfront; everything behind it is ordinary retail plumbing that has to be exactly right.
This document specifies what it is required to do and how it is required to behave. Two things dominate it and neither is the language model. The first is latency, because a shopper abandons a search that takes six seconds. The second is the correctness of money, because an order that reports a tip as sales tax is a bookkeeping problem for somebody else to find months later.
A sentence becomes a search, a search becomes a basket, a basket becomes a paid order. The order is written locally first and reaches the shop's own database afterwards, through an outbox, and that ordering is the whole of section 5.3.
Fig. 1 · from a sentence to a row in the shop's database
| Who | What they come for |
|---|---|
| A shopper | A week's groceries, described rather than navigated. Often on a phone, often by voice, often while doing something else. |
| The shop | Orders arriving in its own database, in its own shape, without anybody rekeying them. |
| The office | What was ordered, what was paid, what was sourced from outside the catalogue, and what failed. |
The catalogue barely changes and used to be re-read in full on every single search: roughly 25,600 rows of embedding text pulled out of MySQL, re-parsed and stacked into a fresh matrix, in order to run one dot product that takes microseconds. The loading was the response time. It is now loaded once at startup and held in memory, and a search is a matrix multiply, a threshold and a sort.
| Query | Before | After | Change |
|---|---|---|---|
| milk | 6,558 ms | 6.50 ms | 1,009x |
| eggs | 6,434 ms | 4.58 ms | 1,405x |
| cheese | 6,428 ms | 11.11 ms | 579x |
| cheapest eggs | 6,444 ms | 26.91 ms | 240x |
| best deal on coffee | 6,468 ms | 27.33 ms | 237x |
| Median | 6,456 ms | 8.21 ms | 787x |
Two rules governed that change and remain requirements. The results must be identical, which is asserted against the live database by a parity check rather than asserted in prose. And it must be never worse: if the index is missing, still building or switched off, search falls back to the database path silently.
N-3 is stated as a requirement rather than a fixed bug because it is the kind of fault that is invisible while it is happening. It was found by checking that a $5 tip left the tax at 1.93, not by anything failing.
Orders are written to this application's own database first, and pushed to the shop's afterwards by a separate process draining an outbox. The shopper's confirmation does not wait on a network hop to somebody else's server, and a shop database that is briefly unreachable delays delivery of an order rather than losing it.
The check for N-7 is one command and belongs in every handover: the sync must be active on the grocery machine and on no other. Checked by asking each machine, not by assuming.
| Part | What |
|---|---|
| Address | marketz.smartzees.com |
| Application | FastAPI, one process |
| Screens | Next.js, exported as static files and served by nginx |
| Database | Its own MySQL schema, plus an outbox to the shop's |
| Catalogue index | About 25,600 products, 384 dimensions, held in memory |
| Region | Its own, separate from the other two agents |
It is the only one of the three agents in its region, which means it cannot reach the other two privately and does not need to. It shares nothing with them except the engine switch and the hardware behind it.
| Not here | Why not |
|---|---|
| Stock levels and reservations | The shop's own systems own stock. This orders from a catalogue, it does not hold inventory |
| Delivery routing and drivers | An order reaches the shop's database and the shop's existing operation takes it from there |
| Refunds and returns | Handled by the shop, through the payment provider, outside this application |
| Community documents and bookings | Separate products, on separate machines, with separate databases |
Written by Abad Naseer. Every measured number in this document is cited from the running system or from the code, and every target says that it is a target. Where the two disagree, the document says so rather than choosing the flattering one.