<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:dc="http://purl.org/dc/elements/1.1/">
  <channel>
    <title>DEV Community: William Jin</title>
    <description>The latest articles on DEV Community by William Jin (@william_jin_d9f49c3ea519e).</description>
    <link>https://dev.to/william_jin_d9f49c3ea519e</link>
    <image>
      <url>https://media2.dev.to/dynamic/image/width=90,height=90,fit=cover,gravity=auto,format=auto/https:%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F3901912%2Fd35a1032-adef-461a-839e-a27a70d63504.png</url>
      <title>DEV Community: William Jin</title>
      <link>https://dev.to/william_jin_d9f49c3ea519e</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/william_jin_d9f49c3ea519e"/>
    <language>en</language>
    <item>
      <title>Graduated autonomy: the design pattern that made our AI agent safe to run in production</title>
      <dc:creator>William Jin</dc:creator>
      <pubDate>Thu, 20 Aug 2026 10:04:23 +0000</pubDate>
      <link>https://dev.to/william_jin_d9f49c3ea519e/graduated-autonomy-the-design-pattern-that-made-our-ai-agent-safe-to-run-in-production-11el</link>
      <guid>https://dev.to/william_jin_d9f49c3ea519e/graduated-autonomy-the-design-pattern-that-made-our-ai-agent-safe-to-run-in-production-11el</guid>
      <description>&lt;p&gt;When people say "AI agent," they usually mean one of two things. Either a chatbot that suggests what you should do, or a script with an API key that just does it. The first is safe and useless. The second is useful right up until the morning it quietly does something expensive.&lt;/p&gt;

&lt;p&gt;I work on an agent that operates live ad accounts — real budgets, real money moving every hour. That constraint forces the question early: how do you hand execution to a model without handing over the keys entirely?&lt;/p&gt;

&lt;p&gt;The pattern we landed on is &lt;strong&gt;graduated autonomy&lt;/strong&gt;, and I think it generalizes well beyond ads.&lt;/p&gt;

&lt;h2&gt;
  
  
  The all-or-nothing trap
&lt;/h2&gt;

&lt;p&gt;Most agent frameworks give you a binary. &lt;code&gt;human_in_the_loop=True&lt;/code&gt; or &lt;code&gt;False&lt;/code&gt;. Approve every tool call, or approve none.&lt;/p&gt;

&lt;p&gt;Both settings are wrong most of the time:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Approve everything&lt;/strong&gt; turns into rubber-stamping within a week. Nobody reads the 40th confirmation dialog. You've built the illusion of oversight, not oversight.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Approve nothing&lt;/strong&gt; works fine until the model does something reasonable-looking and catastrophic, and now you're reconstructing what happened from provider logs.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;The real problem is that the binary treats every action as equally risky. Pausing a keyword that spent $12 with zero conversions is not the same decision as restructuring a campaign. Trust is not a boolean, so the switch shouldn't be either.&lt;/p&gt;

&lt;h2&gt;
  
  
  Four levels instead of two
&lt;/h2&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Level 0  OBSERVE     Agent watches, reports findings. Executes nothing.
Level 1  RECOMMEND   Agent proposes a concrete change. Human applies it manually.
Level 2  APPROVE     Agent stages the change. Human clicks approve. Agent executes.
Level 3  AUTOPILOT   Agent executes directly within a declared action envelope.
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The important part is not the four levels — it's that the level is &lt;strong&gt;per scope, not per system&lt;/strong&gt;. A new account starts at 0. After two weeks of the operator reading the agent's findings and agreeing with them, it moves to 1. Once staged changes have been approved without edits enough times, it earns 2. And a specific &lt;em&gt;class&lt;/em&gt; of action — say, pausing zero-conversion keywords under a spend threshold — can be promoted to 3 while everything else stays at 2.&lt;/p&gt;

&lt;p&gt;That last bit matters more than anything. You are not promoting "the agent." You are promoting &lt;em&gt;this action type, in this account, under these bounds&lt;/em&gt;. It's closer to granting a permission than to trusting a coworker.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="nd"&gt;@dataclass&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;frozen&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="bp"&gt;True&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="k"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;ActionEnvelope&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
    &lt;span class="n"&gt;action_type&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;str&lt;/span&gt;          &lt;span class="c1"&gt;# "pause_keyword"
&lt;/span&gt;    &lt;span class="n"&gt;scope&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;str&lt;/span&gt;                &lt;span class="c1"&gt;# "account:1234"
&lt;/span&gt;    &lt;span class="n"&gt;max_level&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;int&lt;/span&gt;            &lt;span class="c1"&gt;# 3
&lt;/span&gt;    &lt;span class="n"&gt;bounds&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;dict&lt;/span&gt;              &lt;span class="c1"&gt;# {"max_daily_spend_delta": 50.0}
&lt;/span&gt;
&lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;resolve_level&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;action&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;envelopes&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;-&amp;gt;&lt;/span&gt; &lt;span class="nb"&gt;int&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
    &lt;span class="n"&gt;match&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;next&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
        &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;e&lt;/span&gt; &lt;span class="k"&gt;for&lt;/span&gt; &lt;span class="n"&gt;e&lt;/span&gt; &lt;span class="ow"&gt;in&lt;/span&gt; &lt;span class="n"&gt;envelopes&lt;/span&gt;
         &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="n"&gt;e&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;action_type&lt;/span&gt; &lt;span class="o"&gt;==&lt;/span&gt; &lt;span class="n"&gt;action&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nb"&gt;type&lt;/span&gt; &lt;span class="ow"&gt;and&lt;/span&gt; &lt;span class="n"&gt;e&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;scope&lt;/span&gt; &lt;span class="o"&gt;==&lt;/span&gt; &lt;span class="n"&gt;action&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;scope&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt;
        &lt;span class="bp"&gt;None&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="n"&gt;match&lt;/span&gt; &lt;span class="ow"&gt;is&lt;/span&gt; &lt;span class="bp"&gt;None&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
        &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;                      &lt;span class="c1"&gt;# unknown action -&amp;gt; observe only
&lt;/span&gt;    &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="ow"&gt;not&lt;/span&gt; &lt;span class="nf"&gt;within&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;action&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;match&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;bounds&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
        &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="nf"&gt;min&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;match&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;max_level&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;2&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;  &lt;span class="c1"&gt;# out of bounds -&amp;gt; demote to approval
&lt;/span&gt;    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="n"&gt;match&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;max_level&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Note the failure mode: an unrecognized action doesn't get blocked with an error, and it doesn't get executed. It gets &lt;strong&gt;demoted&lt;/strong&gt;. The agent still does its work, the human just sees it first. Unknown means "ask," not "crash."&lt;/p&gt;

&lt;h2&gt;
  
  
  Autonomy is worthless without an audit trail
&lt;/h2&gt;

&lt;p&gt;Here's the part teams skip, and it's the part that actually makes the rest usable.&lt;/p&gt;

&lt;p&gt;Every executed action has to carry the reasoning that produced it — not a post-hoc explanation generated by asking the model "why did you do that," which is confabulation, but the actual inputs the decision was made from.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight json"&gt;&lt;code&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"action"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"pause_keyword"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"target"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"kw:88213"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"level_used"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;3&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"envelope"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"pause_keyword@account:1234"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"observed"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"spend_7d"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mf"&gt;43.10&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"conversions_7d"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"impressions_7d"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;2210&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"account_cpa_target"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mf"&gt;35.0&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="p"&gt;},&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"rule_fired"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"zero_conv_over_cpa_target"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"reverted_by"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="kc"&gt;null&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"ts"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"2026-08-20T09:14:22Z"&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Two properties are non-negotiable:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;Replayable.&lt;/strong&gt; Given &lt;code&gt;observed&lt;/code&gt;, you can re-run the decision and get the same output. If you can't, you don't have a log — you have a diary.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Reversible.&lt;/strong&gt; Every autonomous action names its inverse. &lt;code&gt;reverted_by&lt;/code&gt; starts null and gets filled if a human disagrees.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;The reversion rate is the single most useful metric we track. It's the promotion signal and the demotion signal in one number. If humans revert less than a few percent of a given action type, that action type is ready to move up a level. If reversions spike after a platform change, the action type demotes itself automatically. Trust becomes measured rather than asserted.&lt;/p&gt;

&lt;h2&gt;
  
  
  What this buys you
&lt;/h2&gt;

&lt;p&gt;The thing I did not expect: graduated autonomy makes the agent &lt;em&gt;more&lt;/em&gt; useful at low levels, not just safer.&lt;/p&gt;

&lt;p&gt;At Level 1, the agent is forced to produce a change specific enough for a human to apply by hand. That constraint kills vague output. "Consider optimizing your underperforming campaigns" is not applicable. "Pause keyword X, it spent $43 over seven days against a $35 CPA target with zero conversions" is. The discipline required for Level 3 turns out to improve Level 1.&lt;/p&gt;

&lt;p&gt;And when something does go wrong, the question is answerable. Not "the AI did something," but: this action, at this level, from this envelope, on this data, at this timestamp — and here's the human who approved it, or here's why no human was in the path.&lt;/p&gt;

&lt;p&gt;That's the difference between an agent you can run on production systems and a demo.&lt;/p&gt;




&lt;p&gt;We build this into &lt;a href="https://soku.ai" rel="noopener noreferrer"&gt;Soku&lt;/a&gt;, an agent that runs ad campaigns across Google, Meta, TikTok and ChatGPT Ads. The domain is ads, but nothing above is ads-specific — if your agent touches infrastructure, billing, customer data, or anything else where a bad afternoon is expensive, the same four levels apply.&lt;/p&gt;

&lt;p&gt;Curious what others are doing here. If you've shipped an agent with execution rights, how did you scope its permissions?&lt;/p&gt;

</description>
      <category>ai</category>
      <category>architecture</category>
      <category>python</category>
      <category>devops</category>
    </item>
    <item>
      <title>I Wrote 50+ GPT Image 2 Prompts for Ad Creative — Here's What Actually Works</title>
      <dc:creator>William Jin</dc:creator>
      <pubDate>Tue, 28 Apr 2026 18:11:00 +0000</pubDate>
      <link>https://dev.to/william_jin_d9f49c3ea519e/i-wrote-50-gpt-image-2-prompts-for-ad-creative-heres-what-actually-works-15hp</link>
      <guid>https://dev.to/william_jin_d9f49c3ea519e/i-wrote-50-gpt-image-2-prompts-for-ad-creative-heres-what-actually-works-15hp</guid>
      <description>&lt;p&gt;When OpenAI shipped GPT Image 2 last week, my X feed turned into the same five demos: astronauts on Mars, isometric office scenes, a cat in a beanie. Cool. But I run a marketing tool company, and the question I actually had was: &lt;strong&gt;can this thing replace a $3,000 product photoshoot?&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Short answer: yes, with the right prompt. Long answer: most prompts you see online are tuned for "wow factor," not for shipping. Headlines need negative space. Product heroes need consistent lighting. Lifestyle shots need to look unstaged in a way the default model resists.&lt;/p&gt;

&lt;p&gt;So I spent a few hours writing &lt;strong&gt;56 prompts specifically for ad creative&lt;/strong&gt; — product hero shots, OOH mockups, social ads with in-image taglines, type posters, flat lays, packaging, brand collabs, editorial. They're all live as a free gallery here:&lt;br&gt;
👉 &lt;strong&gt;&lt;a href="https://soku.ai/prompts/gpt-image-2" rel="noopener noreferrer"&gt;Soku AI's Free GPT Image 2 Prompts&lt;/a&gt;&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Below are the seven I'd hand a junior designer on day one — copy-paste ready.&lt;/p&gt;


&lt;h2&gt;
  
  
  1. The "floating product" hero shot
&lt;/h2&gt;

&lt;p&gt;Every DTC brand needs this. The trick is to over-specify the lighting and surface because GPT Image 2 will default to mushy studio mood otherwise.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Studio product photograph of a frosted glass skincare serum bottle with a black dropper, suspended mid-air against a soft peach gradient background. A single droplet of golden serum is frozen falling beneath the dropper. Hard rim light from the upper right, gentle reflected fill, subtle shadow on a bone-white acrylic surface below. Hyper-real macro detail on the brushed aluminum collar, condensation
beads, packaging-shot quality. 4:3, centered composition, copy-safe negative space on the left third.
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;Why it works&lt;/strong&gt;: explicit light direction (upper right rim), explicit surface (bone-white acrylic), explicit copy zone (left third). The model stops guessing.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fkp4scvoafmz2eo9yohnn.jpeg" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fkp4scvoafmz2eo9yohnn.jpeg" alt="The " width="800" height="600"&gt;&lt;/a&gt;&lt;/p&gt;




&lt;h2&gt;
  
  
  2. The lifestyle ad with a tagline already burned in
&lt;/h2&gt;

&lt;p&gt;GPT Image 2 is genuinely better than predecessors at typography. You can ask for the headline directly and it'll usually nail kerning on the first try.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;A lifestyle ad creative for a premium water bottle brand. A woman hiking on a scenic mountain trail, holding the [water bottle] with a natural grip. Wide shot, golden hour light, lush green background. Tagline: 'BUILT FOR THE LONG WAY.' Bold white sans-serif text, lower third. Photorealistic. No watermarks, no extra text.
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;Why it works&lt;/strong&gt;: the bracket placeholder lets you swap products. The "no watermarks, no extra text" is load-bearing — without it the model invents fake brand marks.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F5zk4f3g2w87y3sjjff1g.jpeg" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F5zk4f3g2w87y3sjjff1g.jpeg" alt="The lifestyle ad with a tagline already burned in" width="800" height="454"&gt;&lt;/a&gt;&lt;/p&gt;




&lt;h2&gt;
  
  
  3. The OOH billboard mockup
&lt;/h2&gt;

&lt;p&gt;Pitch decks live and die by these. Don't ask for a "billboard" — ask for the specific physical context.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Photorealistic mockup of a massive curved LED billboard in Times Square at dusk, displaying an ad for a luxury skincare brand: an oversized close-up of a dewy face, a single product bottle, and short bold typography. Wet pavement reflections, ambient signage glow, blurred yellow taxis passing in the foreground. Cinematic 16:9, billboard occupying the upper-right of frame, slight wide-angle distortion.
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;Why it works&lt;/strong&gt;: "wet pavement reflections" + "ambient signage glow" + "yellow taxis in motion blur" are what sell the realism. Without them you get a flat billboard floating in a clean street.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F2ydplsddcdwevlfvj8di.jpeg" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F2ydplsddcdwevlfvj8di.jpeg" alt="The OOH billboard mockup" width="800" height="450"&gt;&lt;/a&gt;&lt;/p&gt;




&lt;h2&gt;
  
  
  4. The type-led poster
&lt;/h2&gt;

&lt;p&gt;Useful for B2B, event branding, conference comms. The trick is committing to a type system and a single accent color.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Editorial type poster: an oversized vertical-set classic serif headline reading "QUIETLY POWERFUL" filling the full frame, set in deep navy on a textured cream paper background. A small product mark and a single date in fine type at the bottom corner. Subtle paper grain, slight letterpress emboss feel. 3:4.
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;Why it works&lt;/strong&gt;: telling the model what &lt;em&gt;kind&lt;/em&gt; of serif (classic), what &lt;em&gt;finish&lt;/em&gt; (letterpress emboss), and what &lt;em&gt;texture&lt;/em&gt; (cream paper grain) gives it three hooks to latch onto instead of generating generic "elegant text."&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fx2x005hoqj9qd5hd4ewu.jpeg" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fx2x005hoqj9qd5hd4ewu.jpeg" alt="The type-led poster" width="768" height="1024"&gt;&lt;/a&gt;&lt;/p&gt;




&lt;h2&gt;
  
  
  5. The before/after for paid social
&lt;/h2&gt;

&lt;p&gt;If you're running performance creative on Meta, this is the workhorse.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Social ad composition split vertically down the middle: left side warm-toned with the word "BEFORE" subtly burned in, right side bright cool-toned with "AFTER", showing the same model — left with dull skin, right with luminous glowing skin. Product bottle floats centered on the seam. Bold sans-serif headline space at the top. 1:1 square.
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;Why it works&lt;/strong&gt;: explicit color temperature shift (warm → cool) gives the model a visual rule for "transformation" that survives even at low quality.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fgeoyllk151f0ttihwcxd.jpeg" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fgeoyllk151f0ttihwcxd.jpeg" alt="The before/after for paid social" width="800" height="800"&gt;&lt;/a&gt;&lt;/p&gt;




&lt;h2&gt;
  
  
  6. The flat lay for ecommerce + Pinterest
&lt;/h2&gt;

&lt;p&gt;These are surprisingly hard to get right because the model wants to clutter.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Top-down overhead flat lay on a soft sage-green linen surface: a complete five-step skincare routine — cleanser, toner, serum, moisturizer, SPF — neatly aligned with subtle space between each item. Sprigs of dried botanicals, a folded muslin cloth, a bone-handled spoon for accent. Soft diffuse daylight, gentle shadows, editorial spacing. 1:1.
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;Why it works&lt;/strong&gt;: "subtle space between each item" + "editorial spacing" tells the model to leave room. Without those phrases it crams everything together.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fbyxce6v49hiq35wwf51m.jpeg" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fbyxce6v49hiq35wwf51m.jpeg" alt="The flat lay for ecommerce + Pinterest" width="800" height="800"&gt;&lt;/a&gt;&lt;/p&gt;




&lt;h2&gt;
  
  
  7. The brand collab
&lt;/h2&gt;

&lt;p&gt;Limited drops are the most-shared ad format on social. The model &lt;em&gt;loves&lt;/em&gt; this because it's basically two product hero shots glued together.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Energetic collab visual: a co-branded chip bag and a limited-edition controller floating in zero-G against a saturated electric-purple background, controlled splash of confetti and crumbs frozen mid-air. Hard rim light, neon accent, gen-z high-energy. 1:1.
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;Why it works&lt;/strong&gt;: "controlled splash" + "frozen mid-air" gives motion that feels intentional rather than accidental.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F5bcy60ffaebe9ths5qwr.jpeg" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F5bcy60ffaebe9ths5qwr.jpeg" alt="The brand collab" width="800" height="800"&gt;&lt;/a&gt;&lt;/p&gt;




&lt;h2&gt;
  
  
  What I learned writing 56 of these
&lt;/h2&gt;

&lt;p&gt;A few patterns that survived from product hero to OOH:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;Specify the surface, not just the background.&lt;/strong&gt; "Bone-white acrylic" beats "white" every time. The model uses the surface to anchor its lighting.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Negative space is a directive, not a vibe.&lt;/strong&gt; "Copy-safe negative space on the left third" is read as a hard constraint. "Clean composition" isn't.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Always close with a denial list.&lt;/strong&gt; "No watermarks, no extra text, no logos" prevents the model from inventing a fake brand for you.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Aspect ratio belongs at the end.&lt;/strong&gt; Putting it first sometimes gets ignored; putting it last as a closing instruction lands better.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Use bracket placeholders for the product noun.&lt;/strong&gt; It gives you a templated prompt you can swap across SKUs without rewriting the whole thing.&lt;/li&gt;
&lt;/ol&gt;




&lt;h2&gt;
  
  
  The full 56
&lt;/h2&gt;

&lt;p&gt;The above seven are a sampler. The full gallery has 56 prompts across nine&lt;br&gt;
categories — packaging mockups, brand collabs, editorial portraits, UGC-style&lt;br&gt;
shots, and more — all free, all copy-paste, organized for ad scenarios:&lt;/p&gt;

&lt;p&gt;👉 &lt;strong&gt;&lt;a href="https://soku.ai/prompts/gpt-image-2" rel="noopener noreferrer"&gt;Soku AI's Free GPT Image 2 Prompts&lt;/a&gt;&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Each card has a one-click "Try in Soku AI" button if you want to skip the prompt-engineering altogether and have an agent run a campaign for you. (Soku is free during beta.)&lt;/p&gt;

&lt;p&gt;Happy hacking!&lt;/p&gt;

</description>
      <category>ai</category>
      <category>marketing</category>
      <category>chatgpt</category>
      <category>nanobanana</category>
    </item>
  </channel>
</rss>
