π Age Prompt Builder
How AgePromptBuilder Makes '65' Drawable
- positive
- negative
- summary
- target_age
AgePromptBuilder is the clever part of the AgeShift pack, and it exists because of a hard-won fact about Flux: a numeric age is a terrible prompt, and concrete physical descriptors are a great one. Ask Flux for "a 70 year old man" and you get a vague hand-wave at old. Give it "deep facial wrinkles, gray or white hair often thinning, sagging jowls, age spots, looser skin" and it actually draws someone who's clearly seventy. This node translates a target age into that second kind of prompt automatically.
It's the prompt half of the age-shift pipeline. The identity half - keeping the face recognizable while it ages - is PuLID's job, via the balazik/ComfyUI-PuLID-Flux companion pack (or InstantID on SDXL). AgePromptBuilder never touches the image; it just hands you a ready-made positive and negative string pair that wires straight into the CLIPTextEncode nodes feeding your sampler.
How it works
The core is a lookup table in the pack's _types.py mapping twenty age ranges to concrete feature phrases - "young toddler, round face, big bright eyes, smooth soft skin" at age 5, right up to "deeply weathered and wrinkled face, sparse thin white hair" at 80. The node assembles your positive prompt in order:
subject + features(age) + style + extra_positive
so you get a 65 year old man, late sixties, deep facial wrinkles, ..., photorealistic portrait, .... The numeric age is kept in there (it helps), but the features carry most of the signal.
The negative prompt is the sneaky-good part. Beyond your negative_base boilerplate, the node auto-injects anti-drift negatives depending on the target band - go for age 5 and it appends "deep wrinkles, gray hair, age spots, sagging skin, facial hair, beard, mustache, adult features". That's the pack fighting a real failure mode: without it, a 40-year-old source photo leaks adult features into the "child" generation and you get creepy mini-adults. include_negative_age_drift is on by default, and you should leave it on.
The inputs that matter
target_age- an INT from 0 to 120. The whole point of the node. You can hardcode it, or wire it from a math node fed by AgeDetect'sageoutput for a "start from reality, add 25 years" workflow.gender+subject- pick these together or you'll get "a 5 year old male man". The PROMPTS.md docs explicitly suggest settingsubjectto "boy" for child generation to dodge that awkward phrasing.include_negative_age_drift- leave it true. It's the anti-mini-adult guard.style,extra_positive- worth touching once. The default extra ("same identity, same facial structure, same eye shape") is a reminder to the model, not a promise; PuLID does the real identity work.
Outputs: positive and negative go to your two CLIPTextEncode nodes. summary is a debug readout (target band + character counts), and target_age is a passthrough if you want to chain the value downstream.
Install - this is where the heavy lifting lives
The pack itself installs in seconds, but it's only useful with the companion stack:
cd ComfyUI/custom_nodes
git clone https://github.com/balazik/ComfyUI-PuLID-Flux.git
cd ComfyUI-PuLID-Flux
uv pip install -r requirements.txt --no-cache-dir
Then the weights: Flux 1 dev fp8 (models/unet/, ~12GB), CLIP-L, T5-XXL, the Flux VAE, the PuLID-Flux weights (~1.1GB), and - the classic trap - InsightFace's antelopev2 models, which do not auto-download and must be placed manually at models/insightface/models/antelopev2/ with that double models directory. Get the path wrong and PuLID throws assert 'detection' in self.models at you. First generation also quietly downloads EVA02-CLIP-L (~430MB), so expect the first run to hang for a bit. The full stack runs on a 16GB card fine.
Troubleshooting the results
The pack's tuning checklist is honest and worth stealing: faces looking like different people is usually a missing fixed seed, a PuLID weight that's too low (try 0.95), or guidance that's too high (drop to 3.0). Child direction specifically wants PuLID weight dialed back to 0.75-0.8 or you get unsettling "small adult" faces. And know the difficulty curve: aging up is easy, aging down is easy, going to child is hard, going to infant is genuinely unreliable. This node produces the prompts faithfully; the physics of identity-preserving age regression are what they are.
Inputs (7)
| Name | Type | Default | Description |
|---|---|---|---|
| target_age | INT | 300β120 | β |
| subjectopt | STRING | person | β |
| genderopt | COMBO | unspecified | 4 options: unspecified, male, female, non-binary |
| styleopt | STRING | photorealistic portrait, sharp focus, natural studio lighting, neutral background | β |
| extra_positiveopt | STRING | same identity, same facial structure, same eye shape | β |
| negative_baseopt | STRING | cartoon, illustration, painting, anime, 3d render, deformed, distorted, blurry, low quality, plastic skin, extra fingers, watermark, text | β |
| include_negative_age_driftopt | BOOLEAN | true | β |
Outputs (4)
| Name | Type | Description |
|---|---|---|
| positive | STRING | β |
| negative | STRING | β |
| summary | STRING | β |
| target_age | INT | β |