Nodes/ComfyUI-DynamicPromptComposer/Dynamic Prompt Composer
ComfyUI Node

Dynamic Prompt Composer

Batch 32 images, every one a different prompt — no LLM required

By Alatza·Created 6 months ago·Updated 6 months ago· 1
Dynamic Prompt Composer
    • prompt
    seed0
    section_0
    section_0_mode
    section_0_start_index0
    section_1
    section_1_mode
    section_1_start_index0
    section_2
    section_2_mode
    section_2_start_index0
    section_3
    section_3_mode
    section_3_start_index0
    section_4
    section_4_mode
    section_4_start_index0
    section_5
    section_5_mode
    section_5_start_index0
    section_6
    section_6_mode
    section_6_start_index0
    section_7
    section_7_mode
    section_7_start_index0
    section_8
    section_8_mode
    section_8_start_index0
    section_9
    section_9_mode
    section_9_start_index0
    section_10
    section_10_mode
    section_10_start_index0
    section_11
    section_11_mode
    section_11_start_index0
    section_12
    section_12_mode
    section_12_start_index0
    section_13
    section_13_mode
    section_13_start_index0
    section_14
    section_14_mode
    section_14_start_index0
    section_15
    section_15_mode
    section_15_start_index0
    section_16
    section_16_mode
    section_16_start_index0
    section_17
    section_17_mode
    section_17_start_index0
    section_18
    section_18_mode
    section_18_start_index0
    section_19
    section_19_mode
    section_19_start_index0

    The name sounds like another "AI writes your prompt" gizmo, but it's the opposite of that. Dynamic Prompt Composer never calls an API, needs no key, and doesn't touch an LLM. It's a plain text mixer: you split your prompt into independent sections, drop a few options into each, and every run it picks one from each section and hands you one clean line of text. Queue a batch of 32 and you get 32 variations of the same idea without writing a single extra prompt.

    It's the structured sibling of the old A1111 {this|that|the other} bracket trick that people use to build character reference libraries - batch a fixed seed and get the same person across different cameras, lighting and moods. The difference: inline braces only expand if the text encoder actually knows wildcard syntax, and many don't (SDXL CLIP won't; a Qwen or T5 encoder definitely won't). This node solves that by doing the picking in Python and emitting plain text, so the output wires into literally any encoder.

    How it works

    Each section is an independent prompt block: subject, style, lighting, whatever. You list options separated by newlines or | characters, and the node splits on both. Empty sections are skipped, and every chosen piece is joined into a single line with spaces - so the output is one tidy STRING you can feed straight into CLIP Text Encode or any STRING input.

    Each section has its own mode, and this is where the node earns its keep:

    • random - true random every run. The seed input is ignored. Non-reproducible, on purpose.
    • random (seed) - random, but seeded. Same seed, same pick, always.
    • increment - cycles through your options in order, starting at start_index.
    • fixed - always picks the option at start_index.

    Two mechanism details worth knowing. First, the node always re-executes when any section is in a random or increment mode, so it re-rolls even if you run with an identical seed. Only when every section is fixed does it cache based on the seed. Second, increment counters reset between batches - the node hooks the queue and wipes them when a new queue starts. See the gotchas, because that last part bites people.

    The inputs that actually matter

    The only required input is seed - a big INT, 0 to 2^64−1, used by random (seed). Then you get up to 20 sections, each with three inputs: the multiline section_N text box, section_N_mode, and section_N_start_index. The one output is prompt, a STRING.

    A fresh node shows three sections (there are Add/Remove Section buttons), but the code accepts 20 - the README says 10, which is stale. Trust the code on that one.

    Wiring it up

    Connect prompt to your text encoder's text input. If you're running a batch, tie the node's seed to your KSampler seed when you want reproducibility. A setup that works well: subject and style sections in random (seed) mode, one "camera/lens" section in increment mode so a 16-image batch guarantees you try every lens, and a fixed start_index on anything you're not ready to shuffle.

    Install

    No models, no dependencies, nothing to download - the requirements list is empty. Either of:

    cd ComfyUI/custom_nodes
    git clone https://github.com/Alatza/ComfyUI-DynamicPromptComposer
    

    …then restart ComfyUI, or open ComfyUI Manager and search "Dynamic Prompt Composer". It lands under the prompt category. Requires Python 3.10+, MIT licensed.

    Gotchas

    • random ignores the seed. If you set the node's seed and expect the same prompt to come back, you're in the wrong mode - that's random (seed).
    • increment looks broken until you batch. Because counters reset at the start of each batch, a single isolated run always shows element at start_index. Queue 5+ images and it suddenly makes sense. Interrupted runs also reset, so it never drifts.
    • Separator is a space. On tag-based models (Illustrious, Pony) where prompts are comma-separated, remember to bake commas into your options, or you'll get "long hair blue eyes" soup.
    • The console is your friend. Every pick is printed as [DynamicPromptComposer] section_2 (random (seed)): 'chosen', so when an output looks wrong you can see exactly what got selected and why.
    Categoryprompt

    Inputs (61)

    NameTypeDefaultDescription
    seedINT00–18446744073709550000
    section_0optSTRING
    section_0_modeoptCOMBO4 options: random, random (seed), increment, fixed
    section_0_start_indexoptINT00–99
    section_1optSTRING
    section_1_modeoptCOMBO4 options: random, random (seed), increment, fixed
    section_1_start_indexoptINT00–99
    section_2optSTRING
    section_2_modeoptCOMBO4 options: random, random (seed), increment, fixed
    section_2_start_indexoptINT00–99
    section_3optSTRING
    section_3_modeoptCOMBO4 options: random, random (seed), increment, fixed
    section_3_start_indexoptINT00–99
    section_4optSTRING
    section_4_modeoptCOMBO4 options: random, random (seed), increment, fixed
    section_4_start_indexoptINT00–99
    section_5optSTRING
    section_5_modeoptCOMBO4 options: random, random (seed), increment, fixed
    section_5_start_indexoptINT00–99
    section_6optSTRING
    section_6_modeoptCOMBO4 options: random, random (seed), increment, fixed
    section_6_start_indexoptINT00–99
    section_7optSTRING
    section_7_modeoptCOMBO4 options: random, random (seed), increment, fixed
    section_7_start_indexoptINT00–99
    section_8optSTRING
    section_8_modeoptCOMBO4 options: random, random (seed), increment, fixed
    section_8_start_indexoptINT00–99
    section_9optSTRING
    section_9_modeoptCOMBO4 options: random, random (seed), increment, fixed
    section_9_start_indexoptINT00–99
    section_10optSTRING
    section_10_modeoptCOMBO4 options: random, random (seed), increment, fixed
    section_10_start_indexoptINT00–99
    section_11optSTRING
    section_11_modeoptCOMBO4 options: random, random (seed), increment, fixed
    section_11_start_indexoptINT00–99
    section_12optSTRING
    section_12_modeoptCOMBO4 options: random, random (seed), increment, fixed
    section_12_start_indexoptINT00–99
    section_13optSTRING
    section_13_modeoptCOMBO4 options: random, random (seed), increment, fixed
    section_13_start_indexoptINT00–99
    section_14optSTRING
    section_14_modeoptCOMBO4 options: random, random (seed), increment, fixed
    section_14_start_indexoptINT00–99
    section_15optSTRING
    section_15_modeoptCOMBO4 options: random, random (seed), increment, fixed
    section_15_start_indexoptINT00–99
    section_16optSTRING
    section_16_modeoptCOMBO4 options: random, random (seed), increment, fixed
    section_16_start_indexoptINT00–99
    section_17optSTRING
    section_17_modeoptCOMBO4 options: random, random (seed), increment, fixed
    section_17_start_indexoptINT00–99
    section_18optSTRING
    section_18_modeoptCOMBO4 options: random, random (seed), increment, fixed
    section_18_start_indexoptINT00–99
    section_19optSTRING
    section_19_modeoptCOMBO4 options: random, random (seed), increment, fixed
    section_19_start_indexoptINT00–99

    Outputs (1)

    NameTypeDescription
    promptSTRING