2026.09.12

Building Backend and AI Core Systems at adGPT

My work on the backend and AI core for a Sweden-founded advertising technology company based in the UK.

Backend EngineeringAI SystemsAPIsLLM WorkflowsSystem Architecture

adGPT was not just another place where i wrote endpoints.

it sat in that difficult part of software where product expectations move very fast because everyone can see what AI appears to make possible, but the actual system still has to behave like reliable backend software.

the company was Sweden-founded and based in the UK, working around advertising and AI. my responsibility was around the backend and the AI core: the part of the system that had to accept product intent, turn it into structured AI workflows, coordinate the moving pieces, and return something the rest of the product could trust.

that is the part i care about most in AI products.

not the shiny demo.

the control plane behind it.

the work was not "call the model and display the result"

there is a very shallow version of AI product engineering where the backend is basically:

text
receive prompt -> call model -> return text

that can work for a prototype. it does not hold for a real product.

advertising workflows are more structured than a raw chat response. the system has to understand campaign intent, audience context, brand constraints, formats, generation steps, retries, user edits, and the difference between a useful output and something that merely sounds confident.

so the backend cannot be a thin wrapper around an LLM API. it has to become the layer that makes AI behavior product-shaped.

the backend had to protect product logic from model randomness

LLMs are useful, but they are not stable infrastructure.

they can drift in tone. they can ignore parts of a request. they can return a shape the frontend did not expect. they can produce output that looks good but misses the business constraint. they can fail slowly, expensively, or with an error message that means nothing to the user.

my work around the AI core was about putting structure around that.

the useful pattern is to keep the model inside a controlled workflow:

text
user intent -> validated request -> normalized product context -> AI task plan -> model call -> structured parsing -> quality checks -> stored result -> editable product output

that pipeline matters because a product cannot depend on vibes. the model can be creative inside the box, but the system owns the box.

state mattered more than it looked

AI features often look stateless from the outside. a user asks for something, a response appears.

inside the backend, there is usually more state than people expect:

  • who made the request;
  • what workspace or campaign it belongs to;
  • what inputs were used;
  • which model or provider handled it;
  • what intermediate output was produced;
  • what failed and whether it can be retried;
  • what the user edited afterwards;
  • what version should be shown, reused, or discarded.

if that state is poorly modeled, the product becomes confusing quickly. a user cannot tell which output is current. retries can overwrite useful work. edits can become detached from the original generation context. support cannot reconstruct what happened.

this is where backend discipline becomes product quality.

AI systems need failure design

one of the easiest mistakes in AI products is pretending every generation will complete cleanly.

real systems need to handle:

  • provider timeouts;
  • malformed model output;
  • safety or policy blocks;
  • rate limits;
  • duplicate submissions;
  • partial completions;
  • expensive retries;
  • user cancellation;
  • downstream formatting failures.

the backend should not treat all of those as the same error.

a timeout may be retryable. malformed output may need a stricter parser or a repair pass. a rate limit should affect scheduling and user messaging. a duplicate request should be idempotent. a policy block should be explained without leaking unnecessary internal detail.

that kind of failure design is not glamorous, but it is what separates an AI feature from an AI incident generator.

the AI core needed boundaries

when a product has AI at the center, every team wants the model to solve more of the problem.

that instinct is understandable, but dangerous.

my preference is to make the model responsible for the parts where language, variation, reasoning and synthesis are useful, then keep deterministic software responsible for everything that must be correct.

for adGPT, that meant thinking about the AI core as an orchestration layer rather than a magic box. prompts, context assembly, tool decisions, schema expectations, retry rules, output validation and persistence all needed clear boundaries.

the backend's job was to make the system legible.

if something went wrong, we should be able to answer:

  1. what did the user ask for?
  2. what context did the system attach?
  3. what did the AI return?
  4. what did the backend accept or reject?
  5. what did the product finally show?

without that chain, debugging becomes archaeology.

what made the work senior

the senior part of this kind of work is not knowing how to call an AI API.

everybody can do that now.

the senior part is designing the system so the AI capability survives contact with users, product changes, cost constraints, latency pressure, unreliable providers and the normal mess of production software.

that means:

  • designing APIs that can evolve without breaking the product;
  • keeping generation workflows observable;
  • separating user-facing errors from internal diagnostics;
  • making retries and idempotency explicit;
  • preserving enough audit trail to debug real failures;
  • treating cost and latency as architecture concerns;
  • building the AI layer so it can change providers or prompts without rewriting the whole backend.

this is the work i handled at adGPT: the backend and AI core pieces that make the product possible after the demo is over.

what i took from it

adGPT sharpened a belief i already had: AI products are backend products wearing a very persuasive interface.

the interface gets attention because it is what people touch. but the trust lives deeper down. in the state model. in the retry path. in the logs. in the way the system validates output before showing it. in the boring decision to make the model one component instead of the whole architecture.

that is the kind of AI engineering i want my name attached to.

systems that are ambitious, yes.

but also controlled, observable, and honest about where the hard parts actually are.