---
title: How AI Creative Director works
description: See how AI Creative Director turns a product photo into three art directions and four campaign images.
url: https://www.felixsanz.dev/articles/how-ai-creative-director-works
language: en
published: 2026-08-18
updated: 2026-08-09
tags:
  - ai
  - development
alternate-es: https://www.felixsanz.dev/es/articulos/como-funciona-ai-creative-director
---

# How AI Creative Director works

## Introduction

Asking for four images of the same product sounds simple. We can repeat the campaign name in four prompts and hope the model understands that they should all belong to the same world. This can leave us with **four images connected by the text, but not necessarily directed as a campaign**.

[AI Creative Director](https://www.felixsanz.dev/lab/creative-director) starts one step earlier. It takes a photograph of an object and lets us add a small amount of campaign guidance. The Lab example uses an orange speaker with this brief:

> For design-conscious urban listeners. Make the campaign feel playful and rooted in everyday city life. Avoid polished luxury and conventional tech advertising.

The tool proposes three art directions, each with its own idea and photographic plan. We then choose one and generate four images that serve different purposes within the same campaign.

In this article we will follow the entire path to see **how a structured direction becomes four different photographs**. We will also see why reusing the same prompt is not enough, and which parts of a campaign fall outside this experiment.

![AI Creative Director with a photograph of an orange speaker and a brief for an urban campaign that avoids polished technology advertising.](https://www.felixsanz.dev/assets/tool.CyUTrj7a_Z2x3wYA.jpg)

*The object photograph and optional brief are the experiment's two inputs.*

## Directing before generating

The process is split into two phases. First we define the treatment, then we run the shoot, much like a photographic production:

-   A vision model studies the object and proposes **three executable directions**.
-   After we choose one, an image model produces **four photographs with different jobs**.

This separation matters because the first phase defines the campaign's shared world. The second resolves each photograph inside that world. If we tried to decide both things in a single call, every image would have to reconstruct the same art direction on its own.

Let's start with the treatment.

## Proposing three directions

The analysis uses [Gemma 4 31B](https://runware.ai/models/google-gemma-4-31b?utm_source=felixsanz.dev&utm_medium=blog&utm_campaign=creative-director&utm_content=gemma-model), an open-weight vision model. It receives the photograph and the optional brief. When there is no brief, the instruction stops it from inventing an audience, a brand story, or capabilities it cannot see in the object.

This is the complete system prompt:

```
You are a contemporary creative director building executable campaign photography treatments. The generated images are source assets for later advertising layouts, not finished ads. Study the supplied object and any specific guidance. When guidance is provided, treat every concrete request as a constraint. When it is absent, ground the directions only in visible properties of the object; do not invent a target audience, brand story, product capability, or marketing claim. Return exactly three genuinely different campaign directions so the user has a meaningful choice. Each direction must use a different central idea, set logic, lighting strategy, composition, and emotional register. Ground every choice in visible properties of the object. Put the strongest, most executable direction first. whyItFits must explain that connection without generic marketing language.

The palette is a proposed campaign palette, not an extraction from the source. Return only as many colors as the direction needs. Visual rules must be concrete constraints that can be applied to every shot; do not pad the list.

Return exactly four shots in this order and role mapping:
- hero: the key visual. Show one complete, unobstructed product as the dominant subject, occupying roughly 35-60% of the frame. Use an asymmetrical campaign-defining composition with intentional negative space where approved copy could be added later, but include no text.
- detail: the product-detail asset. Use one true macro photograph in which a specified visible material, join, control, or texture continues beyond the frame edges. The complete product must not be visible.
- context: the environmental asset. Use a wide composition in which the setting occupies at least 75% of the frame and the complete product occupies no more than 20%. Show a believable place for the object; do not repeat the key visual's isolated display or product scale.
- surprise: the alternate visual. Stage one physically plausible idea with a clearly different viewpoint, orientation, or interaction. It must create a useful secondary composition rather than another centered product display.

The four shots must remain recognizably one campaign while being unmistakably different as thumbnails. Give each shot a different camera distance and composition. Framing must describe the camera and crop; scene must describe the physical arrangement. Do not combine geometrically incompatible instructions such as a top-down view of an object hanging from a ceiling. Silently check each shot for physical and camera consistency before returning it.

The source image will also be provided to the image model, so preserve the object's silhouette, geometry, proportions, materials, colors, controls, fasteners, straps, and real markings. Never invent copy, labels, logos, brand claims, or people. Do not propose magazine pages, billboards, social-media frames, collages, or other finished layouts. Return only JSON.
```

The line that sets the experiment's boundary appears at the beginning: the images are **source assets for a campaign, not finished ads**. We can reserve negative space for copy that will be added later, but the model must not write it or lay out a magazine page or billboard.

The directions also have to connect to visible properties of the object. With the speaker, the model can use the translucent case and strap, or start from the circular control and triangular silhouette. What it cannot do is invent a product claim to justify an idea it had already decided on.

The brief moves that boundary. If we ask for a campaign aimed at urban listeners, that audience becomes a valid constraint. If the field is empty, the model has to work only with what it can observe.

### A response we can execute

A direction cannot stop at an attractive name and a paragraph of inspiration. The next phase needs to know **what the whole campaign must share and what must change in each photograph**.

That is why the request asks for a JSON response. This is the complete contract:

```js
const directionSchema = {
  name: 'creative_direction_options',
  strict: true,
  schema: {
    type: 'object',
    additionalProperties: false,
    required: ['directions'],
    properties: {
      directions: {
        type: 'array',
        minItems: 3,
        maxItems: 3,
        items: {
          type: 'object',
          additionalProperties: false,
          required: [
            'title',
            'concept',
            'whyItFits',
            'palette',
            'lighting',
            'setDesign',
            'visualRules',
            'shots',
          ],
          properties: {
            title: { type: 'string', minLength: 3, maxLength: 48 },
            concept: { type: 'string', minLength: 20, maxLength: 260 },
            whyItFits: { type: 'string', minLength: 20, maxLength: 260 },
            palette: {
              type: 'array',
              minItems: 1,
              maxItems: 5,
              items: {
                type: 'object',
                additionalProperties: false,
                required: ['name', 'hex'],
                properties: {
                  name: { type: 'string', minLength: 2, maxLength: 30 },
                  hex: { type: 'string', pattern: '^#[0-9A-Fa-f]{6}$' },
                },
              },
            },
            lighting: { type: 'string', minLength: 12, maxLength: 240 },
            setDesign: { type: 'string', minLength: 12, maxLength: 240 },
            visualRules: {
              type: 'array',
              minItems: 1,
              maxItems: 5,
              items: { type: 'string', minLength: 8, maxLength: 180 },
            },
            shots: {
              type: 'array',
              minItems: 4,
              maxItems: 4,
              items: {
                type: 'object',
                additionalProperties: false,
                required: ['role', 'title', 'framing', 'scene'],
                properties: {
                  role: {
                    type: 'string',
                    enum: ['hero', 'detail', 'context', 'surprise'],
                  },
                  title: { type: 'string', minLength: 3, maxLength: 48 },
                  framing: { type: 'string', minLength: 3, maxLength: 100 },
                  scene: { type: 'string', minLength: 12, maxLength: 260 },
                },
              },
            },
          },
        },
      },
    },
  },
}
```

`concept`, `palette`, `lighting`, `setDesign`, and `visualRules` define the shared system. Each item in `shots` contains its own framing and physical scene. `whyItFits` is not used for generation, but it lets the interface explain why the proposal makes sense for the object.

`strict: true` asks the model to follow the schema, but does not guarantee it. The server checks that there are exactly three directions and that their four shots follow the expected order. If the response is empty or cannot be parsed, **the analysis runs one more time**. When we choose a direction, the second endpoint validates every field it will use for generation again.

The current configuration uses `temperature: 0.65`, `thinkingLevel: 'off'`, and `maxTokens: 6000`. These values did not come from a comparison, and they are not a recommendation for other cases. They only describe the call the experiment currently makes.

![The three directions proposed for the speaker: Urban Pop, Tactile Play, and Neon Nocturne. The third is selected.](https://www.felixsanz.dev/assets/directions.1h6wuOwI_15n7EK.jpg)

*Three treatments of the same object before generating a single photograph.*

![The Neon Nocturne plan with four shots, along with the shared set, lighting, palette, and visual rules.](https://www.felixsanz.dev/assets/plan.26V3cTEg_2auzEd.jpg)

*The chosen direction separates shared decisions from the framing and scene of each photograph.*

## Four photographs, four jobs

The four images are not variations of the same framing. Each has a different place in the campaign:

-   `hero` presents the complete object as the key visual.
-   `detail` moves close enough that the whole product no longer fits in the frame.
-   `context` makes the object smaller and lets the setting show where it lives.
-   `surprise` looks for a secondary composition from a different viewpoint.

The names help, but they are not enough. A model can call another medium shot a “detail”, or generate four centered products against different backgrounds. Therefore, the endpoint adds a specific constraint for each shot:

```js
const SHOT_CONSTRAINTS = {
  hero: 'Create the key visual. Show one complete, unobstructed product occupying roughly 35-60% of the frame. Use an asymmetrical campaign-defining composition with intentional negative space where approved copy could be added later, but render no text. The environment must remain secondary.',
  detail: 'Create one single extreme-macro photograph, never a collage or sequence. Show only the specified visible material, join, control, or texture continuing beyond the image edges. It must be impossible to see the complete product, its silhouette, the room, or a background.',
  context: 'Create the environmental image. The setting must occupy at least 75% of the frame and the complete product no more than 20%. Integrate it into a believable place; do not use an isolated display or repeat the key visual's product scale and composition.',
  surprise: 'Execute the unusual physical idea literally while keeping gravity, attachment, and perspective plausible. Create a useful alternate composition with a clearly different viewpoint or orientation. Do not default to another centered product display.',
}
```

**The proportions turn vague words into constraints we can check**. The key visual reserves between 35% and 60% of the frame for the product. In the context photograph, the setting takes at least 75% and the object cannot exceed 20%.

Keeping `framing` and `scene` separate also prevents us from mixing the camera with what happens in front of it. The first describes distance and crop. The second arranges the object and set. This lets us catch incompatible instructions before sending them to the image model.

## Generating the campaign

The second phase begins once we choose a direction. All four photographs use [FLUX.2 \[klein\] 9B](https://runware.ai/models/bfl-flux-2-klein-9b?utm_source=felixsanz.dev&utm_medium=blog&utm_campaign=creative-director&utm_content=flux-model), another open-weight model that can work with a reference image.

**Each request combines two layers**. The first contains the complete shared direction. The second adds the role and composition of a single shot:

```
Create one campaign-ready source photograph, not a finished advertisement or mockup. Create one photograph only, never a collage, grid, contact sheet, split view, or sequence. Use the supplied reference image as the exact physical product, not as inspiration. Preserve its precise silhouette, geometry, proportions, materials, colors, controls, fasteners, straps, seams, and all visible details. Do not redesign, simplify, add, remove, relocate, or substitute any part of the product.

Campaign direction: {direction.title}
Central idea: {direction.concept}
Set: {direction.setDesign}
Lighting: {direction.lighting}
Campaign palette: {palette}
Non-negotiable visual rules: {direction.visualRules}

Shot role: {shot.role}
Framing: {shot.framing}
Scene: {shot.scene}
Required composition: {SHOT_CONSTRAINTS[shot.role]}

The shot-specific framing, scene, and required composition control camera distance, crop, product scale, and placement. The shared campaign direction controls the visual world, not the composition. Do not collapse this shot into a generic centered product photograph.
```

### Keeping the object recognizable

Before it reaches either model, the photograph goes through the [same preparation used by Image Debugger](https://www.felixsanz.dev/articles/how-the-image-debugger-works#reading-the-image). The browser limits the longest edge to `1600` pixels, flattens transparency onto white, and keeps the smaller JPEG or PNG version.

All four requests receive the original photograph through `referenceImages`. The text can describe an orange speaker, but **the reference contains its particular shape**, case, grille, metal control, and strap.

The prompt insists on preserving those details and treats the image as the physical product, not as inspiration. This is still not a guarantee of exact identity. A generative model can reinterpret a join or change a proportion, and the final comparison has to check for that.

### A negative prompt for photographs

Every shot shares this negative prompt:

```
typography, text, letters, words, logo, wordmark, label, watermark, signature, border, frame, device frame, magazine page, billboard, mockup, collage, grid, contact sheet, duplicate product, multiple products, people, person, hands
```

Several terms prevent a source photograph from turning into a finished ad. We also block duplicate products. `people` and `hands` are excluded because the only reference is the object, so any person would have to be invented by the tool.

All four calls use `1024 × 1024` pixels and `4` steps. This is the experiment's current configuration, not a conclusion about the best parameters.

Because the requests are independent, they run in parallel. **If one shot fails, the others are not discarded**. The interface keeps its place and shows the error only in that position.

> [!NOTE]
> **One shot can fail on its own**
> The generation uses `Promise.allSettled` instead of `Promise.all`. An isolated error becomes `null` and keeps the shot in its original position. If all four fail, the endpoint returns the complete error because there is no partial result left to show.

![The four Neon Nocturne photographs: a key visual of the speaker, a macro of its strap, a scene beside a neon sign, and a composition built around a reflection.](https://www.felixsanz.dev/assets/outputs.CQA7ld2V_4JNTP.jpg)

*The result of running all four jobs within the same visual direction.*

## What the campaign shows

The Neon Nocturne direction survives the changes in framing. All four images share dark backgrounds, magenta light, and reflective surfaces. *Fabric Weave* works as a macro, while *Night Stand* lets the setting into the frame. *The Glow* and *The Reflection* are the closest pair because both show the complete speaker on a reflective surface, although the latter makes the mirror the center of the composition.

The triangular silhouette, translucent case, grille, metal control, and strap remain recognizable. They do not remain intact. The proportions of the case, the shape of the grille, and some details around the control change. The reference preserves the object's general identity, not an exact copy.

The comparison has to answer two different questions. The first is whether the photographs look like they belong to the same campaign. The second is whether each one serves a purpose the others do not. **Coherence does not mean repeating the same image four times**.

## What it actually directs

AI Creative Director does not deliver an ad ready to publish. It does not write copy or decide the final composition around that text. Nor does it generate finished adaptations for specific media. It produces **a structured treatment and four source photographs** that still need to become finished layouts.

The important part of the experiment happens before generation. An art direction becomes data that we can inspect before choosing it and reuse afterward. Each image then receives the shared part and one responsibility of its own.

The result is still not a finished campaign. At least we have stopped asking for “something similar” four times.
