<?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: Genjutsu AI</title>
    <description>The latest articles on DEV Community by Genjutsu AI (@genjutsu_ai).</description>
    <link>https://dev.to/genjutsu_ai</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%2F4195505%2F79f05f30-33c5-4ca8-a23a-087698c13d53.png</url>
      <title>DEV Community: Genjutsu AI</title>
      <link>https://dev.to/genjutsu_ai</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/genjutsu_ai"/>
    <language>en</language>
    <item>
      <title>Treat Your References Like Function Arguments: A Developer's Mental Model for Video-to-Video AI</title>
      <dc:creator>Genjutsu AI</dc:creator>
      <pubDate>Tue, 20 Oct 2026 06:49:35 +0000</pubDate>
      <link>https://dev.to/genjutsu_ai/treat-your-references-like-function-arguments-a-developers-mental-model-for-video-to-video-ai-200</link>
      <guid>https://dev.to/genjutsu_ai/treat-your-references-like-function-arguments-a-developers-mental-model-for-video-to-video-ai-200</guid>
      <description>&lt;p&gt;Most of us met generative video through text-to-video: you write a paragraph, cross your fingers, and get back something that is &lt;em&gt;almost&lt;/em&gt; what you meant. If you come from software, that workflow feels oddly unstructured. There's no input contract, no deterministic part, and every retry is a full re-run.&lt;/p&gt;

&lt;p&gt;Video-to-video models flip this around, and once I started thinking about them like a function call instead of a wish, my results got noticeably better. Here's the mental model.&lt;/p&gt;

&lt;h2&gt;
  
  
  The signature
&lt;/h2&gt;

&lt;p&gt;Think of a reference-driven video model as something like this:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight typescript"&gt;&lt;code&gt;&lt;span class="nf"&gt;generate&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
  &lt;span class="nx"&gt;source&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;Video&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;          &lt;span class="c1"&gt;// motion, timing, camera&lt;/span&gt;
  &lt;span class="nx"&gt;refs&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;Image&lt;/span&gt;&lt;span class="p"&gt;[],&lt;/span&gt;          &lt;span class="c1"&gt;// who / what appears&lt;/span&gt;
  &lt;span class="nx"&gt;prompt&lt;/span&gt;&lt;span class="p"&gt;?:&lt;/span&gt; &lt;span class="kr"&gt;string&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;        &lt;span class="c1"&gt;// the glue: which ref goes where&lt;/span&gt;
  &lt;span class="nx"&gt;mode&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;motion&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt; &lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;swap&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="nx"&gt;resolution&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;480p&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt; &lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;720p&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt; &lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;1080p&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;
&lt;span class="p"&gt;):&lt;/span&gt; &lt;span class="nx"&gt;Video&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The key insight: &lt;strong&gt;the source video is not a suggestion, it is the bulk of your specification.&lt;/strong&gt; It already encodes choreography, pacing, framing and camera movement, which is exactly the stuff that is painful to describe in words. Your prompt shrinks from a screenplay to a few lines of wiring.&lt;/p&gt;

&lt;h2&gt;
  
  
  Two modes, two very different contracts
&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;Motion transfer&lt;/strong&gt; keeps only the movement and camera of the source and rebuilds everything else from your images. Contract: &lt;em&gt;"same motion, new world."&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Object swap&lt;/strong&gt; keeps the original footage and replaces only the element you point at: a bottle, a jacket, a car, a person. Contract: &lt;em&gt;"same world, one diff."&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;If you think in diffs, object swap is the &lt;code&gt;git commit&lt;/code&gt; that touches one file. Motion transfer is a rewrite that keeps the interface.&lt;/p&gt;

&lt;h2&gt;
  
  
  Positional references: the &lt;code&gt;@Image1&lt;/code&gt; pattern
&lt;/h2&gt;

&lt;p&gt;Some tools number your uploaded references and let you cite them in the prompt, e.g. &lt;code&gt;@Image1&lt;/code&gt;, &lt;code&gt;@Image2&lt;/code&gt;, plus &lt;code&gt;@Video&lt;/code&gt; for the source. This is basically positional arguments, and the same habits that make function calls readable apply:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;@Image1 dances like the person in @Video, wearing the jacket from @Image2
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;





&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;replace the bottle with @Image3
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;A few rules that held up in my testing:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;Keep the prompt about &lt;em&gt;mapping&lt;/em&gt;, not &lt;em&gt;motion&lt;/em&gt;.&lt;/strong&gt; Don't redescribe the dance. The source already "knows" it. Re-describing motion is like passing a value that's already in scope; at best it's noise, at worst it conflicts.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;One responsibility per reference.&lt;/strong&gt; A face shot for identity, a separate flat-lay for the outfit. Mixing roles in one image makes it ambiguous which attribute the model should extract.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Order matters.&lt;/strong&gt; If a template ships with sample references, your uploads typically replace them in order. Treat it like a function signature: argument 1 stays argument 1.&lt;/li&gt;
&lt;/ol&gt;

&lt;h2&gt;
  
  
  Validate your inputs
&lt;/h2&gt;

&lt;p&gt;Garbage in, garbage out applies more strongly here than with text prompts, because the source video carries so much of the spec.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Source clip:&lt;/strong&gt; one continuous shot beats a fast montage. Hard cuts are like unhandled exceptions: the model has to guess what happens across the boundary. For swaps, the target object should stay visible for most of the clip.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Reference images:&lt;/strong&gt; well lit, subject filling a good part of the frame, front-facing for faces, plain background for products. Add a second angle if the subject turns away from camera.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Length:&lt;/strong&gt; tools usually bound this (4–30 seconds is a common window). Shorter clips also mean cheaper iterations.&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Iterate like you would with a slow CI pipeline
&lt;/h2&gt;

&lt;p&gt;Generation is slow and costs money, so treat it like an expensive build:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Draft at low resolution.&lt;/strong&gt; Run 480p to check identity, framing and that the right reference landed in the right place. It's your unit test.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Promote the winner.&lt;/strong&gt; Only re-render the keeper at 720p or 1080p.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Change one variable at a time.&lt;/strong&gt; Swap the reference &lt;em&gt;or&lt;/em&gt; the prompt &lt;em&gt;or&lt;/em&gt; the source, never all three, or you can't tell what fixed (or broke) the output.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Log your runs.&lt;/strong&gt; I keep a tiny JSON file per experiment: source clip, reference filenames, prompt, mode, result notes. It sounds overkill until you try to reproduce a good result a week later.
&lt;/li&gt;
&lt;/ul&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;"source"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"runway-walk-01.mp4"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"refs"&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="s2"&gt;"face_front.jpg"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"coat_flat.jpg"&lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"prompt"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"@Image1 walks like the person in @Video, wearing @Image2"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"mode"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"motion"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"res"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"480p"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"notes"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"identity stable, coat collar drifts at 3s; try second coat angle"&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;h2&gt;
  
  
  Trying it out
&lt;/h2&gt;

&lt;p&gt;If you want to poke at this without wiring up any infrastructure, I've been experimenting with &lt;a href="https://genjutsu.app" rel="noopener noreferrer"&gt;Genjutsu, a browser-based video-to-video generator&lt;/a&gt; that exposes both modes and the numbered-reference prompting described above, and shows the credit cost before each run. Whatever tool you use, the mental model transfers.&lt;/p&gt;

&lt;h2&gt;
  
  
  Responsible inputs
&lt;/h2&gt;

&lt;p&gt;One non-technical note: only use faces, products and footage you have the rights to. "It's just a test" stops being true the moment a clip gets shared.&lt;/p&gt;

&lt;h2&gt;
  
  
  Takeaway
&lt;/h2&gt;

&lt;p&gt;Stop treating the prompt as the whole program. In video-to-video, &lt;strong&gt;the source clip is the spec, the references are the arguments, and the prompt is the wiring.&lt;/strong&gt; Write it that way and your retries go down.&lt;/p&gt;

&lt;p&gt;What patterns have you found for making generative video less of a slot machine? Drop them in the comments.&lt;/p&gt;

</description>
      <category>ai</category>
      <category>generativeai</category>
      <category>video</category>
      <category>beginners</category>
    </item>
  </channel>
</rss>
