DEV Community

Cover image for I Thought I Was Building an AI Image Generator. I Was Actually Building an Iteration System.
Warren
Warren

Posted on

I Thought I Was Building an AI Image Generator. I Was Actually Building an Iteration System.

I started with a pretty simple mental model for my AI image product:

A user enters an idea, chooses a few options, generates an image, and either likes it or tries again.

That model turned out to be too shallow.

Once people started using the product repeatedly, the behavior looked less like “generate another image” and more like “keep narrowing the decision.”

They would keep the core idea and change one variable:

  • a different style
  • a different placement
  • a narrower or wider proportion
  • a different supporting element
  • less detail
  • a different lettering direction

That changed how I think about the product.

The generated image is not always the final unit of value.

Sometimes the real value is the sequence of comparisons that helps the user decide what they actually want.

Generation is only one step

The obvious architecture for an AI image product looks something like this:

input
  ↓
generation
  ↓
result
Enter fullscreen mode Exit fullscreen mode

But the real user workflow often looks more like this:

idea
  ↓
generate
  ↓
compare
  ↓
change one variable
  ↓
generate again
  ↓
compare again
  ↓
narrow the direction
Enter fullscreen mode Exit fullscreen mode

That is a different product.

If the user is iterating toward a decision, several things become more important than simply adding more model choices.

1. Controls become part of the reasoning interface

A prompt box gives users freedom, but it also asks them to describe everything again.

Structured controls let them preserve most of the current idea while intentionally changing one dimension.

In my case, things like style, placement, proportion, and detail level became more useful than I initially expected.

They are not just generation parameters. They are comparison variables.

A user can effectively ask:

same idea
+ different placement
Enter fullscreen mode Exit fullscreen mode

or:

same subject
+ narrower composition
Enter fullscreen mode Exit fullscreen mode

without rewriting the whole concept.

That makes the UI part of the reasoning loop.

2. “Regenerate” is a very blunt tool

Most generative interfaces have some version of a regenerate button.

But full regeneration throws away a lot of information.

A user may like:

  • the composition
  • the main subject
  • the balance
  • the general style

and dislike only one thing.

If every retry regenerates the whole image, the user has to trade one improvement for several accidental changes.

What they really want may be closer to this:

keep:
- composition
- subject

change:
- color
Enter fullscreen mode Exit fullscreen mode

or:

keep:
- style
- main element

remove:
- supporting symbol
Enter fullscreen mode Exit fullscreen mode

That is much closer to editing than random regeneration.

3. History is not enough

I recently added a lightweight generation history feature.

It solves retrieval well. A user can find an earlier result, open it again, download it, or compare it with something newer.

But history by itself does not create iteration.

There is an important difference between:

find an old result
Enter fullscreen mode Exit fullscreen mode

and:

continue from this result
Enter fullscreen mode Exit fullscreen mode

The second one requires more state.

Potentially:

generation state
- original input
- selected controls
- tool type
- model/provider
- relevant assets
- previous result
Enter fullscreen mode Exit fullscreen mode

And even that only gets you to continuation.

Controlled variation is another layer again.

4. Credits are not always paying for outputs

This was another assumption I had to change.

The simple interpretation of generation credits is:

1 credit = 1 more output
Enter fullscreen mode Exit fullscreen mode

But in an iterative workflow, credits can represent something closer to:

more room to explore
Enter fullscreen mode Exit fullscreen mode

The user may not need ten finished images.

They may need ten attempts to answer questions like:

  • Which placement works?
  • Which composition feels right?
  • Is this too detailed?
  • Do I prefer this style or the previous one?
  • What should I bring to the next step?

That changes how I think about both pricing and UX.

If the user is paying for iteration room, the product should make each iteration easier to compare and more intentional.

5. Better models do not automatically fix this

It is tempting to solve every problem in an AI product by improving the model.

Better image quality helps. More reliable instruction following helps.

But neither solves the workflow problem.

A stronger model still does not know which part of the previous result the user wants to preserve unless the product gives them a way to express that.

This is why I am becoming more interested in:

  • preserving generation state
  • comparing related outputs
  • restoring prior controls
  • creating branches
  • controlled variation
  • keeping selected parts while changing others

than simply adding more styles or another model.

The architecture starts changing

Once you treat the product as an iteration system, the data model starts looking different too.

A generation is no longer just:

id
image_url
created_at
Enter fullscreen mode Exit fullscreen mode

It starts looking more like:

generation
- user
- tool
- input state
- selected controls
- output
- parent generation
- model metadata
- created time
Enter fullscreen mode Exit fullscreen mode

You may not need all of this on day one.

I definitely do not.

But the important part is recognizing that a result may eventually need context about where it came from and what it is related to.

Otherwise, history becomes a pile of disconnected images.

The shift for me

I used to think the core loop was:

prompt → image
Enter fullscreen mode Exit fullscreen mode

Now I think it is closer to:

idea → generation → comparison → refinement → decision
Enter fullscreen mode Exit fullscreen mode

That sounds like a small wording difference, but it changes what I prioritize.

The product is not only responsible for producing an image.

It is also responsible for helping the user move between attempts without losing the reasoning that got them there.

I ran into this while building the AI Tattoo Generator in AIMakeTattoo.

I am still keeping the system lightweight, but I am much less interested now in “how many outputs can this generate?” and more interested in “how easily can someone move from one useful attempt to the next?”

For people building generative products: what ended up mattering more in your product — better generation quality, or better iteration controls?

Top comments (0)