<?xml version="1.0" encoding="UTF-8"?><rss xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:content="http://purl.org/rss/1.0/modules/content/" xmlns:atom="http://www.w3.org/2005/Atom" version="2.0"><channel><title><![CDATA[Whisk AI]]></title><description><![CDATA[Whisk AI]]></description><link>https://whiskai.hashnode.dev</link><image><url>https://cdn.hashnode.com/res/hashnode/image/upload/v1593680282896/kNC7E8IR4.png</url><title>Whisk AI</title><link>https://whiskai.hashnode.dev</link></image><generator>RSS for Node</generator><lastBuildDate>Thu, 10 Sep 2026 18:06:51 GMT</lastBuildDate><atom:link href="https://whiskai.hashnode.dev/rss.xml" rel="self" type="application/rss+xml"/><language><![CDATA[en]]></language><ttl>60</ttl><item><title><![CDATA[How I Turned Reference-Image Guesswork Into a Reproducible Test Harness]]></title><description><![CDATA[My image generations were failing in a very specific way: every output looked plausible, but I could not explain why one run kept the subject and another borrowed the camera angle from the wrong refer]]></description><link>https://whiskai.hashnode.dev/how-i-turned-reference-image-guesswork-into-a-reproducible-test-harness</link><guid isPermaLink="true">https://whiskai.hashnode.dev/how-i-turned-reference-image-guesswork-into-a-reproducible-test-harness</guid><category><![CDATA[Artificial Intelligence]]></category><category><![CDATA[creative coding]]></category><category><![CDATA[generative ai]]></category><category><![CDATA[image generation]]></category><category><![CDATA[#ai-tools]]></category><dc:creator><![CDATA[chen mensen]]></dc:creator><pubDate>Wed, 02 Sep 2026 05:39:43 GMT</pubDate><content:encoded><![CDATA[<p>My image generations were failing in a very specific way: every output looked plausible, but I could not explain why one run kept the subject and another borrowed the camera angle from the wrong reference.</p>
<p>I did what most people do first. I rewrote the prompt. Then I made it longer. Then I added negative instructions. The output changed, but the uncertainty did not.</p>
<p>The actual bug was my process. I was changing several inputs at once and judging the result from memory.</p>
<p>So I stopped treating reference images as inspiration and started treating them as test inputs.</p>
<img src="https://cdn.whisk-ai.io/blog/260704-reference-image-prompting-workflow/image-2-workflow.png" alt="A reference-first workflow for controlled AI image experiments" style="display:block;margin:0 auto" />

<h2>What I mean by a test harness</h2>
<p>This is not an automated benchmark and it does not make image generation deterministic.</p>
<p>It is a small structure around the experiment:</p>
<ul>
<li><p>a fixed prompt version</p>
</li>
<li><p>named reference roles</p>
</li>
<li><p>one changed variable per run</p>
</li>
<li><p>explicit acceptance checks</p>
</li>
<li><p>a short result log</p>
</li>
</ul>
<p>The goal is not to prove that one image model is universally better. The goal is to answer a narrower question: <strong>which input changed this output?</strong></p>
<p>That sounds obvious, but it immediately rules out the workflow that caused most of my confusion: replacing two references, tweaking the prompt, and changing the aspect ratio before pressing Generate again.</p>
<h2>Start with a manifest, not a mood board</h2>
<p>A mood board is useful for direction. It is bad at documenting causality.</p>
<p>Before a run, I now write a tiny manifest. It can live in JSON, YAML, a note, or even a filename. Mine looks roughly like this:</p>
<pre><code class="language-json">{
  "prompt_version": "v3",
  "canvas": "4:5",
  "references": {
    "subject": "subject-a.png",
    "scene": "scene-c.png",
    "style": "style-b.png"
  },
  "must_keep": [
    "subject identity",
    "dark green coat",
    "waist-up framing"
  ],
  "allowed_to_change": [
    "background details",
    "small accessories"
  ]
}
</code></pre>
<p>The labels matter more than the format.</p>
<p>Calling an image <code>subject-a.png</code> forces me to state what I expect it to control. Without that label, a visually strong image can quietly become the source for lighting, crop, clothing, and camera position at the same time.</p>
<h2>Step 1: Build a boring baseline</h2>
<p>The baseline should be easy to understand, not beautiful.</p>
<p>I begin with the prompt only, or with the single reference that defines the most important constraint. If identity is the priority, that is the subject reference. If layout is the priority, it may be a rough composition sketch instead.</p>
<p>The baseline gives me something to compare against. Without it, I tend to credit the full reference stack for qualities that the model would have produced anyway.</p>
<p>I save the baseline before adding anything else.</p>
<h2>Step 2: Add references one role at a time</h2>
<p>My usual order is:</p>
<ol>
<li><p>subject</p>
</li>
<li><p>composition or scene</p>
</li>
<li><p>style</p>
</li>
<li><p>material or detail</p>
</li>
</ol>
<p>The order is not a universal rule. It is simply a stable order that makes the log readable.</p>
<p>Each run changes one slot. The prompt, canvas, and other references remain fixed.</p>
<p>If adding the scene image changes the character's face, that is useful evidence. The scene image is carrying a subject signal I did not intend to import. I can then replace it with a quieter scene reference instead of trying to repair the face with another paragraph of prompt text.</p>
<p>This was the biggest improvement in my workflow: a bad result became diagnostic information rather than a reason to add more instructions.</p>
<h2>Step 3: Separate hard checks from preferences</h2>
<p>I used to rate an output with one vague question: “Do I like it?”</p>
<p>That mixes failures with taste.</p>
<p>Now I use two groups.</p>
<h3>Hard checks</h3>
<p>These are pass or fail:</p>
<ul>
<li><p>Is the intended subject recognizable?</p>
</li>
<li><p>Is the required object present?</p>
</li>
<li><p>Is the aspect and framing usable?</p>
</li>
<li><p>Did any forbidden text or logo appear?</p>
</li>
<li><p>Did the composition keep the important spatial relationship?</p>
</li>
</ul>
<h3>Preferences</h3>
<p>These can be scored:</p>
<ul>
<li><p>lighting</p>
</li>
<li><p>color harmony</p>
</li>
<li><p>material quality</p>
</li>
<li><p>visual energy</p>
</li>
<li><p>stylistic match</p>
</li>
</ul>
<p>An output can pass every hard check and still be unattractive. It can also look excellent while failing the one requirement that matters for production.</p>
<p>Keeping those judgments separate prevents a beautiful failure from winning the test.</p>
<h2>Step 4: Record the delta, not the whole image</h2>
<p>Long notes slow the experiment down. I record only what changed from the previous run.</p>
<table>
<thead>
<tr>
<th>Run</th>
<th>Changed input</th>
<th>Hard checks</th>
<th>Useful delta</th>
<th>Harmful delta</th>
</tr>
</thead>
<tbody><tr>
<td>A</td>
<td>Baseline subject</td>
<td>3/5</td>
<td>Identity is stable</td>
<td>Flat composition</td>
</tr>
<tr>
<td>B</td>
<td>Added scene</td>
<td>4/5</td>
<td>Better depth</td>
<td>Face became softer</td>
</tr>
<tr>
<td>C</td>
<td>Replaced scene</td>
<td>5/5</td>
<td>Depth retained</td>
<td>Colors became colder</td>
</tr>
<tr>
<td>D</td>
<td>Added style</td>
<td>4/5</td>
<td>Strong palette</td>
<td>Coat texture drifted</td>
</tr>
</tbody></table>
<p>This table gives me a decision path.</p>
<p>Run C tells me the original scene reference was not necessary. Run D tells me the style image is too influential, so the next test should replace or simplify that image. I do not need a new prompt yet.</p>
<img src="https://cdn.whisk-ai.io/blog/260704-reference-image-prompting-workflow/image-3-comparison.png" alt="Comparing the role of subject, scene, and style references" style="display:block;margin:0 auto" />

<h2>The tool is part of the environment, not the conclusion</h2>
<p>For disclosure: I run <a href="https://whisk-ai.io/">a reference-image generation workspace called Whisk AI</a>, and I used it for these tests because it keeps subject, scene, and style inputs visibly separate.</p>
<p>That means this is not a neutral product comparison.</p>
<p>The method should transfer to any image system that accepts one or more visual references, but the exact influence of each slot will vary by model. Some systems also expose seed, reference strength, or control weights. If those settings are available, they belong in the manifest and should remain fixed while testing another variable.</p>
<h2>What did not work</h2>
<h3>Chasing the same image twice</h3>
<p>Even with identical inputs, a generative model can produce different details. I stopped expecting pixel-level reproduction. The checks need to focus on stable requirements such as identity, layout, and object presence.</p>
<h3>Scoring too many qualities</h3>
<p>My first scorecard had twelve dimensions. I spent more time rating than generating.</p>
<p>Five hard checks and three or four preferences are usually enough. If a criterion cannot change the next decision, I remove it.</p>
<h3>Using a “perfect” reference</h3>
<p>The most polished image is often the noisiest test input. Editorial lighting, a dramatic crop, and complex styling may all leak into the result.</p>
<p>A plain image with one clear job is often easier to control.</p>
<h3>Changing the prompt to rescue every run</h3>
<p>A prompt edit is another variable. If I change it, I label it as a new prompt version and start a new comparison branch. Otherwise the log becomes fiction.</p>
<h2>A compact procedure I can repeat</h2>
<p>Here is the whole loop:</p>
<ol>
<li><p>Define one production goal.</p>
</li>
<li><p>Write three to five hard acceptance checks.</p>
</li>
<li><p>Freeze the prompt, canvas, and model settings.</p>
</li>
<li><p>Generate a baseline.</p>
</li>
<li><p>Add or replace one reference role.</p>
</li>
<li><p>Record only the useful and harmful delta.</p>
</li>
<li><p>Keep the change, revert it, or test a quieter replacement.</p>
</li>
<li><p>Start a new branch only when changing the prompt.</p>
</li>
</ol>
<p>The procedure is deliberately small. It needs to survive a real deadline.</p>
<h2>The useful outcome is an explanation</h2>
<p>A good run is helpful. An explainable run is reusable.</p>
<p>Once I can say, “the second scene reference improved depth but weakened identity,” I have an actionable next step. I can replace that reference, reduce its influence if the tool allows it, or accept the tradeoff.</p>
<p>Without the test harness, I only have a folder full of images and a vague memory of what I tried.</p>
<p>The method will not remove randomness from image generation. It does remove a large amount of randomness from the way I debug it.</p>
<p>If you use a similar workflow, I would be interested to know which acceptance checks remain useful across different models and which ones are too tool-specific.</p>
]]></content:encoded></item></channel></rss>