Nodes/Arctenoxs-Essentials_ComfyUI/Tag Normalizer (Arctenox's Essentials)
ComfyUI Node

Tag Normalizer (Arctenox's Essentials)

Saying the same tag six different ways is a you problem

By Arctenox·Created 8 months ago·Updated 2 months ago· 1
Tag Normalizer (Arctenox's Essentials)
    • text
    • debug_info
    text
    preserve_ordertrue
    escape_parenthesestrue
    underscores_to_spacestrue

    Prompt engineering on tag-based models is mostly bookkeeping. You paste a generated tag list into a hand-written prompt, add a LoRA trigger word or three, and suddenly long_hair, long hair, and Long Hair are all sitting in the same string doing the same job. The CLIP encoder doesn't care, but your prompt gets bloated, and bloat is where tag models start ignoring the stuff that matters. The Tag Normalizer is a tiny cleanup node that fixes exactly that class of problem.

    It splits your text on commas, normalizes every tag (lowercase, spaces and underscores treated as identical), and drops duplicates - keeping the first occurrence's original spelling. That's the whole job, done well. Three toggles control the rest:

    • preserve_order (default on) keeps your tags in the order you wrote them. Turn it off and it sorts alphabetically, which is handy when you're comparing two prompts side by side.
    • escape_parentheses (default on) replaces ( with \( and ) with \). This is the one that saves beginners from a subtle trap: booru tags like (smile) or (drinks) get read by Stable Diffusion's prompt parser as a weight modifier - (tag) means "tag at 1.1 strength." Escaping turns them back into plain text.
    • underscores_to_spaces (default on) converts long_hair to long hair. Good for models trained on natural-language prompts; leave it on for most anime models too, since ComfyUI's CLIP tokenizer splits on spaces anyway.

    The outputs are text (your cleaned string, ready to wire anywhere a STRING is accepted) and debug_info, which reports how many tags went in, came out, and how many duplicates were removed. The debug string is a nice reality check when you're convinced a prompt is "cleaned up" already.

    Where does it earn its keep? Right after nodes that generate or mash tags together - this pack's own Prompt Generator, wildcard resolution, or any prompt concatenation. Run the output of a wildcard stack through the normalizer and you remove the duplicates you can't even see because the wildcard file picked blue eyes while your hand-written prefix already said blue_eyes.

    Where it doesn't help: it operates on comma-separated tags, so a full natural-language sentence is just one big "tag" to it. Feed it a Flux-style paragraph and it'll shrug and hand it back. It also won't merge near-duplicates like blue eyes and sky blue eyes - only exact matches after normalization.

    One honest note on scope: this is a string node, so it's model-agnostic - it'll happily clean prompts for anything. But it's most useful for booru-tag workflows, which is the same territory the rest of the Arctenox pack lives in.

    Install. Part of Arctenox's Essentials - ComfyUI Manager → search "Arctenox's Essentials", or:

    cd ComfyUI/custom_nodes/
    git clone https://github.com/Arctenox/Arctenoxs-Essentials_ComfyUI
    

    Then restart ComfyUI. No extra Python deps beyond what the pack needs (torch, numpy, optional psutil). If the node doesn't show up, check the ComfyUI console for import errors - a missing numpy is the usual culprit. The README calls the whole pack deprecated as the author remasters it, so expect this to migrate to a new pack eventually; the behavior shouldn't change.

    CategoryArctenox Essentials/Prompting

    Inputs (4)

    NameTypeDefaultDescription
    textSTRINGComma-separated tag string to clean.
    preserve_orderBOOLEANtrueKeep tags in original order. Disable to sort alphabetically.
    escape_parenthesesBOOLEANtrueReplace ( with \( and ) with \) for stable diffusion weight syntax.
    underscores_to_spacesBOOLEANtrueConvert tag_underscores to spaces in the output.

    Outputs (2)

    NameTypeDescription
    textSTRING
    debug_infoSTRING