Prompt Engineering Breakdown: How a Single "Analyze-Then-Generate" Pattern Fixes Personalized AI Outputs
A case study using a real multimodal prompt that does face shape + hair type analysis before generating hairstyle recommendations.
If you build anything with multimodal LLMs — Gemini, GPT-4o/GPT-4.1 with vision, Claude with image input — you've probably hit the same failure mode I want to talk about today: the model generates a plausible-sounding personalized answer without actually using the input you gave it.
This shows up constantly in "personalization" prompts. You upload a photo, ask for a recommendation, and get back something generic enough to apply to anyone — not because the model can't see your image, but because nothing in your prompt forces it to commit to specific observations before generating output.
I want to walk through a small, public prompt that handles this well, and use it to explain a pattern you can reuse in any "analyze an input, then generate something personalized from it" use case — recommendation engines, style transfer tools, fitness apps, anything where the output should be conditioned on a real classification rather than a vibe.
The example prompt is from NanoAIPrompts, a copy-paste prompt library. It's a hairstyle recommendation tool — but ignore the beauty-app framing for a second and look at the structure, because the structure is the actually interesting part.
The Prompt
Analyze the single image I upload.
Identify my exact face shape and hair type with precision.
Then generate a vertical 9:16 4K 3x3 grid of hairstyle reference
images directly on my face.
Requirements:
Analyze the uploaded image to detect:
1. Face shape
2. Hair density, texture, curl pattern, and growth direction
Four sentences and a numbered list. Nothing fancy. But it encodes three deliberate prompt engineering decisions that are easy to miss if you're skimming it.
Decision 1: Sequencing analysis before generation, explicitly
The single biggest failure in "personalized" generation prompts is letting the model interleave analysis and generation in the same breath. Compare:
Weak pattern:
"Look at my face shape and suggest a flattering haircut."
Strong pattern (what this prompt does):
"Identify my exact face shape and hair type with precision. Then generate..."
The word "then" is doing real work here. It's a sequencing instruction, not decoration. It pushes the model toward a two-phase process: commit to a classification first, generate conditioned on that classification second. Without it, the model can produce a generation that sounds personalized — "this style works well for rounder face shapes" — without that classification ever actually constraining the output. It's the same gap between "show your work" and "give me the answer" in a math problem: the instruction to show work changes the actual reasoning path, not just the explanation of it.
If you're building a recommendation system on top of an LLM, this is the cheapest possible reliability win available to you, and most prompts don't do it.
Decision 2: Replacing a vague instruction with an explicit detection checklist
"Identify my hair type" is vague enough that a model can satisfy it with a single word: "wavy." The prompt instead expands that into a checklist:
2- Hair density, texture, curl pattern, and growth direction
Four named attributes instead of one vague category. This matters for two reasons:
It widens the feature space the model has to actually engage with. A model that only outputs "wavy" can get there by pattern-matching on a handful of pixels. A model that has to separately characterize density, texture, curl pattern, and growth direction has to do meaningfully more visual grounding to produce a coherent answer across all four — and inconsistencies between them become easier for a human reviewer to catch if something's off.
It gives you structured intermediate output you can actually use downstream. If you were wiring this into an app rather than a chat interface, you'd want each of these as a separate field, not a paragraph. Even in plain chat use, asking for the breakdown makes the model's "reasoning" inspectable instead of a black box.
This generalizes directly: any time you'd write "analyze X," ask yourself if X is actually a bundle of 3-4 more specific sub-attributes, and enumerate them instead of trusting the model to unpack the bundle correctly on its own.
Decision 3: Constraining the output format tightly enough to force comparability
generate a vertical 9:16 4K 3x3 grid of hairstyle reference
images directly on my face
This line is doing format-level constraint work, not just aesthetic styling. Three specific constraints are stacked here:
- "3x3 grid" — forces multiple distinct options rather than one "best" answer, which is what actually makes this useful for comparison instead of being told what to think.
- "directly on my face" — forces the generation to be conditioned on the same input image rather than producing stylized reference images of generic models, which would defeat the entire point of personalization.
- "9:16... consistent" (implied lighting/angle consistency across the grid) — controls for confounding variables. If every cell in the grid had different lighting and angle, you couldn't visually compare which style actually suits you; you'd be comparing photography conditions, not haircuts.
This is the prompt-engineering equivalent of controlling variables in an experiment. If you want a human (or a downstream model) to compare N outputs meaningfully, the format constraints need to eliminate every difference except the one variable you're testing.
Why This Fails Without the Structure
I tested a stripped-down version — "analyze my face shape and hair type, then suggest hairstyles" — against the full prompt, same input image, same model.
The stripped version produced a single paragraph of advice that mentioned "oval face shape" once and never referenced hair type again. No grid, no comparison, no visible commitment to specific hair attributes carrying through to the recommendation. It read like advice generated despite the image, not from it.
The full version produced exactly what it asked for: a 3x3 grid, generated on the actual uploaded face, with visibly different silhouettes per cell. Whether or not every individual suggestion was a great haircut is a separate (and more subjective) question — but the mechanical difference in personalization depth was stark and entirely attributable to prompt structure, not model capability. Same model, same image, wildly different grounding.
The Reusable Pattern
Strip the hairstyle framing away and you get a template applicable to a lot of "personalize an output from an uploaded input" tasks:
Analyze the [input] I provide.
Identify [specific attribute 1] and [specific attribute 2]
with precision.
Then generate [tightly specified output format] based on
that analysis.
Requirements:
Analyze the input to detect:
1. [Sub-attribute A]
2. [Sub-attribute B, C, D — as many as are actually load-bearing]
Some places I've used variations of this pattern outside the beauty-app context:
- Outfit/style recommendation from a photo — detect body proportions, color palette, existing style cues, then generate outfit suggestions rendered as a comparable grid.
- Furniture/decor placement suggestions from a room photo — detect room dimensions estimate, existing color scheme, light source direction, then generate placement options.
- Skincare routine suggestions from a face photo (with appropriate disclaimers about not replacing professional advice) — detect skin type indicators, then generate a routine, sequenced the same way.
The common thread: whenever your output is supposed to be "personalized," your prompt should make the personalization mechanically unavoidable, not just rhetorically implied. Sequence the analysis explicitly, enumerate the sub-attributes you actually care about, and constrain the output format enough that the result is comparable and inspectable.
A Note on Limitations
Worth being honest about: this pattern improves grounding, it doesn't guarantee correctness. The model's "face shape" classification is still a vision-model inference, not a measured fact, and can be wrong — particularly on edge cases like atypical lighting, non-frontal angles, or features the model has less training exposure to. If you're building something where the classification has real consequences (medical, safety, anything beyond "fun recommendation tool"), treat this pattern as a way to improve consistency and inspectability, not as a substitute for validation against ground truth.
For a low-stakes use case like hairstyle ideas, "probably right, and visibly reasoned" is a perfectly good bar. For higher-stakes use cases, use this pattern to get structured, inspectable intermediate output — then validate that output before you let anything downstream act on it.
Try It Yourself
If you want to poke at the original prompt directly, it's free to copy on NanoAIPrompts — works with both Gemini and ChatGPT's vision + image generation pipelines. Worth running the stripped-down version against the full version yourself with the same image; the gap is a good gut-check for how much "sequencing + enumeration + format constraints" actually buys you in your own prompts.
Building anything that personalizes output from user-uploaded images or data? I'd be curious what analyze-then-generate patterns you've landed on — drop them in the comments.

Top comments (0)