Skip to content
Journai
Go back

An ai-commerce architecture based on Shopify

When I started thinking seriously about AI-powered commerce applications, I quickly realized that:

I do not want to integrate AI capabilities into the e-commerce solution which would turn the entire codebase into a tangled mess of prompts, agents, API calls, and business logic. I need to keep the commerce side stable while allowing the AI side to evolve at the speed of the AI ecosystem.

This architecture is the result of those questions and requirements. I decided to base it on Shopify as it is my current e-commerce plaform of choice and its Custom App system perfectly fits into the schema.

Architecture schema

A typical request flow

A typical interaction looks something like this:

  1. A merchant triggers an action from the Shopify admin.
  2. The backend (a Shopify Custom App) receives the request.
  3. The backend calls the AI service.
  4. The AI service invokes agents and supporting services.
  5. The agents interact with one or more models.
  6. Results are returned to the backend.
  7. The backend persists data and updates Shopify if needed.
  8. The merchant receives the final result.

The same pattern works for storefront experiences. The only difference is where the request originates.

The principle: separate commerce from AI

The first decision I made was to separate the commerce platform from the AI platform. I wanted commerce-related concerns to live in one place and AI-related concerns to live somewhere else.

The architecture is therefore split into two major components:

The two communicate through APIs, but remain largely independent. This separation has become one of the most important architectural decisions in the system.

Commerce and AI evolve at completely different speeds. Trying to make them coexist inside the same layer often creates unnecessary coupling.

The Shopify side

At the center of the commerce platform sits the Brush Backend, hosted on Gadget.dev. I decided to make this application the source of truth for everything related to the business domain.

Its responsibilities include:

In other words, this layer understands products, customers, collections, orders, business rules and so on. It does not need to understand how an LLM works.

Leveraging Shopify’s APIs

The backend interacts with Shopify through its GraphQL APIs.

Admin API

The Admin API gives access to merchant-facing data and operational workflows. This is where the application can:

Storefront API

The Storefront API exposes mainly product and shopi data that we can request as localized using the @inContext directive. Whenever I need data that belongs in the shopping experience, this is typically the interface I use. And, to make things easier, Brush comes with the ability to query the Storefront API out-of-the-box.

The merchant experience

For merchants admin experience, I stuck to the required Shopify application setup.

The administration interface is built with:

This gives merchants an experience that feels native to Shopify and the application becomes part of their existing workflow.

The storefront experience

On the storefront side, the application integrates directly with the Shopify theme.

Communication happens through a Shopify App Proxy which, also, is ready to use thanks to the frontend stack of Brush.

I like this approach because it creates a clean separation between:

From the shopper’s perspective, everything appears to happen inside the store. Behind the scenes, requests are routed to the application where the business logic lives.

This allows me to expose AI-powered capabilities on the storefront without exposing internal services directly.

Why I created a dedicated AI service

Again, instead of embedding prompts and agent logic directly into the e-commerce application, I built a dedicated service using FastAPI and deployed it independently and easily thanks to Cloudflare’s Workers.

At first, this may seem like an unnecessary layer but, to me, it allows matching the AI industry standards which are Python-based. So, every AI-related lies in a Python box.

Moreover, AI workloads have different characteristics:

So trying to force all of that into the commerce application felt wrong.

Inside the AI service

The AI service is organized into several layers.

REST API

The REST API powered by FastAPI acts as the entry point. Brush sends requests to the AI service without needing to know anything about the underlying implementation.

In other words: the commerce platform asks for a capability ; the AI platform decides how to execute it.

Services

Below the API layer sits a service layer.

This is where I centralize reusable AI capabilities such as:

This service layer is just enforcing software architecture best practices.

Agents

Above the services sits the agent layer where reasoning happens.

Agents can:

Depending on the use case, an agent might:

Remaining model-agnostic

Another design choice I made early on was avoiding dependence on a single model provider. So the AI service can interact with either simple models, frontier models, local open-source ones, remote open-source, …

I did not want the application architecture to depend on the success or failure of a particular vendor. The AI landscape changes too quickly for that.

This also allows chosing the right model for the right task: not every task deserves a premium model. Some workflows only require:

Others genuinely need to benefit from stronger reasoning capabilities. Keeping providers abstracted allows the AI service to choose the right model for each taskm while the Shopify application doesn’t need to care.

Designing for change

One lesson I learnt in my experience in building solution and software architectures is that they rarely fail because they are too simple. They usually fail because they become difficult to change.

When I designed this system, I assumed three things:

The architecture therefore optimizes for adaptability:

The two remain connected, but neither is tightly coupled to the implementation details of the other. At least for now, this feels like the cleanest way I’ve found to build AI-native commerce applications on top of an e-commerce platform (Shopify in the current case).


Share this post:

Previous Post
The first ping