Skip to content
All work

Case study

Livery Design AI

Vision-LLM pipeline that turns photographs of physical decals into vector assets and composes AI-planned liveries onto product templates.

Role
Owner — AI pipelines and all prompt engineering
Domain
Generative AI & LLMs · Backend & APIs · Cloud & Production
Stack
Python · FastAPI · Anthropic Claude · OpenAI gpt-image · OpenCV
Result
~75s livery composition pipeline
Animation: a photographed decal becomes a clean vector asset, then a vision model plans a colour scheme that is composited onto a product template.

Overview

Two AI pipelines behind one design tool. One turns a photograph of a decal into a clean vector asset; the other has a vision model plan a colour scheme and layout that a deterministic renderer composites onto a product template. In UAT with a small group of users.

The model proposes. Deterministic code disposes.

The problem

Custom artwork meant tracing each decal and laying out every design by hand — and the layout rules were rewritten for every new template, so the work never compounded. A vision model can do the creative part, but its output cannot be sent to print as-is.

Two pipelines

Independent arms behind one API. Extraction produces assets; composition consumes them. Separate, so a failed extraction never corrupts a layout and either can be rerun alone.

Extraction

A photograph in, a clean vector asset out.

  • Vision classifier gates what runs next
  • Decal reproduced in isolation on a clean field
  • Automatic review of the reproduction
  • Background removal, then raster to SVG

Composition

Assets in, a finished design on the template out.

  • Vision model returns a JSON plan — theme, colours, placements, paint
  • Guard passes correct the plan
  • Regions derived from the template's geometry
  • Composited back to front with protection masks

Every failure became a guard

Prompting reduces how often a model gets something wrong; it never reaches never. Each recurring failure was turned into a named, testable correction instead of a longer prompt.

What the model producedDark detail on a dark body — trim that vanished on the product.
The guard that corrects itDetail-visibility lift: contrast between detail and body is checked and raised.
What the model producedBody colours too extreme to carry detail at all.
The guard that corrects itMid-tone clamp: the body is held in a range where anything placed on it reads.
What the model producedTwo elements planned into the same region.
The guard that corrects itZone-collision correction: placements are validated against template regions and moved.
What the model producedGradients strong enough to flatten the form.
The guard that corrects itGradient softening: ramps are limited before rendering.

My Role

Role

Owner — AI pipelines and all prompt engineering

Contribution

  • Built the extraction arm: vision classification, AI image reproduction of an isolated decal, automated review, background removal, and raster-to-vector conversion
  • Built the composition arm: a vision-LLM planner that reads the assets and returns a structured JSON design plan — theme, colour scheme, placements and parametric paint primitives
  • Built a data-driven SVG engine that composites the plan onto templates with window-protection masks and explicit Z-ordering
  • Wrote deterministic guard passes that correct model output — mid-tone body clamp, detail-visibility lift, zone-collision correction
  • Added a composition-fallback layer that generalises rendering rules to new templates with no per-template code
  • Instrumented per-call token and cost tracking across every API call

Team Context

Owned the AI pipelines and prompt work within a wider product backend.

Decisions

Ask for a plan, not a picture.

The output is print-bound, so geometry must be exact and editable. A generated image looks right and cannot be measured, corrected or re-exported. A plan can be validated and re-rendered without another API call.

  • Instead of
  • Image model renders the finished design
  • Freeform text the renderer parses

Derive placement regions from template geometry.

Per-template rules were the original complaint. Regions are computed as proportions of the template, so an unseen one renders with no new code — with a kill-switch for templates that genuinely are special.

  • Instead of
  • Hand-authored regions per template
  • One fixed layout

Seed variety through rotating design archetypes.

The models in use reject a temperature parameter, so the usual lever is gone. Rotating an archetype through the prompt varies designs along an axis a designer can name, which sampling does not.

  • Instead of
  • Temperature sampling
  • Accept repetitive output

Engineering around the model

Credit-free iteration
Saved plans re-render through the real pipeline with no model call, so renderer changes cost nothing to test.
Honest failure codes
Provider errors classified into billing, auth, rate limit and outage — a caller can retry the retryable and stop on the rest.
Per-call accounting
Tokens, cost and stage logged on every call, so an expensive run traces to the step that caused it.
Real-world inputs
Phone-camera formats normalised on upload, with retries and streamed progress for long image operations.

Results

~75s

livery composition pipeline

~200s

asset extraction pipeline

How it is measured

Measured
Wall-clock latency per pipeline, instrumented per call alongside tokens and cost.
Method
Per-call instrumentation across real runs, not a controlled benchmark.
Quality
Assessed by UAT users reviewing rendered output. There is no labelled set and no ground truth for a good design.

What I Learned

  • Wrapping a creative model in deterministic correction beats prompting it into submission. A guard is a named, testable rule; a longer prompt is neither.
  • Ask for a plan, not an artefact, when output must be exact. A plan can be corrected; an image can only be regenerated.
  • Make iteration cheap early. The credit-free harness paid for itself in days and changed how much I was willing to try.

Limits

The honest weak point: no fidelity metric for extraction and no scored evaluation of design quality — both need a labelled set and a rubric, and neither exists. Latency is instrumented, not benchmarked under load. The system is in UAT with a handful of users, so none of this is production-scale evidence.

What I'd Improve

  • Build a labelled evaluation set and score extraction fidelity. Quality is asserted, not measured. First fix.
  • Add a golden-render regression test, so a change that silently degrades output fails the build.
  • Benchmark both pipelines under controlled conditions rather than averaging live runs.
  • Cache planner output across similar inputs — many runs re-plan nearly identical work.