Nodes/ComfyUI-Alchemine-Pack/Consistency Guard
ComfyUI Node

Consistency Guard

Stop Your Prompt Contradicting Itself

By alchemine·Created about a year ago·Updated 27 days ago· 2
Consistency Guard
    • processed_text
    • table
    text
    category
    cosine_threshold0.75
    lift_threshold0.20
    fixed_tags

    Contradictory tags are the quiet killer of anime SDXL generations. Ask the model for dress and bikini in the same prompt and you'll get some dreadful hybrid; ask for day and night and it honestly tries to render both. The community knows this well enough that the standard advice for newer, prompt-following models is blunt: never put contradicting tags in the prompt, because some models will attempt the impossible and hand you body horror instead. Consistency Guard is the fix for that - a node that reads your tag prompt, spots the pairs that contradict each other, removes one of them, and tells you exactly why.

    Here's the author's own example. Feed it bikini, waterfall, pond, dress, day, night with fixed_tags set to bikini, waterfall, day, and it returns bikini, waterfall, pond, day - dress is dropped as a conflict against bikini, night as a conflict against day, while waterfall and pond coexist fine even though they're obviously related. The interesting part is the last pair: no category list anywhere says "day" and "night" clash. The node figured it out from the data.

    How it actually works

    Under the hood is a precomputed co-occurrence table built from the Danbooru 2024 tag dump - roughly 21,000 general tags that appear on at least 100 posts, counted only on solo-tagged images (multi-character posts would smear the statistics). For every tag pair it stores two numbers: a PPMI-profile cosine, which measures whether two tags behave like the same kind of tag, and lift, the observed-over-expected co-occurrence rate where 1.0 means "happens at chance level" and far below 1.0 means "these two actively avoid each other." A tag conflicts with a reference when the cosine clears the bar and the lift sits below it - same kind of tag, but they never appear together. That's a conflict, not a coincidence.

    The default thresholds are cosine_threshold 0.75 and lift_threshold 0.2. The lift bar isn't flat: it rises exponentially with cosine, so near-twin tags need stronger evidence of avoidance, and clothes-vs-clothes pairs get a looser bar (2.5×) because that bucket is dense with genuine substitutes like shoes and boots. Lower lift_threshold to be stricter, raise cosine_threshold to only ever catch near-identical tags.

    The inputs, in practice:

    • text - the prompt to clean (forceInput; wire from upstream)
    • fixed_tags - the tags you've locked in; everything else is checked against these. This is where you pin your character and setting.
    • category - restrict conflict checking to one bucket (clothes, pose, … or all), handy when you only care about, say, outfit contradictions
    • cosine_threshold / lift_threshold - the two dials above

    Two outputs: processed_text (the cleaned prompt) and table - a small audit table of every checked tag with its nearest reference, cosine, lift, a REMOVED/kept status and a star severity rating, capped at 20 rows. The table is the real gold: it tells you why a tag died, which is what lets you trust the node or retune it.

    Installing it

    Same pack as Classify Tags - alchemine/comfyui-alchemine-pack:

    cd ComfyUI/custom_nodes
    git clone https://github.com/alchemine/comfyui-alchemine-pack
    cd comfyui-alchemine-pack && pip install -r requirements.txt
    

    Restart, or use ComfyUI Manager and search ComfyUI-Alchemine-Pack. It's listed as Consistency Guard under AlcheminePack/Prompt. Dependencies are featherweight (python-dotenv only) - but there's a catch: the 26MB co-occurrence table tag_cooc.npz isn't committed to the repo. The first time the node runs it downloads it from a GitHub release (checksum-verified, TIPO-style) into nodes/resources/. Needs network access on that first run.

    Where people get caught

    If you ever see [ConsistencyGuard] tag_cooc.npz not found; falling back to static category rules in the console, the download failed - no network, GitHub blocked, whatever. The node keeps working, but the static fallback only catches the exclusive categories (clothes, hair color, eye color, hair length), so it won't catch day vs night-style conflicts that exist purely in the data. And a few limits are baked in rather than broken: tags too rare to prove avoidance are treated as neutral (kept), and subject tags like 1boy or solo are never used as conflict references - statistically 1boy avoids large breasts, but removing one of those would be madness. There's even a documented open problem: wading vs sitting and spread arms vs sitting can't be told apart by co-occurrence statistics alone. And the README doesn't cover this node at all (it landed in v2.2.0 after the README froze), so the docs/tag-consistency-guard/ folder in the repo is the real documentation - it's in Korean, but the data-pipeline writeup is worth the translation if you're going to trust these conflicts at scale.

    CategoryAlcheminePack/Prompt

    Inputs (5)

    NameTypeDefaultDescription
    textSTRING
    categoryCOMBO10 options: all, characters, clothes, body, expression, pose, +4
    cosine_thresholdFLOAT0.750–1
    lift_thresholdFLOAT0.200–2
    fixed_tagsoptSTRING

    Outputs (2)

    NameTypeDescription
    processed_textSTRING
    tableSTRING