A5 CLIP Prompt Enhancer
Borrow the text encoder you already loaded
- clip
- image
- enhanced_prompt
Most "prompt enhancer" nodes spin up a second process - Ollama, an LM Studio server, some API key you paste into a widget. This one uses the generative text encoder already sitting in your graph, the same machinery behind ComfyUI's own Generate Text node, and asks it to rewrite your prompt.
If you're running Qwen-Image, or anything else whose text encoder is a real language model, you already paid the VRAM cost for a capable writer. This just borrows it.
Why you'd reach for it
The 2026 trend is that your prompt is an instruction, not a token bag. On LLM-encoded models - Flux 2, Qwen, Z-Image, ERNIE - the encoder is a language model reading a sentence, so having a language model write that sentence is a translation between two things that speak the same language.
And because it takes an image, a vision-capable encoder can seed an img2img prompt from the picture itself.
How it works
Three steps, all the encoder's own methods: tokenize, generate(), decode().
tokenizegets your system prompt and input prompt joined into one block, plus the image and thethinkingflag if you enabled them.generateruns the decoder - greedy when Sampling Mode is off, sampled when it's on (temperature, top_k, top_p, min_p, repetition penalty, seed, all in the on-branch).decodeturns token IDs back into text; the node strips<think>blocks and zero-width junk before returning it.
The clever bit is the caching. A config file next to the node's Python remembers the last generated prompt plus a fingerprint of what produced it. Auto bypass if unchanged compares that fingerprint - system prompt, input prompt, a hash of the image if there is one, the CLIP's identity - and if nothing moved, it hands back the stored prompt without touching the GPU.
The inputs that matter
Four of them, realistically:
- clip - and it has to be a generative encoder. A plain CLIP-L or T5 does not have
generate(). This is the number one thing that bites people. - system_prompt / input_prompt - the instruction and the rough idea. The defaults are sane: keep the core idea, add useful detail, return only the prompt.
- run_mode -
Always run LLM,Bypass - send last/manual prompt, orAuto bypass if unchanged. Bypass means a real generation never happens; the node returns whatever is inlast_generated_prompt(which you can edit by hand) or the cached one. - unload_clip_after_generation - drops the enhancer's CLIP from VRAM after a real run. Handy if the encoder and your diffusion model are fighting for the same card, less handy for speed.
Then max_length, the sampling options, and the optional trio: image, thinking, and use_default_template - the last one, off, stops the encoder applying its built-in chat template.
One output: enhanced_prompt, a plain STRING. Into a CLIP Text Encode, into another enhancer for a second pass, into a Save Text if you want to keep it.
Installing it
It's one of nine nodes in the same pack, so you install the pack once.
cd ComfyUI/custom_nodes
git clone https://github.com/A5Projects/ComfyUI-A5Nodes
Then restart ComfyUI and refresh the browser. Or search A5 Custom Nodes in ComfyUI Manager - pick the numbered version, not the Nightly one. No Python packages, no model downloads; the CLIP you connect is the only weight involved. If you already have a standalone copy of these nodes, disable it, or you'll get duplicate registrations.
One note from the README worth respecting: this node is the one piece of the pack written against ComfyUI's newer V3 schema (io.ComfyNode), so it wants a reasonably current ComfyUI with lazy-input support. On an old build it errors rather than silently misbehaving. And in Firefox, the author's advice is to stay in classic node mode - Nodes 2.0 has unresolved rendering issues there.
Where people get burned
"The connected CLIP could not generate text." Your encoder isn't generative. Before blaming the node, drop the core Generate Text node in and try the same encoder. If that can't write text either, this one can't.
Vision errors. Wiring image into a text-only encoder throws a tokenize error telling you the encoder may not support vision. The model list is not a promise; the model is.
Sampling on plus Auto bypass is a trap. The fingerprint doesn't include the seed, so with sampling enabled the auto mode will happily return its one stored prompt forever. Want a fresh variation each run? Always run LLM.
Empty output raises. A model that returns nothing but scaffolding gets you a RuntimeError, not a blank string.
And the ceiling: an enhancer adds detail you didn't ask for. Ask for a fox in neon rain and you may get a specific lens, a coat, a time of night. When that's the feature, great. When your prompt is already exactly right, the bypass switch is right there.
Inputs (11)
| Name | Type | Default | Description |
|---|---|---|---|
| clip | CLIP | — | |
| system_prompt | STRING | Enhance the user's image-generation prompt. Keep the core idea, add useful visual details, and return only the improved prompt. | — |
| input_prompt | STRING | A cinematic portrait of a fox in a rainy neon city | — |
| run_mode | COMBO | Always run LLM | 3 options: Always run LLM, Bypass - send last/manual prompt, Auto bypass if unchanged |
| last_generated_prompt | STRING | Prompt returned by bypass modes; real LLM runs overwrite it. | |
| max_length | INT | 5121–32768 | — |
| sampling_mode | COMBO | 2 options: [object Object], [object Object] | |
| unload_clip_after_generation | BOOLEAN | false | Unload only the connected enhancer CLIP from VRAM after a real generation. Bypass modes skip this; later uses reload it. |
| imageopt | IMAGE | — | |
| thinkingopt | BOOLEAN | false | Operate in thinking mode if the model supports it. |
| use_default_templateopt | BOOLEAN | true | Use the connected model's built-in prompt template. |
Outputs (1)
| Name | Type | Description |
|---|---|---|
| enhanced_prompt | STRING | — |