Text Encode with Flux2 Klein System Prompt (Legacy)
The correct chat template for Flux 2 Klein, think block included
- clip
- CONDITIONING
Flux 2 Klein is the model that made local image editing mainstream in 2026: 4B/9B, four-step distilled, one checkpoint doing text-to-image and single- and multi-reference editing. It runs on a Qwen3 text encoder, which means it speaks a very different template language than Flux 2 dev - chatml-style <|im_start|> tags, and a <think> reasoning block the model expects before it produces output. This node wraps your prompt in exactly that format, system message and thinking content included.
How it works
Inputs: clip (Klein's Qwen3 encoder), prompt, system_prompt (optional), and thinking_content - the one that sets this apart. Klein is trained with a CoT-style <think>\n…\n</think> block injected between the user turn and the model's answer. Leave thinking_content empty and the node inserts an empty think block (which is the correct structural placeholder - the tokenizer expects it). Fill it with actual reasoning, like "the subject's hair should read as wet and reflective", and you're steering the model's internal reasoning before it renders. That's a real lever on Klein, not a gimmick.
The node builds the full template: <|im_start|>system\n{system_prompt}<|im_end|>\n<|im_start|>user\n{prompt}<|im_end|>\n<|im_start|>assistant\n<think>\n{thinking}\n</think>. If system_prompt is empty, the system turn is omitted. It then tokenizes with that template (skip_template=True, so the wrapper isn't double-applied) and encodes to CONDITIONING.
The one output is CONDITIONING, straight into your sampler.
The honest comparison
The pack ships this plain node and a ScaledBiasTextEncodeKleinSystemPrompt twin. Both wrap the prompt in the identical Klein template with think block. The scaled-bias version additionally parses <tag=strength> bias syntax in your prompt and scales those tokens' embeddings directly - useful if you want (word:1.3)-style emphasis, which Klein's LLM encoder otherwise discards. If you don't use that syntax, this node is the simpler one and the output is equivalent.
Where people get burned
- Use the Klein encoder clip, not Flux 2 dev's. The two models use different template families and different text encoders entirely; crossing them produces conditioning the sampler can't use well.
thinking_contentandsystem_promptare optional but the order of the template is fixed - you can't move the think block before the user turn, and you don't want to.- It's an encoder, not a sampler. Conditioning alone does nothing until it reaches a KSampler with the Klein model loaded.
Installing it
Ships in silveroxides/ComfyUI-UtilsCollection. ComfyUI Manager: search ComfyUI-UtilsCollection, install, restart. Or manually:
cd ComfyUI/custom_nodes
git clone https://github.com/silveroxides/ComfyUI-UtilsCollection
cd ComfyUI-UtilsCollection
pip install -r requirements.txt # opencv-python, typing-extensions
Restart. No node-specific model downloads - Klein's weights are loaded through ComfyUI's normal CLIP loader. Legacy alias of UC_TextEncodeKleinSystemPrompt, identical behavior.
Inputs (4)
| Name | Type | Default | Description |
|---|---|---|---|
| clip | CLIP | — | |
| prompt | STRING | — | |
| system_prompt | STRING | — | |
| thinking_content | STRING | Custom thinking content to inject. Leave empty for default. |
Outputs (1)
| Name | Type | Description |
|---|---|---|
| CONDITIONING | CONDITIONING | — |