A Consistent Character in the Gemini API: An 18-Frame Test Shows a Bare Prompt Makes Clothing Drift
An image generator has no memory between requests, so a "persistent character" is a discipline the client has to enforce: a fixed text passport for the hero and reference images in every request. The author ran 18 generations of a two-character scene across three prompt variants. The faces never changed, but with the bare prompt, clothing and accessories drifted from the reference and text showed up in the background.
AI-processed from Habr AI; edited by Hamidun News
If you make videos or ads with the same characters, the main pain is familiar: by the third frame the heroine no longer looks like herself, and two people in one scene suddenly swap faces or clothes. A Habr author worked out how to handle this through the Gemini API and tested the techniques with a small measurement.
Why the face drifts
The generator has no memory between requests. Each call builds the frame from scratch from the text and the attached images. So character consistency has to be enforced on the client side.
The author proposes four elements:
- Passport: a fixed text block describing the character's appearance, pasted into every prompt byte for byte. It holds only what never changes: age, hair, eyes, distinguishing features. Do not put a smile or clothing in it, or the smile will show up in every frame.
- Reference: a front-facing portrait on a gray background, even lighting, neutral expression. It goes into every request as a reference image.
- Views: front, three-quarter, profile, back. Each view is generated in a separate request with the reference as input. When the author asked for all four views in a single image, the model turned the head to the left and the feet to the right.
- Review of every frame by eye at full size.
Technically it is simple: in generateContent, images go in as inlineData in the same parts array as the text. The order of the parts is the order of the images that the prompt refers to. It is better to set the aspect ratio with the imageConfig.aspectRatio parameter: a line in the prompt remains a hint, while the parameter is enforced.
The test: two characters in frame
The author used gemini-3.1-flash-image and two pairs of characters: a woman and a man, and two clearly different women. There were three prompt variants, three takes per pair, 18 generations in total:
- Bare: "these two meet in a café", with no roles and no distinguishing features.
- With roles: who sits, who stands, who is on the left. No image numbering.
- With numbering: "Image 1 is the woman: …", "Image 2 is the man: …", features described in words, and a direct ban on mixing up the faces.
The faces never swapped, and nobody sat with their back to the camera. The difference was in the details. In the bare prompt, in one take out of three, the heroine appeared in a dark jacket and a gold bracelet that are not on the reference, and she looked older. In another take, the text "EVENING SPECIALS" appeared on a board in the café. The variant with roles kept faces and clothing correct in 6 takes out of 6, but in two takes there were signs in the background even though the prompt said no text. The numbered variant produced 6 out of 6 with no errors and no text.
The main takeaway: the risk of a bare prompt is not swapped faces but drift of clothing and accessories away from the reference. Three takes per variant is a small sample, and you cannot use it to claim "N percent fewer errors". The comparison is also imperfect: the time of day differs across the bare prompts, and no text appeared only in the prompts with roles. The author did not test two similar-looking characters, such as brunettes in suits.
Video and Omni
For video, the author uses gemini-omni-1.1-flash through the Interactions API. Image roles are set with tags directly in the text: <FIRST_FRAME> for the first frame and <IMAGE_REF_n> for the character references. The working order is: first build and check a frame with both characters, then pass it as the first frame and add the references as references.
The model decides for itself where everyone ends up. Given the request "sits down across from her", the character sat next to her, because he was standing to the side. If the arrangement matters, you need a first frame in which the characters are already seated, so the video only has to supply the action.
gemini-omni-1.2-flash has been available since November 5, and from December 3 requests to 1.1 will be redirected to it. In it, duration became a parameter (from 3 to 15 seconds), and a second of 720p dropped in price from $0.10 to $0.07. But in one test the first-frame and last-frame tags did not work. A direct phrase at the start of the prompt helped: "The video starts exactly on the first image and ends exactly on the second image". The variant with a single FIRST_FRAME and IMAGE_REF was not tested on 1.2.
What to do in practice
- Keep the hero's passport as a constant in code, not as text written anew each time.
- For scenes with two characters, number the images and list distinguishing features. It costs a couple of lines and makes the prompt unambiguous.
- Do not trust no text: check the background. In an ad, a sign behind the character will show up first.
- Stitch the takes into a contact sheet and zoom in on suspicious frames. The author noticed the jacket and bracelet only when they sat next to clean takes.
On cost, a 1K image costs about $0.067, the whole 18-frame test about $1.21, and a 6-second clip on Omni 1.1 came to $0.63.
- Nov 12, 2026Anthropic ported Claude to AMD chips in three days using its Mythos model
- Nov 12, 2026Google launches Gemini Decision 1: video and PDF decisions for $0.10 per 1M tokens
- Nov 12, 2026AlphaProof Code Proved Correctness of Signal's Encryption Core in 4 Weeks Instead of Years
- Nov 12, 2026Timeweb Cloud Adds Video Models, Ruble Limits and Fallback Models to AI Gateway
Key Questions Answered
Why the face drifts?
The generator has no memory between requests. Each call builds the frame from scratch from the text and the attached images. So character consistency has to be enforced on the client side. The author proposes four elements: Passport: a fixed text block describing the character's appearance, pasted into every prompt byte for byte. It holds only what never changes: age, hair, eyes, distinguishing features. Do not put a smile or clothing in it, or the smile will show up in every frame.
What are the key details on The test: two characters in frame?
The author used gemini-3.1-flash-image and two pairs of characters: a woman and a man, and two clearly different women. There were three prompt variants, three takes per pair, 18 generations in total: Bare: "these two meet in a café", with no roles and no distinguishing features. With roles: who sits, who stands, who is on the left. No image numbering. With numbering: "Image 1 is the woman: …", "Image 2 is the man: …", features described in words, and a direct ban on mixing up the faces.
What are the key details on Video and Omni?
For video, the author uses gemini-omni-1.1-flash through the Interactions API. Image roles are set with tags directly in the text: <FIRST_FRAME> for the first frame and <IMAGE_REF_n> for the character references. The working order is: first build and check a frame with both characters, then pass it as the first frame and add the references as references. The model decides for itself where everyone ends up.
Test Frontier LLMs & Autonomous Agents in One Workspace
Run Claude Opus 5.5, GPT-6, Gemini 3.1, and DeepSeek side-by-side in Nomad AI (nomadnet.ai) — unified model routing, deep research, and multimodal workflows under one subscription.
The AI world, distilled — once a week
Seven stories that actually mattered, hand-picked. No noise, no reposts, no press releases.
Done! Check your inbox for a confirmation.