ComfyUI Node

Emaysee Tag Parser

Split an LLM's [NatDes]/[TagDes] output into description and tags

By EmAySee·Created about a year ago·Updated 4 months ago· 2
Emaysee Tag Parser
    • Natural Description
    • Image Tags
    text

    A lot of LLM-based prompt expansion produces two things at once: a flowing natural-language description and a list of booru-style tags. The two behave very differently in a prompt encoder - natural language reads well as a sentence, while comma-separated tags are how SD models actually get their cues. Emaysee Tag Parser is the bridge: it expects the LLM's output to be wrapped in two custom markers - [NatDes]...[/NatDes] for the natural description and [TagDes]...[/TagDes] for the tags - and it splits those two sections into separate string outputs.

    So the workflow it's built for looks like: LLM node → something that formats the reply inside those bracket markers → this parser → description goes to your prompt, tags get appended to your tag list. The marker convention is the author's own (it's not a standard anyone else uses), so unless the model is explicitly instructed to emit [NatDes]/[TagDes], the parser finds nothing.

    How it works

    Two regexes, one for each marker pair:

    nat_match = re.search(r'\[NatDes\](.*?)\[/NatDes\]', text, re.DOTALL | re.IGNORECASE)
    tag_match = re.search(r'\[TagDes\](.*?)\[/TagDes\]', text, re.DOTALL | re.IGNORECASE)
    

    Both are case-insensitive and DOTALL, so the markers can wrap multi-line content. If a marker pair isn't found, that output comes back as an empty string rather than an error - which means a model that forgot its markers silently gives you empty strings. That's the main thing to watch for.

    Inputs and outputs

    • text (multiline STRING, force-input) - the combined output from upstream. It's force-input, so you can't type into it; you have to wire it.

    Outputs:

    • Natural Description - the content between [NatDes] markers.
    • Image Tags - the content between [TagDes] markers.

    Both wire into whatever consumes strings - typically a CLIP Text Encode for the description and a tag combiner for the tags. Nothing here inspects the content itself; it's a pure splitter.

    Installing it

    Same pack, one install: ComfyUI_EmAySee_CustomNodes via ComfyUI Manager, or:

    cd ComfyUI/custom_nodes
    git clone https://github.com/EmAySee/ComfyUI_EmAySee_CustomNodes
    

    Restart, and it shows up under Emaysee/Text. Zero dependencies, zero models - it's just two regexes.

    Where people get burned

    The marker convention is the whole contract. If your LLM node doesn't output [NatDes]/[TagDes], this node returns empty strings and it looks broken. The fix is prompt-side: tell the model, "reply with [NatDes]...[/NatDes] for the description and [TagDes]...[/TagDes] for the tags." The author pairs this with their own LLM connector nodes (the Oobabooga family in this pack), where the system prompt can be set to produce exactly that format - that's the intended pairing. Also note the whitespace: the parser strips whitespace around the matched content, but keeps internal line breaks, so a tag list that comes back with newlines still needs a comma-join downstream if your tag consumer wants CSV.

    CategoryEmaysee/Text

    Inputs (1)

    NameTypeDefaultDescription
    textSTRING

    Outputs (2)

    NameTypeDescription
    Natural DescriptionSTRING
    Image TagsSTRING