Prodedify is the company behind a small family of products, and Frela — our furniture and homeware store — is one of them. When we started thinking seriously about AI shopping assistants, we did the obvious thing: we built one for ourselves first. Frela became the proving ground for Kiln, the AI agent layer we now run in production. This is the story of how Kiln came together, the decisions we made, and what we would tell anyone else building commerce agents from scratch.
Why we built our own agent layer
There is no shortage of bolt-on shopping chatbots. Most of them share the same flaw: they are language models with a product feed stapled to the side. Ask one for a sofa under £800 and it will happily invent a product, quote a price that does not exist, and link you to a 404. For a real store, that is worse than having no assistant at all — it erodes trust at exactly the moment a customer is deciding whether to buy. We wanted an agent that could only ever speak about products that actually exist, at prices that are actually live, and that could take real actions on the customer’s behalf. None of the drop-in widgets did that, so we built Kiln.
Kiln in one sentence
Kiln is a standalone AI service that sits alongside the Frela storefront and talks to the catalogue through a small set of well-defined tools. It is provider-agnostic, so the underlying model can be swapped without rewriting the product. It is grounded in Frela’s real inventory through semantic search, so it never has to guess what we sell. And it runs as its own service with its own database, so an experiment in the agent layer can never destabilise the store itself.
Provider-agnostic from day one
The fastest-moving part of any AI product is the model underneath it. A frontier model that is best-in-class today may be second-best — or twice the price — in three months. So we designed Kiln around a provider abstraction from the very first commit. The same agent can run on Anthropic, OpenAI, or Gemini, and switching is a configuration change rather than a rewrite. The one deliberate exception is embeddings: those are always routed to OpenAI, because not every provider exposes a competitive embeddings API and we wanted the vector space to stay consistent as we swap the chat model around it.
Grounding answers in the real catalogue
The core of Kiln is retrieval, not generation. Before the model says anything, Frela’s catalogue is embedded into vectors and stored in Postgres using pgvector. When a customer asks for “a low oak bed frame that works in a small room,” we turn that sentence into a vector, find the closest real products, and hand those to the model as the only material it is allowed to talk about. The language model’s job is to explain and compare what retrieval surfaced — not to dream up inventory. That single design choice is what separates a useful shopping agent from a confident liar.
Giving the agent hands, not just a mouth
A chatbot answers questions. An agent does things. We gave Kiln a deliberately small toolkit — search products, fetch a single product, get recommendations, and add to cart — and made those tools the only way it can interact with the store. The model cannot free-text a price or a stock level; it has to call a tool, and the tool returns structured data straight from the source of truth. When a customer says “add the walnut one to my basket,” that is a real tool call against the real cart, not a simulated reply. Keeping the toolkit small kept the behaviour predictable and the surface easy to reason about.
Configuration as YAML, not code
Agent behaviour — which model, which system prompt, which tools, which guardrails — lives in YAML configuration files with environment-variable expansion, not buried in application code. That sounds like a small thing, but it changed how quickly we could iterate. Tuning an agent’s tone, swapping a model, or tightening a guardrail became an edit-and-reload loop instead of a code-review-and-deploy loop. It also meant the people shaping the assistant’s behaviour did not have to be the people who wrote the service.
Keeping Kiln separate from the store
Kiln runs as its own service, with its own Postgres-and-pgvector database, completely separate from the commerce backend that runs Frela. This isolation was intentional. The store’s database is the source of truth for orders and money; the last thing we wanted was an AI experiment competing for connections or locks with checkout. By giving Kiln its own runtime and its own data store, we can rebuild the entire vector index, change embedding strategies, or restart the agent service without a single customer noticing on the storefront.
What we learned
Three lessons stuck with us. First, retrieval quality matters more than model choice — a great model on top of weak retrieval still gives weak answers, while solid retrieval makes even a mid-tier model genuinely helpful. Second, constraining the agent makes it better, not worse; a small, well-defined toolkit produced more trustworthy behaviour than an open-ended one ever did. Third, dogfooding is the cheapest research you can buy — running Kiln on our own store meant every rough edge showed up in front of us before it ever reached a customer of a product we sell to others.
What’s next
Kiln started as the assistant for one store, but the architecture was never specific to furniture. The same provider-agnostic, retrieval-grounded, tool-driven pattern applies to any catalogue and any commerce surface. Frela proved the model works; the next step is making it something other teams can point at their own stores. If you are building shopping agents and wrestling with the same questions, we would love to compare notes.